test: containerized Chrome end-to-end harness that drives the real popup (closes #181)
Some checks failed
check / check (push) Has been cancelled

`make check` was green while the AddToken screen crashed on every open.
`script/lint` is only `prettier --check`, so a used-but-not-imported
identifier is invisible until a browser evaluates it. This adds a suite
that runs the real popup in a real Chrome and treats any uncaught page
error or console.error as a failure.

- `script/test-e2e` (with `make test-e2e` as a thin shim) builds
  `dist/chrome/` and runs `tests/e2e/run.js` inside the Playwright image,
  pinned by digest. `playwright-core` is pinned to the matching 1.56.0
  through `yarn.lock`; the two must be bumped together because the
  browsers ship inside the image.
- Deliberately outside `script/test` and `script/check`: REPO_POLICIES
  caps `make test` at 20 seconds. Nothing under `tests/e2e/` is named
  `*.test.js`, so jest cannot pick it up either.
- Launches with `channel: "chromium"`; the default headless shell
  silently refuses to load extensions with no error at all. The extension
  id is read from the service worker URL, never hardcoded.
- All http(s) traffic is intercepted at the browser level and served from
  fixtures, so the run is deterministic and offline. Unrecognised
  outbound requests are reported as failures rather than allowed.
- A missing build or an unavailable container fails loudly; a skip that
  looks like a pass is the failure mode this is meant to prevent.
- One allowlisted page error, for the libsodium WASM CSP fallback tracked
  as #182, which is otherwise untouched here.

The suite was demonstrated failing against the unfixed tree with
`pageerror: showView is not defined` and `pageerror: addressDotHtml is
not defined`, so it carries the two one-line import fixes it caught:

closes #150 — `showView` restored to the destructure in
`src/popup/views/addToken.js`, dropped by a22f33d, which made the
AddToken screen unreachable and corrupted the navigation stack.

closes #151 — `addressDotHtml` restored in
`src/popup/views/transactionDetail.js`, dropped by df031fd, which threw
before `showView("transaction")` for every ERC-20 transfer. The shared
`renderAddressHtml` helper is not used here on purpose: it hardcodes the
`/address/` explorer URL, and this row needs the token-specific `/token/`
link.
This commit is contained in:
2026-08-09 14:24:36 +00:00
parent 23aeae4841
commit a6885a0d62
11 changed files with 710 additions and 12 deletions

48
script/test-e2e Executable file
View File

@@ -0,0 +1,48 @@
#!/bin/sh
# script/test-e2e: build the extension and drive the real popup in a real
# Chromium inside a pinned container. Our own extension to
# scripts-to-rule-them-all.
#
# Deliberately NOT called by script/check or script/test: REPO_POLICIES.md
# caps make test at 20 seconds and a browser suite does not fit. Run it
# yourself before touching popup views; it is the only check that can see
# a used-but-not-imported identifier blow up at runtime.
set -eu
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
# mcr.microsoft.com/playwright:v1.56.0-noble, 2026-08-09
#
# The playwright-core devDependency is pinned to the matching Playwright
# version (1.56.0) and the two must be bumped together: the browsers ship
# inside this image, and playwright-core looks for the exact browser
# revision its own version expects. A mismatch fails at launch.
IMAGE="mcr.microsoft.com/playwright@sha256:35246d87a7c88ea9b771c65d33171b2611b02a8253b4b12ce6f94376c55f99f2"
main() {
cd "$ROOT"
if ! command -v docker >/dev/null 2>&1; then
echo "test-e2e: docker is required to run the e2e suite" >&2
exit 1
fi
echo "Building extension for e2e..."
yarn run build 2>&1
echo "Running e2e suite in the pinned Playwright container..."
# --ipc=host: Chromium's shared-memory needs more than the default
# 64MB /dev/shm or renderers crash.
# --user: keep files the suite touches owned by the caller, not root.
# HOME=/tmp: the mapped uid has no home directory in the image.
docker run --rm \
--ipc=host \
--user "$(id -u):$(id -g)" \
-e HOME=/tmp \
-v "$ROOT:/work" \
-w /work \
"$IMAGE" \
node tests/e2e/run.js
}
main "$@"