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
|
1. Compile radicle-httpd from the `radicle-httpd/` directory
|
||||||
2. Run the full test suite against the locally compiled binary
|
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
|
Proposing changes
|
||||||
-----------------
|
-----------------
|
||||||
When proposing changes via a patch:
|
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