From 3d9324b82a2d80ea722ddd8805c8a94fecf8650f Mon Sep 17 00:00:00 2001 From: SnapOtter Date: Fri, 8 May 2026 16:33:12 +0800 Subject: [PATCH] chore: update tool count to 50 across all references --- apps/docs/guide/getting-started.md | 2 +- apps/landing/src/components/bento-grid.tsx | 2 +- .../components/settings/settings-dialog.tsx | 2 +- packages/shared/src/i18n/en.ts | 2 +- tests/e2e-docs/homepage.spec.ts | 2 +- tests/e2e-landing/homepage.spec.ts | 4 ++-- tests/e2e-landing/interactions.spec.ts | 12 ++++++------ tests/unit/landing/bento-grid.test.tsx | 18 +++++++++--------- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/apps/docs/guide/getting-started.md b/apps/docs/guide/getting-started.md index 3de508d5..b16e3bad 100644 --- a/apps/docs/guide/getting-started.md +++ b/apps/docs/guide/getting-started.md @@ -64,7 +64,7 @@ pnpm dev ## What You Can Do -### Image Processing (49 Tools) +### Image Processing (50 Tools) | Category | Tools | |----------|-------| diff --git a/apps/landing/src/components/bento-grid.tsx b/apps/landing/src/components/bento-grid.tsx index 7c896fb8..668089d2 100644 --- a/apps/landing/src/components/bento-grid.tsx +++ b/apps/landing/src/components/bento-grid.tsx @@ -396,7 +396,7 @@ export function BentoGrid() {

- 48 tools. Zero cloud dependency. + 50 tools. Zero cloud dependency.

