Files
AutistMask/script/test-e2e
clawbot 7cff69b35f
All checks were successful
check / check (push) Successful in 52s
e2e / e2e-chrome (push) Successful in 1m54s
e2e / e2e-firefox (push) Successful in 1m3s
wip: e2e in ci
2026-08-12 11:54:38 +00:00

86 lines
3.5 KiB
Bash
Executable File

#!/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. The e2e workflow
# in .gitea/workflows/e2e.yml runs it on every push, as a job separate
# from check so that cap and the local fast path both stay intact.
#
# Docker is the only prerequisite. The repo reaches the container as a
# build context and the extension is built inside it, so nothing here
# depends on the node, yarn or make on the machine that starts the run.
# That is not a convenience: it is what makes the CI job possible. The
# Gitea runner executes the job in a container against the host's docker
# socket, so a `docker run -v "$PWD:/work"` source path is resolved by the
# host daemon and mounts an empty directory (measured on this repo's
# runner), and the runner image ships node 18, which cannot install this
# repo's dependencies at all.
set -eu
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
IMAGE="$("$SCRIPT_DIR/projectname")-e2e-chrome"
IIDFILE=""
cleanup() {
if [ -n "$IIDFILE" ]; then
rm -f "$IIDFILE"
fi
}
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
IIDFILE="$(mktemp)"
trap cleanup EXIT
trap 'cleanup; exit 130' INT TERM
echo "Building the Chrome e2e image (extension included)..."
docker build --iidfile "$IIDFILE" -t "$IMAGE" -f tests/e2e/Dockerfile .
echo "Running e2e suite in the pinned Playwright container..."
# The image is run by ID, not by tag: on a machine where two clones of
# this repo run the suite at once, the tag can be moved by the other
# build between this build and this run, and the suite would then
# silently test the other checkout.
#
# --ipc=host: Chromium's shared-memory needs more than the default
# 64MB /dev/shm or renderers crash.
# HOME=/tmp: root's home is not writable in every base image and the
# browser profile goes under it.
# 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 \
-e HOME=/tmp \
-e PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS=1 \
-e "E2E_TRACE_NETWORK=${E2E_TRACE_NETWORK:-0}" \
"$(cat "$IIDFILE")" \
node tests/e2e/run.js
}
main "$@"