sueta / client / e2e / update-banner.e2e.mjs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// Proves the in-app update flow: load current version (SW installs), publish
// version+1 into dist, trigger an update check → numbered banner → tap →
// running the new version. Requires `npx vite preview --port 4174`.
import { execSync } from "node:child_process";
import { chromium } from "playwright";

const BASE = "http://localhost:4174";

const browser = await chromium.launch();
const page = await (await browser.newContext({ viewport: { width: 390, height: 844 } })).newPage();
page.on("console", (m) => {
  if (/error/i.test(m.type())) console.log("[pg-err]", m.text().slice(0, 160));
});

await page.goto(BASE);
await page.click("#new-room");
await page.waitForSelector("#name-in");
await page.fill("#name-in", "tester");
await page.click("#name-ok");
await page.evaluate(() => navigator.serviceWorker.ready);
await page.waitForTimeout(1500); // let the SW finish precaching
const cur = Number((await page.textContent(".ver")).trim().slice(1));
console.log("running: v" + cur);

console.log("publishing next version into dist…");
execSync("npm run release", { cwd: new URL("..", import.meta.url).pathname, stdio: "inherit" });

await page.evaluate(async () => (await navigator.serviceWorker.getRegistration())?.update());
await page.waitForSelector("#upd-banner", { timeout: 20000 });
const banner = (await page.textContent("#upd-banner")).trim();
console.log("banner:", banner);
if (!banner.includes(`version ${cur + 1}`)) {
  console.error("❌ banner doesn't announce the new version number");
  process.exit(1);
}

await page.click("#upd-banner");
try {
  await page.waitForFunction((v) => document.querySelector(".ver")?.textContent === `v${v}`, cur + 1, {
    timeout: 20000,
  });
} catch {
  console.error("❌ still on", await page.textContent(".ver").catch(() => "<no .ver>"));
  console.error("controller:", await page.evaluate(() => navigator.serviceWorker.controller?.scriptURL ?? "none"));
  console.error(
    "sw states:",
    await page.evaluate(async () => {
      const r = await navigator.serviceWorker.getRegistration();
      return { waiting: !!r?.waiting, active: r?.active?.state, installing: !!r?.installing };
    }),
  );
  process.exit(1);
}
console.log("✅ one-tap update: now running", (await page.textContent(".ver")).trim());
await browser.close();
process.exit(0);