mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-10-18 19:30:27 +08:00
Run e2e tests in a Docker container
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
node_modules
|
||||
build
|
||||
.svelte-kit
|
||||
.git
|
||||
tests/tmp
|
||||
tests/artifacts
|
||||
tests/visual/snapshots
|
||||
data.ms
|
||||
dumps
|
||||
radicle-httpd/target
|
||||
radicle-search/target
|
||||
target
|
||||
.wrangler
|
||||
@@ -57,6 +57,38 @@ This will:
|
||||
1. Compile radicle-httpd from the `radicle-httpd/` directory
|
||||
2. Run the full test suite against the locally compiled binary
|
||||
|
||||
**Running e2e tests in Docker:**
|
||||
|
||||
If your host OS isn't supported by Playwright's browser builds (e.g. a very
|
||||
new or unusual Linux distribution), run the suite inside a container instead.
|
||||
Requires Docker with the Compose plugin.
|
||||
|
||||
scripts/test-e2e-docker
|
||||
|
||||
Any arguments are forwarded to `npm run test:e2e` (defaulting to
|
||||
`--project chromium` when none are given):
|
||||
|
||||
scripts/test-e2e-docker tests/e2e/repo.spec.ts
|
||||
scripts/test-e2e-docker --project chromium -g "some test name"
|
||||
|
||||
`SKIP_SETUP=true` is forwarded the same as for the native runner:
|
||||
|
||||
SKIP_SETUP=true scripts/test-e2e-docker
|
||||
|
||||
To test against a radicle-httpd you compile from source (the equivalent of
|
||||
`npm run test:e2e:local`), pass `--local`:
|
||||
|
||||
scripts/test-e2e-docker --local
|
||||
|
||||
Notes:
|
||||
* The first image build is slow (it downloads Chromium); subsequent runs are
|
||||
cached. `--local` additionally installs a Rust toolchain and compiles
|
||||
radicle-httpd on first use.
|
||||
* The repo is bind-mounted, so test artifacts and the binary/fixture cache
|
||||
land on the host as usual. `node_modules`, the cargo cache, and httpd's
|
||||
build directory live in container-private volumes, leaving your host copies
|
||||
untouched.
|
||||
|
||||
Proposing changes
|
||||
-----------------
|
||||
When proposing changes via a patch:
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# Runs the Playwright e2e suite in a Playwright-supported Linux distro.
|
||||
# Useful when the host OS is too new/old for Playwright's browser builds.
|
||||
#
|
||||
# Two stages:
|
||||
# base - Node + Chromium; runs the suite against the released radicle-httpd.
|
||||
# local - base + a Rust toolchain; additionally compiles radicle-httpd from
|
||||
# source for `--local` runs (needed when testing backend changes).
|
||||
#
|
||||
# Chromium and its OS dependencies are baked in at the project's pinned
|
||||
# Playwright version. node_modules and the repo are provided at runtime via
|
||||
# bind mount + named volume (see docker-compose.e2e.yml).
|
||||
FROM node:24-bookworm AS base
|
||||
|
||||
ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright \
|
||||
DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# xz-utils: install-binaries unpacks .tar.xz release archives.
|
||||
# git/curl/ca-certificates: fetching binaries and git operations in fixtures.
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
xz-utils ca-certificates git curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /work
|
||||
|
||||
# Install Chromium plus its apt-level runtime dependencies, pinned to the
|
||||
# Playwright version in package-lock.json so the baked browser matches the
|
||||
# @playwright/test that npm ci installs into the volume at runtime. Copying
|
||||
# only the lockfiles keeps this layer cached across source changes.
|
||||
# --ignore-scripts: the repo's postinstall (copy-katex/twemoji assets) needs
|
||||
# scripts/ which isn't in this layer; those run at runtime instead.
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci --ignore-scripts \
|
||||
&& npx playwright install --with-deps chromium \
|
||||
&& rm -rf node_modules
|
||||
|
||||
ENTRYPOINT ["/work/scripts/docker-e2e-entrypoint.sh"]
|
||||
|
||||
# --- local stage: adds Rust so the entrypoint can build radicle-httpd ---
|
||||
FROM base AS local
|
||||
|
||||
# Toolchain + build deps for compiling radicle-httpd (debug build).
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
build-essential pkg-config libssl-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV RUSTUP_HOME=/usr/local/rustup \
|
||||
CARGO_HOME=/usr/local/cargo \
|
||||
PATH=/usr/local/cargo/bin:$PATH
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
|
||||
| sh -s -- -y --no-modify-path --profile minimal --default-toolchain stable \
|
||||
&& rustc --version
|
||||
@@ -0,0 +1,43 @@
|
||||
x-e2e-common: &e2e-common
|
||||
init: true
|
||||
working_dir: /work
|
||||
environment:
|
||||
PLAYWRIGHT_BROWSERS_PATH: /ms-playwright
|
||||
|
||||
services:
|
||||
# Runs the suite against the released radicle-httpd binary.
|
||||
e2e:
|
||||
<<: *e2e-common
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.e2e
|
||||
target: base
|
||||
volumes:
|
||||
# Repo bind-mounted so code edits, test artifacts, and the
|
||||
# binary/fixture cache (tests/tmp) are shared with the host.
|
||||
- .:/work
|
||||
# Container-private node_modules: keeps the host's untouched and
|
||||
# avoids a glibc mismatch with host-built native modules.
|
||||
- e2e-node-modules:/work/node_modules
|
||||
|
||||
# Compiles radicle-httpd from source and runs the suite against it.
|
||||
# Used via `scripts/test-e2e-docker --local` when testing backend changes.
|
||||
e2e-local:
|
||||
<<: *e2e-common
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.e2e
|
||||
target: local
|
||||
volumes:
|
||||
- .:/work
|
||||
- e2e-node-modules:/work/node_modules
|
||||
# Container-private cargo crate cache and httpd build dir, so the
|
||||
# Rust build is incremental across runs and never mixes with the
|
||||
# host's (different glibc/rustc) target artifacts.
|
||||
- e2e-cargo-registry:/usr/local/cargo/registry
|
||||
- e2e-httpd-target:/work/radicle-httpd/target
|
||||
|
||||
volumes:
|
||||
e2e-node-modules:
|
||||
e2e-cargo-registry:
|
||||
e2e-httpd-target:
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
# Entrypoint for the e2e Docker container. Installs npm deps into the
|
||||
# container-private node_modules volume (only when package-lock.json changes),
|
||||
# ensures the Radicle test binaries are present, then runs Playwright. Any
|
||||
# arguments are forwarded to the test command.
|
||||
#
|
||||
# When USE_LOCAL_HTTPD=true, runs test:e2e:local (compiles radicle-httpd from
|
||||
# source and tests the frontend against it) instead of test:e2e.
|
||||
set -euo pipefail
|
||||
|
||||
cd /work
|
||||
|
||||
# The container runs as root, so anything it writes into the bind-mounted repo
|
||||
# would otherwise be root-owned on the host. Hand those paths back to the
|
||||
# invoking user (HOST_UID/HOST_GID set by scripts/test-e2e-docker) on exit.
|
||||
# radicle-httpd/target lives in a named volume, so it's not host-visible.
|
||||
cleanup() {
|
||||
if [ -n "${HOST_UID:-}" ]; then
|
||||
chown -R "$HOST_UID:${HOST_GID:-$HOST_UID}" \
|
||||
tests/tmp tests/artifacts tests/visual/snapshots build .svelte-kit \
|
||||
2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
LOCK_HASH=$(md5sum package-lock.json | cut -d' ' -f1)
|
||||
STAMP=node_modules/.lockhash
|
||||
if [ ! -f "$STAMP" ] || [ "$(cat "$STAMP")" != "$LOCK_HASH" ]; then
|
||||
echo "📦 Installing npm dependencies..."
|
||||
npm ci
|
||||
echo "$LOCK_HASH" >"$STAMP"
|
||||
else
|
||||
echo "📦 npm dependencies up to date."
|
||||
fi
|
||||
|
||||
echo "⬇️ Ensuring Radicle test binaries..."
|
||||
mkdir -p tests/artifacts
|
||||
./scripts/install-binaries
|
||||
|
||||
NPM_SCRIPT="test:e2e"
|
||||
if [ "${USE_LOCAL_HTTPD:-}" = "true" ]; then
|
||||
NPM_SCRIPT="test:e2e:local"
|
||||
echo "🦀 Local httpd mode: radicle-httpd will be compiled from source."
|
||||
fi
|
||||
|
||||
echo "🧪 Running e2e tests ($NPM_SCRIPT)..."
|
||||
set +e
|
||||
npm run "$NPM_SCRIPT" -- "$@"
|
||||
status=$?
|
||||
set -e
|
||||
exit "$status"
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build and run the Playwright e2e suite inside a Docker container. Use this
|
||||
# when the host OS is not supported by Playwright's browser builds.
|
||||
#
|
||||
# Usage:
|
||||
# scripts/test-e2e-docker # all chromium e2e tests
|
||||
# scripts/test-e2e-docker tests/e2e/foo.spec.ts # a single spec
|
||||
# scripts/test-e2e-docker --project chromium -g "some test"
|
||||
# scripts/test-e2e-docker --local # build radicle-httpd from
|
||||
# # source and test against it
|
||||
#
|
||||
# Any non-flag arguments are forwarded to the test command. When none are
|
||||
# given, defaults to `--project chromium`.
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT=$(cd "$(dirname "$0")/.." && pwd)
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
COMPOSE="docker compose -f docker-compose.e2e.yml"
|
||||
|
||||
# Strip our own --local flag; forward everything else to Playwright.
|
||||
LOCAL=false
|
||||
ARGS=()
|
||||
for arg in "$@"; do
|
||||
if [ "$arg" = "--local" ]; then
|
||||
LOCAL=true
|
||||
else
|
||||
ARGS+=("$arg")
|
||||
fi
|
||||
done
|
||||
|
||||
SERVICE=e2e
|
||||
EXTRA_ENV=()
|
||||
if $LOCAL; then
|
||||
SERVICE=e2e-local
|
||||
EXTRA_ENV=(-e USE_LOCAL_HTTPD=true)
|
||||
fi
|
||||
|
||||
$COMPOSE build "$SERVICE"
|
||||
|
||||
if [ "${#ARGS[@]}" -eq 0 ]; then
|
||||
ARGS=(--project chromium)
|
||||
fi
|
||||
|
||||
# SKIP_SETUP (no value) forwards the host's value through, mirroring the
|
||||
# native runner's fast-iteration flag.
|
||||
exec $COMPOSE run --rm \
|
||||
-e HOST_UID="$(id -u)" -e HOST_GID="$(id -g)" \
|
||||
-e SKIP_SETUP \
|
||||
"${EXTRA_ENV[@]}" \
|
||||
"$SERVICE" "${ARGS[@]}"
|
||||
Reference in New Issue
Block a user