Import tests: test/popup
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
+102
@@ -0,0 +1,102 @@
|
|||||||
|
"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('<script src="popup.js"></script>', "");
|
||||||
|
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;
|
||||||
|
})();
|
||||||
Reference in New Issue
Block a user