Files
Crystal/tests/pwa-browser.spec.ts
T
samyandClaude Opus 5.5 ce8129703f
Checks / web (push) Failing after 16s
Private ROM checks / private-rom (push) Failing after 17m47s
Make Crystal an installable web app with an offline shell (#39)
A manifest and icons rendered from icon.svg make the app installable.
The native build emits a service worker that precaches exactly the
built files and passes everything else to the network, so ROMs never
reach its cache. New versions wait for the player's Update, which saves
before reloading. Savegames offers installation, iPhone steps and
persistent storage, and a full disk gets its own save error.

Acceptance on physical iPhone and Android devices remains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 20:51:57 +02:00

57 lines
1.8 KiB
TypeScript

import { test, expect } from "@playwright/test";
const PREVIEW = "http://127.0.0.1:4173/";
// Playwright's WebKit does not run service workers; Chromium covers them.
test.beforeEach(({ browserName }) =>
test.skip(
browserName !== "chromium",
"Service workers run in Chromium here.",
),
);
test("the production build installs its shell and opens offline", async ({
page,
context,
}) => {
const errors: string[] = [];
page.on("pageerror", (error) => errors.push(error.message));
await page.goto(PREVIEW);
const manifest = await page
.locator('link[rel="manifest"]')
.getAttribute("href");
const response = await page.request.get(new URL(manifest!, PREVIEW).href);
expect(response.ok()).toBe(true);
expect(await response.json()).toMatchObject({
display: "standalone",
start_url: "./",
});
// The worker installs, then controls the page after a reload.
await page.evaluate(() => navigator.serviceWorker.ready);
await page.reload();
expect(
await page.evaluate(() => Boolean(navigator.serviceWorker.controller)),
).toBe(true);
await context.setOffline(true);
await page.reload();
await expect(page.locator("#status")).toContainText("Choose your ROM");
await expect(page.locator("#rom-file")).toBeAttached();
// The Savegames tab describes installation and storage.
await page.locator("#tab-saves").click();
await expect(page.locator("#install-status")).not.toBeEmpty();
await expect(page.locator("#storage-status")).not.toHaveText(/Checking/);
await context.setOffline(false);
expect(errors).toEqual([]);
});
test("the development server registers no service worker", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(500);
expect(
await page.evaluate(
async () => (await navigator.serviceWorker.getRegistrations()).length,
),
).toBe(0);
});