mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
ai-canvas-expand was added to constants.ts and route files but never added to the landing page bento grid, causing all hardcoded counts to remain at 51. This updates all references across source, docs, i18n, and tests to reflect the correct count of 52 tools.
102 lines
4.2 KiB
TypeScript
102 lines
4.2 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
|
|
test.describe("BentoGrid Interactions", () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto("/");
|
|
});
|
|
|
|
test("search filters tools by name", async ({ page }) => {
|
|
const input = page.getByPlaceholder("Search tools...");
|
|
await input.fill("resize");
|
|
await expect(page.getByText("Resize", { exact: true }).first()).toBeVisible();
|
|
await expect(page.getByText(/Showing \d+ of 52 tools/)).toBeVisible();
|
|
});
|
|
|
|
test("category pill filters tools", async ({ page }) => {
|
|
await page.getByText(/AI Tools/).click();
|
|
await expect(page.getByText(/Showing 16 of 52 tools/)).toBeVisible();
|
|
await expect(page.getByText("Remove Background")).toBeVisible();
|
|
});
|
|
|
|
test("clicking All resets category filter", async ({ page }) => {
|
|
await page.getByText(/AI Tools/).click();
|
|
await expect(page.getByText(/Showing 16 of 52 tools/)).toBeVisible();
|
|
|
|
await page.getByText(/All \(52\)/).click();
|
|
await expect(page.getByText(/Showing 52 of 52 tools/)).toBeVisible();
|
|
});
|
|
|
|
test("search with no results shows empty state", async ({ page }) => {
|
|
const input = page.getByPlaceholder("Search tools...");
|
|
await input.fill("xyznonexistent");
|
|
await expect(page.getByText("No tools found. Try a different search.")).toBeVisible();
|
|
await expect(page.getByText(/Showing 0 of 52 tools/)).toBeVisible();
|
|
});
|
|
|
|
test("combined search and category filter works", async ({ page }) => {
|
|
await page.getByText(/AI Tools/).click();
|
|
const input = page.getByPlaceholder("Search tools...");
|
|
await input.fill("background");
|
|
await expect(page.getByText("Remove Background")).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe("HowItWorks Copy Button", () => {
|
|
test("copy button shows Copied! feedback", async ({ page }) => {
|
|
await page.goto("/");
|
|
const copyButton = page.locator("button").filter({ hasText: "docker run" });
|
|
await copyButton.click();
|
|
await expect(page.getByText("Copied!")).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe("FAQ Page Accordion", () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto("/faq");
|
|
});
|
|
|
|
test("renders all FAQ questions", async ({ page }) => {
|
|
await expect(page.getByText("Frequently Asked Questions")).toBeVisible();
|
|
await expect(page.getByText("Are my files safe and private?")).toBeVisible();
|
|
await expect(page.getByText("Is SnapOtter really free?")).toBeVisible();
|
|
await expect(page.getByText("Do I need an internet connection?")).toBeVisible();
|
|
});
|
|
|
|
test("answers are hidden by default", async ({ page }) => {
|
|
await expect(page.getByText(/All processing happens on your own server/)).not.toBeVisible();
|
|
});
|
|
|
|
test("clicking a question expands the answer", async ({ page }) => {
|
|
await page.getByText("Are my files safe and private?").click();
|
|
await expect(page.getByText(/All processing happens on your own server/)).toBeVisible();
|
|
});
|
|
|
|
test("clicking again collapses the answer", async ({ page }) => {
|
|
const question = page.getByText("Are my files safe and private?");
|
|
await question.click();
|
|
await expect(page.getByText(/All processing happens on your own server/)).toBeVisible();
|
|
await question.click();
|
|
await expect(page.getByText(/All processing happens on your own server/)).not.toBeVisible();
|
|
});
|
|
|
|
test("multiple FAQs can be open simultaneously", async ({ page }) => {
|
|
await page.getByText("Are my files safe and private?").click();
|
|
await page.getByText("Is SnapOtter really free?").click();
|
|
await expect(page.getByText(/All processing happens on your own server/)).toBeVisible();
|
|
await expect(page.getByText(/open source under AGPL-3.0/)).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe("Mobile Navigation", () => {
|
|
test("hamburger menu opens and shows links", async ({ page }) => {
|
|
await page.setViewportSize({ width: 375, height: 812 });
|
|
await page.goto("/");
|
|
const toggle = page.getByLabel("Toggle menu");
|
|
await toggle.click();
|
|
await expect(page.getByRole("link", { name: "Features" }).last()).toBeVisible();
|
|
await expect(page.getByRole("link", { name: "Pricing" }).last()).toBeVisible();
|
|
await expect(page.getByRole("link", { name: "Docs" }).last()).toBeVisible();
|
|
await expect(page.getByRole("link", { name: "Contact" }).last()).toBeVisible();
|
|
});
|
|
});
|