mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-12 06:52:57 +02:00
test(e2e): run playwright via container (#37300)
Enable running playwright tests on unsupported platforms as well Signed-off-by: wxiaoguang <wxiaoguang@gmail.com> Signed-off-by: silverwind <me@silverwind.io> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
This commit is contained in:
parent
a61598884f
commit
c78c84c3ca
5
Makefile
5
Makefile
@ -468,12 +468,11 @@ migrations.individual.test\#%:
|
|||||||
|
|
||||||
.PHONY: playwright
|
.PHONY: playwright
|
||||||
playwright: deps-frontend
|
playwright: deps-frontend
|
||||||
@# on GitHub Actions VMs, playwright's system deps are pre-installed
|
@./tools/test-e2e.sh install
|
||||||
@pnpm exec playwright install $(if $(GITHUB_ACTIONS),,--with-deps) chromium firefox $(PLAYWRIGHT_FLAGS)
|
|
||||||
|
|
||||||
.PHONY: test-e2e
|
.PHONY: test-e2e
|
||||||
test-e2e: playwright frontend backend
|
test-e2e: playwright frontend backend
|
||||||
@EXECUTABLE=$(EXECUTABLE) ./tools/test-e2e.sh $(GITEA_TEST_E2E_FLAGS)
|
@EXECUTABLE=$(EXECUTABLE) ./tools/test-e2e.sh run $(GITEA_TEST_E2E_FLAGS)
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build: frontend backend ## build everything
|
build: frontend backend ## build everything
|
||||||
|
|||||||
@ -1,13 +1,99 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
CONTAINER_RUNTIME="${CONTAINER_RUNTIME:-docker}"
|
||||||
|
CONTAINER_NAME="gitea-e2e-runner-$$"
|
||||||
|
|
||||||
|
free_port() {
|
||||||
|
node -e "const s=require('net').createServer();s.listen(0,'127.0.0.1',()=>{process.stdout.write(String(s.address().port));s.close()})"
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_playwright_mode() {
|
||||||
|
if [ "${PLAYWRIGHT_MODE:-auto}" = "local" ] || [ "${PLAYWRIGHT_MODE:-auto}" = "container" ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
PLAYWRIGHT_MODE="local"
|
||||||
|
|
||||||
|
if [ "$(uname -s)" = "Linux" ]; then
|
||||||
|
# playwright only supports ubuntu/debian officially
|
||||||
|
if ! grep -qE '^ID(_LIKE)?=.*(ubuntu|debian)' /etc/os-release 2>/dev/null; then
|
||||||
|
PLAYWRIGHT_MODE="container"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_container() {
|
||||||
|
local max_wait=30
|
||||||
|
local elapsed=0
|
||||||
|
echo "Waiting for container to start..."
|
||||||
|
while ! (echo > "/dev/tcp/127.0.0.1/$PLAYWRIGHT_SERVER_PORT") 2>/dev/null; do
|
||||||
|
if [ "$("$CONTAINER_RUNTIME" inspect -f '{{.State.Running}}' "$CONTAINER_NAME" 2>/dev/null)" != "true" ]; then
|
||||||
|
echo "Error: container exited before becoming ready." >&2
|
||||||
|
"$CONTAINER_RUNTIME" logs "$CONTAINER_NAME" >&2 || true
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ "$elapsed" -ge "$max_wait" ]; then
|
||||||
|
echo "Error: container did not become ready after ${max_wait}s." >&2
|
||||||
|
"$CONTAINER_RUNTIME" logs "$CONTAINER_NAME" >&2 || true
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
elapsed=$((elapsed + 1))
|
||||||
|
done
|
||||||
|
echo "Container is ready."
|
||||||
|
}
|
||||||
|
|
||||||
|
CMD="${1:-run}"
|
||||||
|
if [ "$CMD" = "install" ] || [ "$CMD" = "run" ]; then
|
||||||
|
[ $# -gt 0 ] && shift
|
||||||
|
else
|
||||||
|
CMD="run"
|
||||||
|
fi
|
||||||
|
|
||||||
|
detect_playwright_mode
|
||||||
|
|
||||||
|
if [ "$PLAYWRIGHT_MODE" = "container" ]; then
|
||||||
|
if ! command -v "$CONTAINER_RUNTIME" >/dev/null 2>&1; then
|
||||||
|
echo "error: PLAYWRIGHT_MODE=container but '$CONTAINER_RUNTIME' is not installed." >&2
|
||||||
|
echo "Install docker/podman or set CONTAINER_RUNTIME to an available runtime." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
PLAYWRIGHT_VERSION=$(sed -n 's/.*"@playwright\/test"[[:space:]]*:[[:space:]]*"[^[:digit:]]*\([^"]*\)".*/\1/p' package.json)
|
||||||
|
if ! [[ "$PLAYWRIGHT_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.]+)?$ ]]; then
|
||||||
|
echo "error: invalid @playwright/test version in package.json: '${PLAYWRIGHT_VERSION}'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
PLAYWRIGHT_IMAGE="mcr.microsoft.com/playwright:v${PLAYWRIGHT_VERSION}-noble"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$CMD" = "install" ]; then
|
||||||
|
if [ "$PLAYWRIGHT_MODE" = "local" ]; then
|
||||||
|
# on GitHub Actions VMs, playwright's system deps are pre-installed
|
||||||
|
if [ -z "${GITHUB_ACTIONS:-}" ]; then
|
||||||
|
pnpm exec playwright install --with-deps chromium firefox ${PLAYWRIGHT_FLAGS:-}
|
||||||
|
else
|
||||||
|
pnpm exec playwright install chromium firefox ${PLAYWRIGHT_FLAGS:-}
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Running playwright in container as host distro is not supported by playwright directly"
|
||||||
|
if ! "$CONTAINER_RUNTIME" image inspect "$PLAYWRIGHT_IMAGE" >/dev/null 2>&1; then
|
||||||
|
"$CONTAINER_RUNTIME" pull "$PLAYWRIGHT_IMAGE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
# Create isolated work directory
|
# Create isolated work directory
|
||||||
WORK_DIR=$(mktemp -d)
|
WORK_DIR=$(mktemp -d)
|
||||||
|
|
||||||
# Find a random free port
|
# Find a random free port
|
||||||
FREE_PORT=$(node -e "const s=require('net').createServer();s.listen(0,'127.0.0.1',()=>{process.stdout.write(String(s.address().port));s.close()})")
|
FREE_PORT=$(free_port)
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
|
if [ "$PLAYWRIGHT_MODE" = "container" ]; then
|
||||||
|
"$CONTAINER_RUNTIME" stop "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
if [ -n "${SERVER_PID:-}" ]; then
|
if [ -n "${SERVER_PID:-}" ]; then
|
||||||
kill "$SERVER_PID" 2>/dev/null || true
|
kill "$SERVER_PID" 2>/dev/null || true
|
||||||
wait "$SERVER_PID" 2>/dev/null || true
|
wait "$SERVER_PID" 2>/dev/null || true
|
||||||
@ -16,6 +102,16 @@ cleanup() {
|
|||||||
}
|
}
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
if [ "$PLAYWRIGHT_MODE" = "container" ]; then
|
||||||
|
PLAYWRIGHT_SERVER_PORT=$(free_port)
|
||||||
|
# --network=host: container needs host loopback to reach gitea.
|
||||||
|
"$CONTAINER_RUNTIME" run --network=host --name "$CONTAINER_NAME" -d --rm --init --workdir /home/pwuser --user pwuser "$PLAYWRIGHT_IMAGE" /bin/sh -c "npx -y playwright@${PLAYWRIGHT_VERSION} run-server --port ${PLAYWRIGHT_SERVER_PORT} --host 0.0.0.0"
|
||||||
|
|
||||||
|
if ! wait_for_container; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Write config file for isolated instance
|
# Write config file for isolated instance
|
||||||
mkdir -p "$WORK_DIR/custom/conf"
|
mkdir -p "$WORK_DIR/custom/conf"
|
||||||
cat > "$WORK_DIR/custom/conf/app.ini" <<EOF
|
cat > "$WORK_DIR/custom/conf/app.ini" <<EOF
|
||||||
@ -112,4 +208,7 @@ export GITEA_TEST_E2E_PASSWORD
|
|||||||
export GITEA_TEST_E2E_EMAIL
|
export GITEA_TEST_E2E_EMAIL
|
||||||
export GITEA_TEST_E2E_TIMEOUT_FACTOR
|
export GITEA_TEST_E2E_TIMEOUT_FACTOR
|
||||||
|
|
||||||
|
if [ "$PLAYWRIGHT_MODE" = "container" ]; then
|
||||||
|
export PW_TEST_CONNECT_WS_ENDPOINT="ws://127.0.0.1:${PLAYWRIGHT_SERVER_PORT}/"
|
||||||
|
fi
|
||||||
pnpm exec playwright test "$@"
|
pnpm exec playwright test "$@"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user