#!/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. # PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS=1: without it, # ctx.route() intercepts page requests only, and every fetch made by # the MV3 background service worker — including the phishing # blocklist fetch that src/background/index.js issues at worker # startup — goes to the real internet. The flag is experimental and # Playwright may drop or rename it. It cannot break silently: the # harness probes service-worker interception at launch and aborts # the whole suite if it is not in effect (see the interception # canary in tests/e2e/harness.js). If a future Playwright removes # the flag, that probe is what will fail, and the fix is either a # replacement mechanism or an honest downgrade of the isolation # claim in tests/e2e/network.js and README.md — not deleting the # probe. The image is pinned by digest, so this can only ever bite # on a deliberate bump. docker run --rm \ --ipc=host \ --user "$(id -u):$(id -g)" \ -e HOME=/tmp \ -e PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS=1 \ -e "E2E_TRACE_NETWORK=${E2E_TRACE_NETWORK:-0}" \ -v "$ROOT:/work" \ -w /work \ "$IMAGE" \ node tests/e2e/run.js } main "$@"