import { expect, test } from "@playwright/test"; const ORIGIN = "http://127.0.0.1:4221"; test("runs stages nested and locally", async ({ page }) => { const external: string[] = []; await page.route("**/*", async (r) => { if (new URL(r.request().url()).origin !== ORIGIN) { external.push(r.request().url()); await r.abort(); } else await r.continue(); }); await page.setViewportSize({ width: 1800, height: 900 }); await page.goto("/deep/nested/flow/"); await expect(page.getByRole("heading", { name: "Flow Tools" })).toBeVisible(); await page.getByRole("button", { name: "Run complete pipeline" }).click(); await expect(page.getByRole("status")).toContainText("2 stages"); await expect(page.getByRole("cell", { name: "Ada" })).toBeVisible(); expect(external).toEqual([]); expect( await page .locator(".toolbox-shell__main") .evaluate((n) => getComputedStyle(n).width), ).toBe("1440px"); }); test("exports recipe and keeps snapshots after error", async ({ page }) => { await page.goto("/deep/nested/flow/"); const pending = page.waitForEvent("download"); await page.getByRole("button", { name: "Recipe JSON" }).click(); expect((await pending).suggestedFilename()).toBe("flow-recipe.json"); await page.getByLabel("Field", { exact: true }).first().fill(""); await page.getByRole("button", { name: "Run complete pipeline" }).click(); await expect(page.getByRole("status")).toContainText("remain visible"); }); test("PWA theme, offline reload, and manifest", async ({ page, context, request, }) => { await page.goto("/deep/nested/flow/"); await page.getByRole("button", { name: "Personalize" }).click(); await page.getByRole("button", { name: "Dark" }).click(); await expect(page.locator(".toolbox-shell").first()).toHaveAttribute( "data-toolbox-theme", "dark", ); expect( await page.evaluate(async () => Boolean(await navigator.serviceWorker.ready), ), ).toBe(true); await context.setOffline(true); await page.reload(); await expect(page.getByRole("heading", { name: "Flow Tools" })).toBeVisible(); await context.setOffline(false); const response = await request.get("/deep/nested/flow/"); expect(response.headers()["content-security-policy"]).toContain( "connect-src 'self'", ); const m = await request.get("/deep/nested/flow/toolbox-app.json"); await expect(m.json()).resolves.toMatchObject({ id: "de.add-ideas.flow-tools", version: "0.2.0", }); });