From 7949c73afdcf09653f59b138490cf43ee33dd0c6 Mon Sep 17 00:00:00 2001 From: sneak Date: Sun, 4 Oct 2026 12:39:56 +0000 Subject: [PATCH] test: load the popup's libraries once per test file, not on every boot (closes #428) Every popup boot in the tests resets jest's module registry so that src/ loads fresh, and that also reloaded ethers, libsodium-wrappers-sumo, qrcode and ethereum-blockies-base64 each time: more than half of a boot, and tests/persistedFieldContract.test.js boots the popup 321 times. tests/support/popupBoot.js now loads those four once per test file and hands the same copies to every boot. No test or assertion changed. make test takes 10-15s on the shared build host instead of 23-29s. Model: opus-5-5 --- TODO.md | 9 +++++++++ script/test | 12 ++++++------ tests/support/popupBoot.js | 16 ++++++++++++++++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/TODO.md b/TODO.md index 316be33..d67c3e0 100644 --- a/TODO.md +++ b/TODO.md @@ -45,6 +45,15 @@ but the review is broader than any of them. # Completed Steps +- 2026-10-04: `make test` takes 10-15s on the shared build host, down from + 23-29s ([#428](https://git.eeqj.de/sneak/AutistMask/issues/428)). Each popup + boot in the tests (`tests/support/popupBoot.js`) resets jest's module registry + so that everything under `src/` loads fresh, and that also reloaded `ethers`, + `libsodium-wrappers-sumo`, `qrcode` and `ethereum-blockies-base64` every time: + more than half of each boot, and `tests/persistedFieldContract.test.js` boots + the popup 321 times. Those four libraries are now loaded once per test file + and handed to every boot. No test or assertion changed. + - 2026-10-04: `make test` runs jest in three worker processes ([#426](https://git.eeqj.de/sneak/AutistMask/issues/426)). The `test` and `test:verbose` scripts in `package.json` ran `jest --forceExit`, which starts diff --git a/script/test b/script/test index ebe015c..b329fd3 100755 --- a/script/test +++ b/script/test @@ -5,12 +5,12 @@ # many-core shared host one per core took gigabytes of RAM per run. # # The timeout bounds a hung suite; it is not a performance budget. On the busy -# shared build host the suite takes 23-29s with three workers, so -# REPO_POLICIES' 30s cap is tight there, not comfortable. Inside the image the -# same suite also pays a cold jest cache and shares the runner with the rest of -# the build, which is not what that budget describes, so the Dockerfile raises -# the bound through AUTISTMASK_TEST_TIMEOUT. A cap a healthy suite can trip on a -# cold cache produces a red that means nothing, and teaches "just run it again". +# shared build host the suite takes 10-15s with three workers, inside +# REPO_POLICIES' 20s budget. Inside the image the same suite also pays a cold +# jest cache and shares the runner with the rest of the build, which is not what +# that budget describes, so the Dockerfile raises the bound through +# AUTISTMASK_TEST_TIMEOUT. A cap a healthy suite can trip on a cold cache +# produces a red that means nothing, and teaches "just run it again". set -eu ROOT="$(cd "$(dirname "$0")/.." && pwd -P)" diff --git a/tests/support/popupBoot.js b/tests/support/popupBoot.js index e8dcebb..47a557b 100644 --- a/tests/support/popupBoot.js +++ b/tests/support/popupBoot.js @@ -20,6 +20,17 @@ const path = require("path"); const { makeStorageStub } = require("./storageStub"); +// The four libraries the popup loads from node_modules, loaded once per test +// file and handed to every boot. jest.resetModules() in bootPopup() would +// otherwise load them again on every boot, which was more than half of what a +// boot cost. None of them holds popup state; everything under src/ is still +// loaded fresh on each boot. A test that mocks one of these itself has its mock +// replaced by bootPopup(). +const ethers = require("ethers"); +const sodium = require("libsodium-wrappers-sumo"); +const QRCode = require("qrcode"); +const makeBlockie = require("ethereum-blockies-base64"); + const POPUP_HTML = fs.readFileSync( path.join(__dirname, "..", "..", "src", "popup", "index.html"), "utf8", @@ -219,6 +230,11 @@ async function settle() { async function bootPopup(stored, options) { jest.resetModules(); + jest.doMock("ethers", () => ethers); + jest.doMock("libsodium-wrappers-sumo", () => sodium); + jest.doMock("qrcode", () => QRCode); + jest.doMock("ethereum-blockies-base64", () => makeBlockie); + // The three modules that reach the network. None is on the path under // test; all would make the suite hit the internet. jest.doMock("../../src/shared/prices", () => ({