script/test-e2e and script/test-e2e-firefox tagged their image with one fixed name. When two clones ran a suite at once, the second build moved that tag, the image store deleted the first run's now-untagged image, and that suite exited 125 without running a test. Each run now tags its image with the suite's name and twelve random hex digits and runs it by that tag. The cleanup that runs on exit, Ctrl-C, kill and a closed terminal removes the run's container if docker's client left it running, then the image. The image-ID file that guarded against a moving tag is gone. README.md's End-to-End Tests section says which endings clean up. Model: opus-5-5
99 lines
3.9 KiB
Bash
Executable File
99 lines
3.9 KiB
Bash
Executable File
#!/bin/sh
|
|
# script/test-e2e-firefox: build the extension and drive the real popup in
|
|
# a real Firefox inside a pinned container. The Firefox counterpart to
|
|
# script/test-e2e. Our own extension to scripts-to-rule-them-all.
|
|
#
|
|
# Deliberately NOT called by script/check or script/test, for the same
|
|
# reason as the Chrome suite: REPO_POLICIES.md caps make test at 60 seconds
|
|
# and a browser suite does not fit. .gitea/workflows/e2e.yml also runs it
|
|
# on every push, in a job separate from check.
|
|
#
|
|
# Unlike script/test-e2e this builds its base image locally, because no
|
|
# published image carries both a pinned Firefox and a matching geckodriver.
|
|
# All three external artifacts are pinned by digest inside the Dockerfile;
|
|
# see tests/e2e/firefox/Dockerfile, which also explains why the repo and
|
|
# the extension build are baked into the image rather than mounted.
|
|
#
|
|
# Docker is the only prerequisite: nothing here depends on the node, yarn
|
|
# or make on the machine that starts the run.
|
|
set -eu
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
|
ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
|
|
|
# A tag and a container name of this run's own, as in script/test-e2e,
|
|
# which says why.
|
|
SUFFIX="$(od -An -N6 -tx1 /dev/urandom | tr -d ' \n')"
|
|
NAME="$("$SCRIPT_DIR/projectname")-e2e-firefox"
|
|
IMAGE="$NAME:$SUFFIX"
|
|
CONTAINER="$NAME-$SUFFIX"
|
|
|
|
cleanup() {
|
|
# After a third Ctrl-C docker's client exits whether or not the
|
|
# container has stopped, and a container still running keeps the image
|
|
# in use.
|
|
if docker container inspect "$CONTAINER" >/dev/null 2>&1; then
|
|
docker container rm -f "$CONTAINER" >/dev/null
|
|
fi
|
|
# No image to remove when the build failed or was interrupted.
|
|
if docker image inspect "$IMAGE" >/dev/null 2>&1; then
|
|
docker image rm "$IMAGE" >/dev/null
|
|
fi
|
|
}
|
|
|
|
main() {
|
|
cd "$ROOT"
|
|
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
echo "test-e2e-firefox: docker is required to run the e2e suite" >&2
|
|
exit 1
|
|
fi
|
|
|
|
trap cleanup EXIT
|
|
# HUP: the terminal or SSH session running the suite closed.
|
|
trap 'cleanup; exit 130' HUP INT TERM
|
|
|
|
echo "Building the pinned Firefox e2e image (extension included)..."
|
|
# --no-cache: the image build runs make build and its checks, and a
|
|
# cached layer is a check that did not run.
|
|
docker build --no-cache -t "$IMAGE" -f tests/e2e/firefox/Dockerfile .
|
|
|
|
echo "Running the Firefox e2e suite..."
|
|
# --shm-size=1g: Firefox needs more than the default 64MB /dev/shm.
|
|
# --network none: the suite stubs nothing, so this is what keeps the
|
|
# run offline and deterministic. The extension swallows its own
|
|
# fetch failures, so the popup flows work unchanged; see the
|
|
# network note in README.md. Weaker than the Chrome suite's
|
|
# fixture interception, and honestly so — it proves no request
|
|
# escaped, but it cannot report which ones were attempted.
|
|
# HOME=/tmp: the image's root home is not a reliable place for the
|
|
# browser profile.
|
|
#
|
|
# No --privileged. Firefox's sandbox logs
|
|
# "CanCreateUserNamespace() clone() failure: EPERM" on startup here;
|
|
# it is cosmetic and headless Firefox runs fine without it.
|
|
docker run --rm \
|
|
--name "$CONTAINER" \
|
|
--shm-size=1g \
|
|
--network none \
|
|
-e HOME=/tmp \
|
|
"$IMAGE" \
|
|
node tests/e2e/firefox/run.js dist/firefox
|
|
|
|
# The install/uninstall/re-install property, against the packaged XPI
|
|
# rather than the unpacked directory: it is the artifact a user would be
|
|
# handed, and this is the only place a real Firefox is asked to load it.
|
|
# Its own browser session, because it takes the add-on away in the middle
|
|
# and the suite above shares one session throughout.
|
|
echo "Running the Firefox re-install suite against the packaged XPI..."
|
|
docker run --rm \
|
|
--name "$CONTAINER" \
|
|
--shm-size=1g \
|
|
--network none \
|
|
-e HOME=/tmp \
|
|
"$IMAGE" \
|
|
node tests/e2e/firefox/reinstall.js
|
|
}
|
|
|
|
main "$@"
|