Files
SnapOtter/tests/e2e/home-page.spec.ts
T
SnapOtterandGitHub 4ec39c556f test: testing overhaul -- CI e2e gates, parallel suites, generated matrices, mutation testing (#215)
Closes the "e2e never runs in CI" hole. Adds per-PR e2e smoke gate,
nightly full-suite workflows, parallel vitest forks (per-fork DBs),
Playwright parallel/serial/visual projects against production builds,
metadata-generated test suites (drift guards, hostile inputs, format
matrix, pairwise settings, property-based fuzz), Stryker mutation
testing, Schemathesis API fuzz, coverage ratchet, and fixes for three
session-poisoning bugs that caused 200+ serial-bucket failures.

Bug fix included: favicon/split/bulk-rename could hang clients forever
when ZIP streaming failed after reply.hijack().
2026-06-10 22:01:13 +08:00

90 lines
3.1 KiB
TypeScript

import { expect, test, uploadTestImage } from "./helpers";
test.describe("Home Page", () => {
test("shows branding and dropzone prompt", async ({ loggedInPage: page }) => {
// The wordmark renders as a logo image, not text; the document title is
// the stable brand assertion.
await expect(page).toHaveTitle(/SnapOtter/i);
await expect(page.getByText("Drop your images here")).toBeVisible();
});
test("dropzone shows upload button", async ({ loggedInPage: page }) => {
await expect(page.getByText("Upload from computer")).toBeVisible();
});
test("tool panel is visible on home page", async ({ loggedInPage: page }) => {
// Search bar should be visible in tool panel
await expect(page.getByPlaceholder(/search/i).first()).toBeVisible();
// Tool categories should be visible
await expect(page.getByText("Essentials").first()).toBeVisible();
});
test("tool panel search filters tools", async ({ loggedInPage: page }) => {
const searchInput = page.getByPlaceholder(/search/i).first();
await searchInput.fill("compress");
// Should show Compress tool
await expect(page.getByText("Compress").first()).toBeVisible();
});
test("clicking a tool in panel navigates to tool page", async ({ loggedInPage: page }) => {
// Find and click a tool link
await page.locator("a").filter({ hasText: "Resize" }).first().click();
await expect(page).toHaveURL("/resize");
});
test("after upload shows quick actions and tool selector", async ({ loggedInPage: page }) => {
await uploadTestImage(page);
// Should show quick actions
await expect(page.getByText("Quick Actions").first()).toBeVisible();
// Should show quick action tools
await expect(page.getByRole("button", { name: /resize/i }).first()).toBeVisible();
await expect(page.getByRole("button", { name: /compress/i }).first()).toBeVisible();
// Should show all tools section
await expect(page.getByText("All Tools").first()).toBeVisible();
});
test("after upload shows image preview", async ({ loggedInPage: page }) => {
await uploadTestImage(page);
// Should show the image preview (file info)
await expect(page.getByText(/test-image/i).first()).toBeVisible();
});
test("change file button resets upload", async ({ loggedInPage: page }) => {
await uploadTestImage(page);
// Click change file
await page.getByText("Change file").click();
// Should go back to dropzone
await expect(page.getByText("Upload from computer")).toBeVisible();
});
test("clicking quick action tool navigates with file", async ({ loggedInPage: page }) => {
await uploadTestImage(page);
// Click resize quick action
await page
.getByRole("button", { name: /resize/i })
.first()
.click();
await expect(page).toHaveURL("/resize");
// File should still be loaded (no dropzone)
await expect(page.getByText("Upload from computer")).not.toBeVisible();
});
test("footer has theme toggle", async ({ loggedInPage: page }) => {
// Footer should have theme toggle
const footer = page.locator("[class*='fixed'][class*='bottom']").last();
await expect(footer).toBeVisible();
});
});