Search to find exactly what you need. Every tool runs 100% locally. diff --git a/apps/web/src/components/settings/settings-dialog.tsx b/apps/web/src/components/settings/settings-dialog.tsx index f304bde7..2a5c2d0b 100644 --- a/apps/web/src/components/settings/settings-dialog.tsx +++ b/apps/web/src/components/settings/settings-dialog.tsx @@ -2456,7 +2456,7 @@ function AboutSection() {

- A self-hosted, privacy-first image processing suite with 48 tools. Resize, compress, + A self-hosted, privacy-first image processing suite with 50 tools. Resize, compress, convert, watermark, and automate your image workflows without sending data to the cloud.

diff --git a/packages/shared/src/i18n/en.ts b/packages/shared/src/i18n/en.ts index 1e284767..6e1aada0 100644 --- a/packages/shared/src/i18n/en.ts +++ b/packages/shared/src/i18n/en.ts @@ -215,7 +215,7 @@ export const en = { regenerateKey: "Regenerate", copyKey: "Copy Key", aboutDescription: - "SnapOtter is a self-hosted, privacy-first image processing suite with 48 tools.", + "SnapOtter is a self-hosted, privacy-first image processing suite with 50 tools.", aboutLinks: "Links", github: "GitHub", documentation: "Documentation", diff --git a/tests/e2e-docs/homepage.spec.ts b/tests/e2e-docs/homepage.spec.ts index 1c97f994..cbace833 100644 --- a/tests/e2e-docs/homepage.spec.ts +++ b/tests/e2e-docs/homepage.spec.ts @@ -13,7 +13,7 @@ test.describe("Docs Homepage", () => { await expect(page.getByText("SnapOtter").first()).toBeVisible(); await expect(page.getByText("A Self Hosted Image Manipulator")).toBeVisible(); await expect( - page.getByText("48 tools. Local AI. No cloud. Your images never leave your home."), + page.getByText("50 tools. Local AI. No cloud. Your images never leave your home."), ).toBeVisible(); }); diff --git a/tests/e2e-landing/homepage.spec.ts b/tests/e2e-landing/homepage.spec.ts index 772f6736..8086d3f2 100644 --- a/tests/e2e-landing/homepage.spec.ts +++ b/tests/e2e-landing/homepage.spec.ts @@ -59,9 +59,9 @@ test.describe("Landing Homepage", () => { }); test("bento grid renders with search and tool count", async ({ page }) => { - await expect(page.getByText("48 tools. Zero cloud dependency.")).toBeVisible(); + await expect(page.getByText("50 tools. Zero cloud dependency.")).toBeVisible(); await expect(page.getByPlaceholder("Search tools...")).toBeVisible(); - await expect(page.getByText(/Showing 48 of 48 tools/)).toBeVisible(); + await expect(page.getByText(/Showing 50 of 50 tools/)).toBeVisible(); }); test("enterprise section renders feature cards", async ({ page }) => { diff --git a/tests/e2e-landing/interactions.spec.ts b/tests/e2e-landing/interactions.spec.ts index fe61b52f..9974ee74 100644 --- a/tests/e2e-landing/interactions.spec.ts +++ b/tests/e2e-landing/interactions.spec.ts @@ -9,28 +9,28 @@ test.describe("BentoGrid Interactions", () => { 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 48 tools/)).toBeVisible(); + await expect(page.getByText(/Showing \d+ of 50 tools/)).toBeVisible(); }); test("category pill filters tools", async ({ page }) => { await page.getByText(/AI Tools/).click(); - await expect(page.getByText(/Showing 15 of 48 tools/)).toBeVisible(); + await expect(page.getByText(/Showing 15 of 50 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 15 of 48 tools/)).toBeVisible(); + await expect(page.getByText(/Showing 15 of 50 tools/)).toBeVisible(); - await page.getByText(/All \(48\)/).click(); - await expect(page.getByText(/Showing 48 of 48 tools/)).toBeVisible(); + await page.getByText(/All \(50\)/).click(); + await expect(page.getByText(/Showing 50 of 50 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 48 tools/)).toBeVisible(); + await expect(page.getByText(/Showing 0 of 50 tools/)).toBeVisible(); }); test("combined search and category filter works", async ({ page }) => { diff --git a/tests/unit/landing/bento-grid.test.tsx b/tests/unit/landing/bento-grid.test.tsx index 0f317d9d..24582b9a 100644 --- a/tests/unit/landing/bento-grid.test.tsx +++ b/tests/unit/landing/bento-grid.test.tsx @@ -25,7 +25,7 @@ function getCountText(): string { describe("BentoGrid", () => { it("renders the section heading", () => { render(); - expect(screen.getByText("48 tools. Zero cloud dependency.")).toBeDefined(); + expect(screen.getByText("50 tools. Zero cloud dependency.")).toBeDefined(); }); it("renders the search input", () => { @@ -36,12 +36,12 @@ describe("BentoGrid", () => { it("shows all tools by default", () => { render(); const text = getCountText(); - expect(text).toMatch(/Showing 48 of 48 tools/); + expect(text).toMatch(/Showing 50 of 50 tools/); }); it("renders category filter pills including All", () => { render(); - expect(screen.getByText((_, el) => el?.textContent === "All (48)")).toBeDefined(); + expect(screen.getByText((_, el) => el?.textContent === "All (50)")).toBeDefined(); expect(screen.getByText(/Essentials/)).toBeDefined(); expect(screen.getByText(/AI Tools/)).toBeDefined(); expect(screen.getByText(/Optimization/)).toBeDefined(); @@ -53,7 +53,7 @@ describe("BentoGrid", () => { fireEvent.change(input, { target: { value: "resize" } }); expect(screen.getByText("Resize")).toBeDefined(); const text = getCountText(); - expect(text).toMatch(/Showing \d+ of 48 tools/); + expect(text).toMatch(/Showing \d+ of 50 tools/); expect(screen.queryByText("OCR / Text Extraction")).toBeNull(); }); @@ -62,7 +62,7 @@ describe("BentoGrid", () => { const aiButton = screen.getByText(/AI Tools/); fireEvent.click(aiButton); const text = getCountText(); - expect(text).toMatch(/Showing 15 of 48 tools/); + expect(text).toMatch(/Showing 15 of 50 tools/); expect(screen.getByText("Remove Background")).toBeDefined(); expect(screen.queryByText("Resize")).toBeNull(); }); @@ -73,7 +73,7 @@ describe("BentoGrid", () => { fireEvent.change(input, { target: { value: "xyznonexistent" } }); expect(screen.getByText("No tools found. Try a different search.")).toBeDefined(); const text = getCountText(); - expect(text).toMatch(/Showing 0 of 48 tools/); + expect(text).toMatch(/Showing 0 of 50 tools/); }); it("combines search and category filter", () => { @@ -89,9 +89,9 @@ describe("BentoGrid", () => { it("clicking All resets category filter", () => { render(); fireEvent.click(screen.getByText(/AI Tools/)); - expect(getCountText()).toMatch(/Showing 15 of 48 tools/); - fireEvent.click(screen.getByText((_, el) => el?.textContent === "All (48)")); - expect(getCountText()).toMatch(/Showing 48 of 48 tools/); + expect(getCountText()).toMatch(/Showing 15 of 50 tools/); + fireEvent.click(screen.getByText((_, el) => el?.textContent === "All (50)")); + expect(getCountText()).toMatch(/Showing 50 of 50 tools/); }); it("renders each tool with name and description", () => {