test: containerized Firefox end-to-end harness (closes #184)
All checks were successful
check / check (push) Successful in 28s

Drives the real popup in a real Firefox with dist/firefox/ installed as an
unpacked MV2 temporary add-on, via geckodriver. Covers popup load, wallet
creation through the UI, and the Add Token screen. Outside make check, like
the Chrome suite.

Zero npm dependencies: tests/e2e/firefox/driver.js is a WebDriver client
over global fetch and child_process against geckodriver's HTTP API. The
Dockerfile pins the node base image, the Firefox 153.0.3 tarball and
geckodriver 0.36.0 by digest.

Errors are read from the privileged nsIConsoleService in Marionette's chrome
context, filtered to non-warning entries whose sourceName is the extension
origin. BiDi log.entryAdded delivers nothing at all for extension pages, so
a Playwright-BiDi or Puppeteer-BiDi harness would see nothing and report
success; the code says so where someone would be tempted to simplify it.
Errors logged during add-on install and background startup are drained and
folded into step 1, never discarded: a throw at the top of
src/background/index.js kills the background page and fails the run.
Content-script capture is left as unverified, because --network none leaves
no http:// page for a content script to be injected into.

No driver layer is shared with the Chrome suite and the three UI steps are
written twice deliberately: the two backends have no common substrate, and
three steps do not pay for a shim.

Two limits are documented rather than papered over. Error capture is
poll-based, so an error is attributed to a step and not to a moment within
it, and an error logged more than ~1s after the last step is missed
entirely because the browser is torn down. Nothing is stubbed; the container
runs with --network none instead, which proves no request escaped, cannot
report which were attempted, and runs only the failure branches of
network-dependent code.
This commit is contained in:
2026-08-12 08:42:22 +00:00
parent afe6ddaea0
commit ee9932b01b
7 changed files with 965 additions and 16 deletions

27
TODO.md
View File

@@ -30,9 +30,10 @@ compiled off.
The backlog lives on the
[Gitea tracker](https://git.eeqj.de/sneak/AutistMask/issues), which is
authoritative; this file does not duplicate it. Full policy file set present. A
real-browser end-to-end suite (`make test-e2e`) now sits alongside `make check`,
which cannot see a runtime `ReferenceError` in a popup view.
authoritative; this file does not duplicate it. Full policy file set present.
Real-browser end-to-end suites (`make test-e2e` for Chrome,
`make test-e2e-firefox` for Firefox) now sit alongside `make check`, which
cannot see a runtime `ReferenceError` in a popup view.
# Next Step
@@ -44,6 +45,18 @@ undefined identifiers, which is how
# Completed Steps
- 2026-08-12: A containerized Firefox end-to-end harness
(`make test-e2e-firefox`) drives the real popup in a real Firefox with the MV2
build installed as a temporary add-on. Zero npm dependencies — a WebDriver
client over `fetch` against geckodriver — with `node`, Firefox 153.0.3 and
geckodriver 0.36.0 all pinned by digest. Uncaught errors are read from the
privileged console service in Marionette's chrome context, because BiDi
`log.entryAdded` reports nothing at all for extension pages, and errors logged
during add-on install and background startup are folded into step 1 instead of
being cleared; demonstrated discriminating by exiting 1 on a `throw` at the
top of `src/background/index.js` and on a build with one import removed, and 0
on the branch as it stands
([#184](https://git.eeqj.de/sneak/AutistMask/issues/184)).
- 2026-08-12: WaitTx lifecycle: a receipt and the 60-second timeout can no
longer both render on one tick, no timer or in-flight lookup outlives its
wait, a failed receipt lookup no longer counts as a timeout (but six in a row
@@ -202,9 +215,9 @@ tracker.
- Pre-1.0 security review of the extension (key handling, DEBUG mode policy, RPC
input validation) before any 1.0rc tag. Individual filed issues are parts of
it, but the review is broader than any of them.
- Decide whether docker-in-docker makes `make test-e2e` runnable in the Gitea
workflow. Extending the suite itself is tracked as
[#183](https://git.eeqj.de/sneak/AutistMask/issues/183) and
[#184](https://git.eeqj.de/sneak/AutistMask/issues/184).
- Decide whether docker-in-docker makes `make test-e2e` and
`make test-e2e-firefox` runnable in the Gitea workflow. Extending the Chrome
suite itself is tracked as
[#183](https://git.eeqj.de/sneak/AutistMask/issues/183).
- Cut 1.0.0 once the milestone is empty, then continue tagging as milestones
land.