ความคืบหน้างาน ไฟล์ต้นฉบับ

tracker/e2e/theme-check.mjs

// End-to-end check of the theme switch in a real browser.
// Usage (tracker must be running on :8099): node e2e/theme-check.mjs <path-to-chrome> <screenshot-dir>
// Checks OS dark/light with "ตามระบบ", the "มืด" choice surviving a reload, and going back to "ตามระบบ".
import { spawn } from "node:child_process";
import { writeFileSync } from "node:fs";
const [chrome, outDir] = process.argv.slice(2);
const proc = spawn(chrome, ["--headless=new", "--no-sandbox", "--disable-gpu", "--hide-scrollbars", "--remote-debugging-port=9334", "--window-size=1440,1700", "about:blank"], { stdio: "ignore" });
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
let ws, id = 0; const pending = new Map();
const send = (method, params = {}) => new Promise((res) => { const i = ++id; pending.set(i, res); ws.send(JSON.stringify({ id: i, method, params })); });
const ev = async (e) => (await send("Runtime.evaluate", { expression: e, returnByValue: true })).result.value;
const shot = async (name, h = 1700) => { await send("Emulation.setDeviceMetricsOverride", { width: 1440, height: h, deviceScaleFactor: 1, mobile: false }); const r = await send("Page.captureScreenshot", { format: "png" }); writeFileSync(`${outDir}/${name}.png`, Buffer.from(r.data, "base64")); };
try {
  let t; for (let i = 0; i < 50 && !t; i++) { try { t = (await (await fetch("http://127.0.0.1:9334/json")).json()).find((x) => x.type === "page"); } catch {} await sleep(200); }
  ws = new WebSocket(t.webSocketDebuggerUrl); await new Promise((r) => ws.addEventListener("open", r));
  ws.addEventListener("message", (e) => { const m = JSON.parse(e.data); if (pending.has(m.id)) { pending.get(m.id)(m.result); pending.delete(m.id); } });
  // 1) OS dark, theme = system
  await send("Emulation.setEmulatedMedia", { features: [{ name: "prefers-color-scheme", value: "dark" }] });
  await send("Page.navigate", { url: "http://localhost:8099/" }); await sleep(2500);
  console.log("OS dark/system: bg =", await ev("getComputedStyle(document.body).backgroundColor"), "pressed =", await ev("document.querySelector('[aria-pressed=true]').dataset.themeChoice"));
  await shot("dark-overview");
  await send("Page.navigate", { url: "http://localhost:8099/milestones" }); await sleep(2000); await shot("dark-milestones", 1200);
  // 2) OS light, click "มืด", reload
  await send("Emulation.setEmulatedMedia", { features: [{ name: "prefers-color-scheme", value: "light" }] });
  await send("Page.navigate", { url: "http://localhost:8099/" }); await sleep(2000);
  console.log("OS light/system: bg =", await ev("getComputedStyle(document.body).backgroundColor"));
  await ev("document.querySelector('[data-theme-choice=dark]').click()");
  console.log("after click dark: bg =", await ev("getComputedStyle(document.body).backgroundColor"), "data-theme =", await ev("document.documentElement.dataset.theme"));
  await send("Page.navigate", { url: "http://localhost:8099/reviews" }); await sleep(2000);
  console.log("after reload: data-theme =", await ev("document.documentElement.dataset.theme"), "pressed =", await ev("document.querySelector('[aria-pressed=true]').dataset.themeChoice"));
  await shot("dark-reviews", 1000);
  await ev("document.querySelector('[data-theme-choice=system]').click()");
  console.log("back to system (OS light): bg =", await ev("getComputedStyle(document.body).backgroundColor"), "stored =", await ev("localStorage.getItem('tracker-theme')"));
} finally { ws?.close(); proc.kill(); }