// Unit tests for src/main.js, run by script/frontend-test with Node's // built-in test runner. Importing the module does not start the page. import { test } from "node:test"; import assert from "node:assert/strict"; import { CONFIG, measureLatency } from "../../src/main.js"; // measureLatency writes timeouts to the debug log, which looks for its // panel in the page. There is no page here. globalThis.document = { getElementById: () => null }; // Mocks the clock for test t, so that a check lasting seconds takes no real // time, and replaces fetch with a target that answers after answerAfter // milliseconds of that clock, or never when answerAfter is Infinity. Both // are restored when the test ends. function mockTarget(t, answerAfter) { t.mock.timers.enable({ apis: ["setTimeout", "Date"] }); t.mock.method(performance, "now", () => Date.now()); t.mock.method( globalThis, "fetch", (url, { signal }) => new Promise((resolve, reject) => { if (answerAfter !== Infinity) setTimeout(resolve, answerAfter); signal.addEventListener("abort", () => reject(signal.reason)); }), ); } // The result of check if it has ended, otherwise "still waiting". function settled(check) { return Promise.race([ check, new Promise((resolve) => setImmediate(resolve, "still waiting")), ]); } for (const interval of [10000, 30000]) { const timeout = interval * 0.8; // Over 3 seconds, which the timeout used to be capped at. const slowAnswer = timeout - 1000; test(`at a ${interval}ms interval, an answer after ${slowAnswer}ms is recorded with its real time`, async (t) => { CONFIG.updateInterval = interval; mockTarget(t, slowAnswer); const check = measureLatency("https://target.test"); t.mock.timers.tick(slowAnswer); assert.deepEqual(await settled(check), { latency: slowAnswer, error: null, }); }); test(`at a ${interval}ms interval, a target that never answers is recorded as a timeout after ${timeout}ms`, async (t) => { CONFIG.updateInterval = interval; mockTarget(t, Infinity); const check = measureLatency("https://target.test"); t.mock.timers.tick(timeout - 1); assert.equal(await settled(check), "still waiting"); t.mock.timers.tick(1); assert.deepEqual(await settled(check), { latency: null, error: "timeout", }); }); }