test: load the popup's libraries once per test file, not on every boot (closes #428)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run

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
This commit is contained in:
2026-10-04 12:39:56 +00:00
parent 43c236451f
commit 7949c73afd
3 changed files with 31 additions and 6 deletions
+9
View File
@@ -45,6 +45,15 @@ but the review is broader than any of them.
# Completed Steps # 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 - 2026-10-04: `make test` runs jest in three worker processes
([#426](https://git.eeqj.de/sneak/AutistMask/issues/426)). The `test` and ([#426](https://git.eeqj.de/sneak/AutistMask/issues/426)). The `test` and
`test:verbose` scripts in `package.json` ran `jest --forceExit`, which starts `test:verbose` scripts in `package.json` ran `jest --forceExit`, which starts
+6 -6
View File
@@ -5,12 +5,12 @@
# many-core shared host one per core took gigabytes of RAM per run. # 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 # 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 # shared build host the suite takes 10-15s with three workers, inside
# REPO_POLICIES' 30s cap is tight there, not comfortable. Inside the image the # REPO_POLICIES' 20s budget. Inside the image the same suite also pays a cold
# same suite also pays a cold jest cache and shares the runner with the rest of # jest cache and shares the runner with the rest of the build, which is not what
# the build, which is not what that budget describes, so the Dockerfile raises # that budget describes, so the Dockerfile raises the bound through
# the bound through AUTISTMASK_TEST_TIMEOUT. A cap a healthy suite can trip on a # AUTISTMASK_TEST_TIMEOUT. A cap a healthy suite can trip on a cold cache
# cold cache produces a red that means nothing, and teaches "just run it again". # produces a red that means nothing, and teaches "just run it again".
set -eu set -eu
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)" ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
+16
View File
@@ -20,6 +20,17 @@ const path = require("path");
const { makeStorageStub } = require("./storageStub"); 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( const POPUP_HTML = fs.readFileSync(
path.join(__dirname, "..", "..", "src", "popup", "index.html"), path.join(__dirname, "..", "..", "src", "popup", "index.html"),
"utf8", "utf8",
@@ -219,6 +230,11 @@ async function settle() {
async function bootPopup(stored, options) { async function bootPopup(stored, options) {
jest.resetModules(); 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 // The three modules that reach the network. None is on the path under
// test; all would make the suite hit the internet. // test; all would make the suite hit the internet.
jest.doMock("../../src/shared/prices", () => ({ jest.doMock("../../src/shared/prices", () => ({