fix: an open popup moves to the recovery screen when its profile becomes unreadable (closes #373)
check / check (push) Failing after 1s
e2e / e2e-chrome (push) Failing after 2s
e2e / e2e-firefox (push) Failing after 2s

A popup already open when the stored profile became unreadable stayed on the
last good profile until reopened. Every save already reads the stored record
and runs the same check loadState() runs at open; the popup now sends a save
refused by that check to the recovery screen and stops its ten-second refresh,
while any other failed save keeps the "NOT SAVED" banner and the screen it is
on. The recovery screen ignores a second request to show it, so a save that
was in flight does not clear an export or a typed confirmation. The test
harness records the refresh loop so a test can run one tick of it.

Model: opus-5-5
This commit is contained in:
2026-10-04 19:50:14 +00:00
parent 3b713809c8
commit bdbe999c05
7 changed files with 130 additions and 22 deletions
+12 -2
View File
@@ -292,9 +292,14 @@ async function bootPopup(stored, options) {
}),
addEventListener: () => {},
};
// The 10s refresh loop init() starts would outlive the test.
// The 10s refresh loop init() starts would outlive the test, so it is
// recorded rather than started, and refresh() below runs it once.
const realSetInterval = globalThis.setInterval;
globalThis.setInterval = () => 0;
const intervals = [];
globalThis.setInterval = (fn) => {
intervals.push(fn);
return 0;
};
require("../../src/popup/index");
@@ -337,6 +342,11 @@ async function bootPopup(stored, options) {
for (const fn of fns) await fn();
await settle();
},
// One tick of the refresh loop, as if ten seconds had passed.
refresh: async () => {
for (const fn of intervals) await fn();
await settle();
},
settle,
// The view ids whose section is not hidden, as the audit measured them.
visibleViews: () => {