mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix(demo): boot to dashboard, sample-data notice, robust mobile editor icon (#464)
The demo signs in as an admin on load (no login/change-password screen; /login and /change-password bounce to the dashboard), authEnabled stays true so the People/Teams/Roles/Security settings tabs remain available, the banner notes the admin data is sample data, and the mobile editor icon is an inline SVG so it always renders.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
|
||||
test("demo preview uses the real app theme and reaches a tool page", async ({ page }) => {
|
||||
test("demo boots straight into the dashboard with no login screen", async ({ page }) => {
|
||||
const consoleErrors: string[] = [];
|
||||
const pageErrors: string[] = [];
|
||||
|
||||
@@ -11,9 +11,12 @@ test("demo preview uses the real app theme and reaches a tool page", async ({ pa
|
||||
pageErrors.push(error.message);
|
||||
});
|
||||
|
||||
await page.goto("/login");
|
||||
await expect(page.getByText("This is a live demo. Processing is disabled.")).toBeVisible();
|
||||
await expect(page.getByRole("heading", { name: "Login" })).toBeVisible();
|
||||
// Visiting the root lands directly on the dashboard, not the login page.
|
||||
await page.goto("/");
|
||||
await expect(page).toHaveURL(/\/$/);
|
||||
// The demo banner is visible and makes clear the admin data is sample data.
|
||||
await expect(page.getByText(/live demo/i).first()).toBeVisible();
|
||||
await expect(page.getByText(/sample data/i).first()).toBeVisible();
|
||||
|
||||
const theme = await page.evaluate(() => {
|
||||
const bannerLink = Array.from(document.querySelectorAll("a")).find((link) =>
|
||||
@@ -34,23 +37,17 @@ test("demo preview uses the real app theme and reaches a tool page", async ({ pa
|
||||
expect(theme.themeColor?.toLowerCase()).toBe("#e07832");
|
||||
expect(theme.bannerBackground).toBe("rgb(224, 120, 50)");
|
||||
|
||||
await page.getByLabel("Username").fill("demo");
|
||||
await page.getByLabel("Password").fill("demo");
|
||||
await page.getByRole("button", { name: /^login$/i }).click();
|
||||
|
||||
await page.waitForURL(/\/change-password$/);
|
||||
await expect(page.getByRole("heading", { name: "Change your password" })).toBeVisible();
|
||||
|
||||
await page.evaluate(() => {
|
||||
localStorage.setItem("snapotter-demo-state", JSON.stringify({ passwordChanged: true }));
|
||||
});
|
||||
|
||||
await page.goto("/");
|
||||
// The dashboard tool grid renders without any login/change-password gate.
|
||||
const allTab = page.getByRole("button", { name: /^All\s*\d+$/ });
|
||||
await expect(allTab).toBeVisible();
|
||||
const allCount = Number((await allTab.textContent())?.match(/\d+$/)?.[0] ?? 0);
|
||||
expect(allCount).toBeGreaterThan(100);
|
||||
|
||||
// Even hitting /login directly bounces to the dashboard.
|
||||
await page.goto("/login");
|
||||
await expect(page).toHaveURL(/\/$/);
|
||||
await expect(allTab).toBeVisible();
|
||||
|
||||
await page.goto("/image/compress");
|
||||
await expect(page.getByRole("heading", { name: "Compress" })).toBeVisible();
|
||||
await expect(page.getByText("Drop your files here")).toBeVisible();
|
||||
@@ -76,13 +73,8 @@ test("admin settings sections render sample data without crashing", async ({ pag
|
||||
}
|
||||
});
|
||||
|
||||
// Seed an authenticated session (past the forced change-password) so we land
|
||||
// straight in the app, then open Settings from the avatar menu.
|
||||
await page.addInitScript(() => {
|
||||
localStorage.setItem("snapotter-token", "demo-token");
|
||||
localStorage.setItem("snapotter-demo-state", JSON.stringify({ passwordChanged: true }));
|
||||
});
|
||||
|
||||
// No login step needed: the demo is signed in on load. Open Settings from
|
||||
// the avatar menu straight away.
|
||||
await page.goto("/");
|
||||
await page.getByTestId("user-menu").click();
|
||||
await page.getByRole("button", { name: "Settings", exact: true }).click();
|
||||
@@ -109,11 +101,20 @@ test("admin settings sections render sample data without crashing", async ({ pag
|
||||
expect(pageErrors).toEqual([]);
|
||||
});
|
||||
|
||||
test("serves the editor icon asset so the mobile nav icon renders", async ({ request }) => {
|
||||
// The mobile bottom-nav editor icon is a CSS mask over /edit-image.png. When
|
||||
// that asset was missing from the demo build the mask resolved to nothing and
|
||||
// the icon vanished on phones. Guard the asset so it can't regress.
|
||||
const response = await request.get("/edit-image.png");
|
||||
expect(response.status()).toBe(200);
|
||||
expect(response.headers()["content-type"]).toContain("image");
|
||||
test("mobile bottom nav renders a visible image-editor icon", async ({ page }) => {
|
||||
// The editor icon used to be a CSS mask over /edit-image.png and vanished on
|
||||
// phones when that asset didn't load. It is now an inline SVG. Render the
|
||||
// mobile nav (viewport under the 768px breakpoint) and assert the editor
|
||||
// link's icon is actually drawn with a non-zero box.
|
||||
await page.setViewportSize({ width: 390, height: 844 });
|
||||
await page.goto("/");
|
||||
|
||||
const editorLink = page.getByRole("link", { name: /editor/i });
|
||||
await expect(editorLink).toBeVisible();
|
||||
|
||||
const icon = editorLink.locator("svg");
|
||||
await expect(icon).toBeVisible();
|
||||
const box = await icon.boundingBox();
|
||||
expect(box?.width ?? 0).toBeGreaterThan(0);
|
||||
expect(box?.height ?? 0).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user