"use strict"; const assert = require("node:assert/strict"); const fs = require("node:fs"); const path = require("node:path"); const { JSDOM } = require("jsdom"); const html = fs.readFileSync(path.join(__dirname, "../popup/popup.html"), "utf8") .replace('', ""); const source = fs.readFileSync(path.join(__dirname, "../popup/popup.js"), "utf8"); function tick() { return new Promise((resolve) => setTimeout(resolve, 0)); } async function openPopup({ url = "https://chatgpt.com/c/123", settings = {}, storageError = null } = {}) { const writes = []; const dom = new JSDOM(html, { url: "chrome-extension://test/popup/popup.html", runScripts: "dangerously" }); const runtime = { lastError: null }; dom.window.chrome = { runtime, storage: { local: { get(defaults, callback) { runtime.lastError = storageError ? { message: storageError } : null; callback({ ...defaults, ...settings }); runtime.lastError = null; }, set(patch, callback) { writes.push(patch); if (callback) callback(); } }, onChanged: { addListener() {} } }, tabs: { query(_query, callback) { callback([{ url }]); } } }; const script = dom.window.document.createElement("script"); script.textContent = source; dom.window.document.body.appendChild(script); await tick(); return { dom, document: dom.window.document, writes }; } const tests = []; function test(name, fn) { tests.push({ name, fn }); } test("shows the current host and an active text status", async () => { const { document } = await openPopup(); assert.equal(document.getElementById("host").textContent, "chatgpt.com"); assert.match(document.getElementById("siteStatus").textContent, /active/i); assert.equal(document.getElementById("siteStatus").getAttribute("role"), "status"); }); test("exposes the approved settings and persists direction changes", async () => { const { dom, document, writes } = await openPopup(); for (const id of ["enabled", "thisSite", "fixDirection", "useFont", "fixInputs"]) { assert.ok(document.getElementById(id), `missing #${id}`); } const direction = document.getElementById("fixDirection"); direction.checked = false; direction.dispatchEvent(new dom.window.Event("change", { bubbles: true })); assert.equal(JSON.stringify(writes.at(-1)), JSON.stringify({ fixDirection: false })); }); test("describes unsupported browser pages and disables the site switch", async () => { const { document } = await openPopup({ url: "chrome://extensions" }); assert.equal(document.getElementById("host").textContent, "Unavailable"); assert.match(document.getElementById("siteStatus").textContent, /cannot be modified/i); assert.equal(document.getElementById("thisSite").disabled, true); }); test("a disabled master switch clearly disables dependent controls", async () => { const { document } = await openPopup({ settings: { enabled: false } }); assert.equal(document.getElementById("thisSite").disabled, true); assert.equal(document.getElementById("fixDirection").disabled, true); assert.equal(document.getElementById("useFont").disabled, true); assert.equal(document.getElementById("fixInputs").disabled, true); assert.match(document.getElementById("siteStatus").textContent, /paused/i); }); test("storage failures produce a safe error state", async () => { const { document } = await openPopup({ storageError: "Storage unavailable" }); assert.match(document.getElementById("siteStatus").textContent, /settings unavailable/i); assert.equal(document.getElementById("thisSite").disabled, true); }); (async () => { let passed = 0; for (const { name, fn } of tests) { try { await fn(); passed += 1; console.log(`PASS ${name}`); } catch (error) { console.error(`FAIL ${name}`); console.error(error.message); } } console.log(`\n${passed}/${tests.length} passed`); process.exitCode = passed === tests.length ? 0 : 1; })();