mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
chore: update tool count to 50 across all references
This commit is contained in:
@@ -64,7 +64,7 @@ pnpm dev
|
|||||||
|
|
||||||
## What You Can Do
|
## What You Can Do
|
||||||
|
|
||||||
### Image Processing (49 Tools)
|
### Image Processing (50 Tools)
|
||||||
|
|
||||||
| Category | Tools |
|
| Category | Tools |
|
||||||
|----------|-------|
|
|----------|-------|
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ export function BentoGrid() {
|
|||||||
<div className="mx-auto max-w-6xl">
|
<div className="mx-auto max-w-6xl">
|
||||||
<FadeIn>
|
<FadeIn>
|
||||||
<h2 className="font-[family-name:var(--font-nunito)] text-center text-3xl font-bold tracking-tight md:text-4xl">
|
<h2 className="font-[family-name:var(--font-nunito)] text-center text-3xl font-bold tracking-tight md:text-4xl">
|
||||||
48 tools. Zero cloud dependency.
|
50 tools. Zero cloud dependency.
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mx-auto mt-4 max-w-xl text-center text-lg text-muted">
|
<p className="mx-auto mt-4 max-w-xl text-center text-lg text-muted">
|
||||||
Search to find exactly what you need. Every tool runs 100% locally.
|
Search to find exactly what you need. Every tool runs 100% locally.
|
||||||
|
|||||||
@@ -2456,7 +2456,7 @@ function AboutSection() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
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.
|
convert, watermark, and automate your image workflows without sending data to the cloud.
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-center gap-4 text-sm">
|
<div className="flex items-center gap-4 text-sm">
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ export const en = {
|
|||||||
regenerateKey: "Regenerate",
|
regenerateKey: "Regenerate",
|
||||||
copyKey: "Copy Key",
|
copyKey: "Copy Key",
|
||||||
aboutDescription:
|
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",
|
aboutLinks: "Links",
|
||||||
github: "GitHub",
|
github: "GitHub",
|
||||||
documentation: "Documentation",
|
documentation: "Documentation",
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ test.describe("Docs Homepage", () => {
|
|||||||
await expect(page.getByText("SnapOtter").first()).toBeVisible();
|
await expect(page.getByText("SnapOtter").first()).toBeVisible();
|
||||||
await expect(page.getByText("A Self Hosted Image Manipulator")).toBeVisible();
|
await expect(page.getByText("A Self Hosted Image Manipulator")).toBeVisible();
|
||||||
await expect(
|
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();
|
).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -59,9 +59,9 @@ test.describe("Landing Homepage", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("bento grid renders with search and tool count", async ({ page }) => {
|
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.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 }) => {
|
test("enterprise section renders feature cards", async ({ page }) => {
|
||||||
|
|||||||
@@ -9,28 +9,28 @@ test.describe("BentoGrid Interactions", () => {
|
|||||||
const input = page.getByPlaceholder("Search tools...");
|
const input = page.getByPlaceholder("Search tools...");
|
||||||
await input.fill("resize");
|
await input.fill("resize");
|
||||||
await expect(page.getByText("Resize", { exact: true }).first()).toBeVisible();
|
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 }) => {
|
test("category pill filters tools", async ({ page }) => {
|
||||||
await page.getByText(/AI Tools/).click();
|
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();
|
await expect(page.getByText("Remove Background")).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("clicking All resets category filter", async ({ page }) => {
|
test("clicking All resets category filter", async ({ page }) => {
|
||||||
await page.getByText(/AI Tools/).click();
|
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 page.getByText(/All \(50\)/).click();
|
||||||
await expect(page.getByText(/Showing 48 of 48 tools/)).toBeVisible();
|
await expect(page.getByText(/Showing 50 of 50 tools/)).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("search with no results shows empty state", async ({ page }) => {
|
test("search with no results shows empty state", async ({ page }) => {
|
||||||
const input = page.getByPlaceholder("Search tools...");
|
const input = page.getByPlaceholder("Search tools...");
|
||||||
await input.fill("xyznonexistent");
|
await input.fill("xyznonexistent");
|
||||||
await expect(page.getByText("No tools found. Try a different search.")).toBeVisible();
|
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 }) => {
|
test("combined search and category filter works", async ({ page }) => {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ function getCountText(): string {
|
|||||||
describe("BentoGrid", () => {
|
describe("BentoGrid", () => {
|
||||||
it("renders the section heading", () => {
|
it("renders the section heading", () => {
|
||||||
render(<BentoGrid />);
|
render(<BentoGrid />);
|
||||||
expect(screen.getByText("48 tools. Zero cloud dependency.")).toBeDefined();
|
expect(screen.getByText("50 tools. Zero cloud dependency.")).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders the search input", () => {
|
it("renders the search input", () => {
|
||||||
@@ -36,12 +36,12 @@ describe("BentoGrid", () => {
|
|||||||
it("shows all tools by default", () => {
|
it("shows all tools by default", () => {
|
||||||
render(<BentoGrid />);
|
render(<BentoGrid />);
|
||||||
const text = getCountText();
|
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", () => {
|
it("renders category filter pills including All", () => {
|
||||||
render(<BentoGrid />);
|
render(<BentoGrid />);
|
||||||
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(/Essentials/)).toBeDefined();
|
||||||
expect(screen.getByText(/AI Tools/)).toBeDefined();
|
expect(screen.getByText(/AI Tools/)).toBeDefined();
|
||||||
expect(screen.getByText(/Optimization/)).toBeDefined();
|
expect(screen.getByText(/Optimization/)).toBeDefined();
|
||||||
@@ -53,7 +53,7 @@ describe("BentoGrid", () => {
|
|||||||
fireEvent.change(input, { target: { value: "resize" } });
|
fireEvent.change(input, { target: { value: "resize" } });
|
||||||
expect(screen.getByText("Resize")).toBeDefined();
|
expect(screen.getByText("Resize")).toBeDefined();
|
||||||
const text = getCountText();
|
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();
|
expect(screen.queryByText("OCR / Text Extraction")).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ describe("BentoGrid", () => {
|
|||||||
const aiButton = screen.getByText(/AI Tools/);
|
const aiButton = screen.getByText(/AI Tools/);
|
||||||
fireEvent.click(aiButton);
|
fireEvent.click(aiButton);
|
||||||
const text = getCountText();
|
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.getByText("Remove Background")).toBeDefined();
|
||||||
expect(screen.queryByText("Resize")).toBeNull();
|
expect(screen.queryByText("Resize")).toBeNull();
|
||||||
});
|
});
|
||||||
@@ -73,7 +73,7 @@ describe("BentoGrid", () => {
|
|||||||
fireEvent.change(input, { target: { value: "xyznonexistent" } });
|
fireEvent.change(input, { target: { value: "xyznonexistent" } });
|
||||||
expect(screen.getByText("No tools found. Try a different search.")).toBeDefined();
|
expect(screen.getByText("No tools found. Try a different search.")).toBeDefined();
|
||||||
const text = getCountText();
|
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", () => {
|
it("combines search and category filter", () => {
|
||||||
@@ -89,9 +89,9 @@ describe("BentoGrid", () => {
|
|||||||
it("clicking All resets category filter", () => {
|
it("clicking All resets category filter", () => {
|
||||||
render(<BentoGrid />);
|
render(<BentoGrid />);
|
||||||
fireEvent.click(screen.getByText(/AI Tools/));
|
fireEvent.click(screen.getByText(/AI Tools/));
|
||||||
expect(getCountText()).toMatch(/Showing 15 of 48 tools/);
|
expect(getCountText()).toMatch(/Showing 15 of 50 tools/);
|
||||||
fireEvent.click(screen.getByText((_, el) => el?.textContent === "All (48)"));
|
fireEvent.click(screen.getByText((_, el) => el?.textContent === "All (50)"));
|
||||||
expect(getCountText()).toMatch(/Showing 48 of 48 tools/);
|
expect(getCountText()).toMatch(/Showing 50 of 50 tools/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders each tool with name and description", () => {
|
it("renders each tool with name and description", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user