/** * Freeze loading screen: it must appear the moment generation starts, keep * the wizard's action bar out of the way, and Cancel must return to the * wizard with the cancelled notice (not a stuck spinner). */ import { BASE, launchBrowser, makeChecker, makePage, seed } from "./lib.mjs"; const { check, finish } = makeChecker(); const browser = await launchBrowser(); const { context, page } = await makePage(browser); await seed(page, { decks: [] }); // Hold the generation so the loading screen stays up. await page.route("**/api/generate", () => new Promise(() => {})); await page.goto(`${BASE}/create`, { waitUntil: "networkidle" }); await page.waitForTimeout(800); await page.getByRole("button", { name: "Paste text instead" }).click(); await page.locator("textarea").first().fill("Photosynthesis needs light and water."); await page.getByRole("button", { name: "Next" }).click(); await page.waitForTimeout(300); await page.getByRole("button", { name: "Next" }).click(); await page.waitForTimeout(300); const tClick = Date.now(); await page.getByRole("button", { name: "Freeze my deck" }).click(); let appeared = true; await page .locator('img[src="/icons/icon-512.png"]') .waitFor({ state: "visible", timeout: 2000 }) .catch(() => { appeared = false; }); check("loading screen appears immediately after Freeze", appeared, `${Date.now() - tClick} ms`); check("stage message visible", await page.getByText(/Reading your notes|Finding the key ideas/).first().isVisible().catch(() => false)); check("cancel available", await page.getByRole("button", { name: "Cancel" }).isVisible().catch(() => false)); check("wizard bar is gone", (await page.locator("[data-wizard-bar]").count()) === 0); await page.getByRole("button", { name: "Cancel" }).click(); await page.waitForTimeout(700); check("cancel returns to the wizard", (await page.locator("[data-wizard-bar]").count()) === 1); check("cancel shows the notice + retry", await page.getByRole("button", { name: "Retry" }).isVisible()); await context.close(); await browser.close(); finish();