#!/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 of this run's own, as in script/test-e2e, which says why.
IMAGE="$("$SCRIPT_DIR/projectname")-e2e-firefox:$(od -An -N6 -tx1 /dev/urandom | tr -d ' \n')"

cleanup() {
    # 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
    trap 'cleanup; exit 130' 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 \
        --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 \
        --shm-size=1g \
        --network none \
        -e HOME=/tmp \
        "$IMAGE" \
        node tests/e2e/firefox/reinstall.js
}

main "$@"
