test: the Firefox suite tolerates no extension error (closes #487)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run

The one entry in ALLOWED_ERRORS in tests/e2e/firefox/run.js, Firefox
reporting a popup promise that settled after the page unloaded, lost its
cause when the site-connection buttons stopped sending with an unawaited
sendMessage before closing (#275). Left in place it would also hide the
same error from any other popup code that sends and then closes. The
entry goes, with the code that only printed and set aside tolerated
errors, and the README paragraph that described it.

Model: opus-5-5
This commit was merged in pull request #490.
This commit is contained in:
2026-10-07 07:26:09 +02:00
parent eeb10c20ef
commit cd8e45ae0c
3 changed files with 9 additions and 60 deletions
-8
View File
@@ -603,14 +603,6 @@ without an `await`. Demonstrated, not assumed: a `throw` placed past the first
and on Chrome (`pageerror`), with the rest of the run unaffected because the and on Chrome (`pageerror`), with the rest of the run unaffected because the
approval view had already rendered. approval view had already rendered.
One error is still tolerated rather than fatal, listed in `ALLOWED_ERRORS` in
`tests/e2e/firefox/run.js` and printed on every occurrence so the concession
stays visible in the run output: Firefox reporting an extension promise that
settled after its page unloaded, from anywhere in the popup. Its cause was the
site-approval popup's unawaited `sendMessage` before `window.close()`, which
[#275](https://git.eeqj.de/sneak/AutistMask/issues/275) removed; Firefox runs
since have not printed it, and
[#487](https://git.eeqj.de/sneak/AutistMask/issues/487) removes the entry.
Errors are read from the privileged `nsIConsoleService` in Marionette's chrome Errors are read from the privileged `nsIConsoleService` in Marionette's chrome
context and filtered to non-warning entries whose `sourceName` is the extension context and filtered to non-warning entries whose `sourceName` is the extension
origin. That mechanism is not a stylistic choice. WebDriver BiDi's origin. That mechanism is not a stylistic choice. WebDriver BiDi's
+8
View File
@@ -45,6 +45,14 @@ but the review is broader than any of them.
# Completed Steps # Completed Steps
- 2026-10-07: The Firefox end-to-end suite no longer tolerates any uncaught
extension error ([#487](https://git.eeqj.de/sneak/AutistMask/issues/487)). Its
one entry, Firefox reporting a popup promise that settled after the page
unloaded, had lost its cause with
[#275](https://git.eeqj.de/sneak/AutistMask/issues/275); the entry and the
code that printed tolerated errors are gone from `tests/e2e/firefox/run.js`,
and so is the README paragraph that described it.
- 2026-10-07: The toolbar icons in `icons/` can be redrawn in the tree - 2026-10-07: The toolbar icons in `icons/` can be redrawn in the tree
([#378](https://git.eeqj.de/sneak/AutistMask/issues/378)): `make icons` runs ([#378](https://git.eeqj.de/sneak/AutistMask/issues/378)): `make icons` runs
`script/lib/icons.js`, which draws the mark and writes each PNG with node's `script/lib/icons.js`, which draws the mark and writes each PNG with node's
+1 -52
View File
@@ -854,37 +854,6 @@ step(
// ------------------------------------------------------------- runner // ------------------------------------------------------------- runner
// Uncaught extension errors that are known, tracked and deliberately
// tolerated, in the same spirit as ALLOWED_ERRORS in tests/e2e/harness.js:
// every entry names the issue that will delete it, and every occurrence is
// still printed, so tolerating one is visible in the log rather than silent.
// This is the only concession in an otherwise zero-tolerance policy.
const ALLOWED_ERRORS = [
{
// The site-connection buttons in src/popup/views/approval.js send
// their decision and call window.close() on the next line. Firefox's
// BaseContext.wrapPromise reports, through Cu.reportError, any
// extension-API promise that settles after its context unloaded —
// whether or not the caller attached a handler, so notify()'s catch
// cannot suppress it.
//
// Pre-existing, and not introduced by the promise shim: the send was
// already unawaited, and this suite is merely the first thing to
// drive that window on Firefox. It is the same teardown ordering as
// the issue below, whose fix — making the outcome independent of when
// the popup closes — removes this entry with it.
pattern: /Promise (?:resolved|rejected) after context unloaded/,
source: /\/src\/popup\/index\.js$/,
issue: "https://git.eeqj.de/sneak/AutistMask/issues/275",
},
];
function allowedFor(e) {
return ALLOWED_ERRORS.find(
(a) => a.pattern.test(e.msg) && a.source.test(e.src),
);
}
function formatError(e) { function formatError(e) {
return ( return (
e.msg + " (" + e.src + ":" + e.line + (e.cat ? ", " + e.cat : "") + ")" e.msg + " (" + e.src + ":" + e.line + (e.cat ? ", " + e.cat : "") + ")"
@@ -1001,20 +970,6 @@ async function main() {
installFailure = null; installFailure = null;
} }
// Tolerated errors are set aside, never dropped: each one is
// printed with the issue that keeps it on the list, so the
// concession stays in the run output.
const tolerated = found.filter((e) => allowedFor(e));
found = found.filter((e) => !allowedFor(e));
for (const e of tolerated) {
console.log(
"# tolerated (" +
allowedFor(e).issue +
"): " +
formatError(e),
);
}
// Any uncaught error from an extension source fails the step // Any uncaught error from an extension source fails the step
// that provoked it, whether or not its assertions passed. // that provoked it, whether or not its assertions passed.
if (!failure && found.length > 0) { if (!failure && found.length > 0) {
@@ -1039,13 +994,7 @@ async function main() {
// blamed on any one step, but they are still reported and they // blamed on any one step, but they are still reported and they
// still fail the run. // still fail the run.
await sleep(1000); await sleep(1000);
const trailingAll = await errors.take(); const trailing = await errors.take();
for (const e of trailingAll.filter((x) => allowedFor(x))) {
console.log(
"# tolerated (" + allowedFor(e).issue + "): " + formatError(e),
);
}
const trailing = trailingAll.filter((e) => !allowedFor(e));
console.log( console.log(
"# " + "# " +
(steps.length - failed) + (steps.length - failed) +