5 Commits

Author SHA1 Message Date
5c0e19d08f Replay on network host 2026-02-05 15:30:24 +01:00
cf9aa5bf88 Release version 1.1.1 2026-02-05 15:21:47 +01:00
a739a3fc5c fix(playwright): run codegen and replay containers as host user
Run Playwright Docker containers with the current host UID/GID to avoid
root-owned files in bind-mounted workspaces.

- Add --user UID:GID and HOME override to codegen and replay
- Harden replay workspace cleanup against leftover permission issues

https://chatgpt.com/share/6984a73c-14a0-800f-a40d-778972e518b7
2026-02-05 15:20:33 +01:00
5079e85eb5 Release version 1.1.0 2026-02-05 15:14:24 +01:00
5e9da6dc63 feat: add headless replay support for recorded Playwright tests
- add replay target to Makefile
- introduce scripts/replay.sh for headless test execution
- document replay workflow in README
- clarify requirements and Arch Linux setup

https://chatgpt.com/share/6984a4ca-1118-800f-88f9-1bd0146e922d
2026-02-05 15:09:55 +01:00
5 changed files with 167 additions and 3 deletions

View File

@@ -1,3 +1,13 @@
## [1.1.1] - 2026-02-05
* Fix permission issues by running Playwright Docker containers with the host UID/GID, preventing root-owned files during codegen and replay.
## [1.1.0] - 2026-02-05
* 🎬 Enable replay of recorded Playwright tests in headless mode
## [1.0.0] - 2026-02-05
* Official Release 🥳

View File

@@ -19,3 +19,9 @@ install:
## 🎥 Run Playwright Codegen (GUI recording)
codegen:
bash scripts/codegen.sh
.PHONY: replay
## ▶ Replay recorded Playwright tests (headless)
replay:
bash scripts/replay.sh

View File

@@ -37,12 +37,18 @@ Perfect for:
### 1⃣ Requirements
* Docker
* X11 or XWayland (Wayland-only will NOT work)
* `xhost`
- Docker
- X11 or XWayland (Wayland-only will NOT work)
- `xhost`
On Arch Linux:
```bash
sudo pacman -S --needed xorg-xhost
```
---
## ⚙️ Installation (one-time)
Prepare the recorder script:
@@ -69,6 +75,24 @@ Or with a start URL:
---
## ▶ Replay recorded tests (headless)
Run all recorded tests:
```bash
make replay
```
Run a specific test file:
```bash
./scripts/replay.sh recordings/login.spec.ts
```
Replay runs **headless**, without X11, and does **not** require `xhost`.
---
## 📤 Output
* 📄 Generated test:

View File

@@ -37,6 +37,10 @@ require_cmd xhost
: "${DISPLAY:=:0}"
# Run containers as the current host user to avoid root-owned files in bind mounts.
USER_ID="$(id -u)"
GROUP_ID="$(id -g)"
ROOT="$(repo_root)"
REC_DIR="${ROOT}/${RECORDINGS_DIR}"
WORK_DIR="${REC_DIR}/.work"
@@ -107,6 +111,8 @@ if [[ -n "${START_URL}" ]]; then
fi
docker run --rm -it \
--user "${USER_ID}:${GROUP_ID}" \
-e HOME=/tmp \
--ipc=host \
--network host \
-e "DISPLAY=${DISPLAY}" \

118
scripts/replay.sh Normal file
View File

@@ -0,0 +1,118 @@
#!/usr/bin/env bash
set -euo pipefail
# -----------------------------------------------------------------------------
# playwright-recorder: Replay Playwright tests (headless)
#
# Purpose:
# - Replay previously generated Playwright tests
# - Run fully headless
# - Use Docker + official Playwright image
# - No GUI, no X11, no xhost
#
# Usage:
# ./scripts/replay.sh
# ./scripts/replay.sh recordings/login.spec.ts
#
# Optional env vars:
# PLAYWRIGHT_VERSION=1.58.1
# PLAYWRIGHT_IMAGE=mcr.microsoft.com/playwright:v1.58.1-jammy
# RECORDINGS_DIR=recordings
# -----------------------------------------------------------------------------
PLAYWRIGHT_VERSION="${PLAYWRIGHT_VERSION:-1.58.1}"
PLAYWRIGHT_IMAGE="${PLAYWRIGHT_IMAGE:-mcr.microsoft.com/playwright:v${PLAYWRIGHT_VERSION}-jammy}"
RECORDINGS_DIR="${RECORDINGS_DIR:-recordings}"
TEST_FILE="${1:-}"
die() { echo "ERROR: $*" >&2; exit 1; }
require_cmd() {
command -v "$1" >/dev/null 2>&1 || die "Missing command: $1"
}
repo_root() {
git rev-parse --show-toplevel 2>/dev/null || pwd
}
require_cmd docker
# Run containers as the current host user to avoid root-owned files in bind mounts.
USER_ID="$(id -u)"
GROUP_ID="$(id -g)"
ROOT="$(repo_root)"
REC_DIR="${ROOT}/${RECORDINGS_DIR}"
[[ -d "${REC_DIR}" ]] || die "Recordings dir not found: ${REC_DIR}"
# Build ephemeral workspace
WORK_DIR="${REC_DIR}/.replay-work"
# Robust cleanup: handle possible permission issues from previous runs.
if [[ -e "${WORK_DIR}" ]]; then
chmod -R u+rwX "${WORK_DIR}" 2>/dev/null || true
rm -rf "${WORK_DIR}" 2>/dev/null || true
fi
mkdir -p "${WORK_DIR}/tests"
cleanup() {
rm -rf "${WORK_DIR}" >/dev/null 2>&1 || true
}
trap cleanup EXIT
# Copy recorded tests into workspace
if [[ -n "${TEST_FILE}" ]]; then
[[ -f "${ROOT}/${TEST_FILE}" ]] || die "Test file not found: ${TEST_FILE}"
cp "${ROOT}/${TEST_FILE}" "${WORK_DIR}/tests/"
else
shopt -s nullglob
cp "${REC_DIR}"/*.spec.ts "${WORK_DIR}/tests/" || die "No *.spec.ts found in ${REC_DIR}"
fi
# Minimal Playwright project
cat > "${WORK_DIR}/package.json" <<EOF
{
"name": "playwright-replay",
"private": true,
"type": "commonjs",
"devDependencies": {
"@playwright/test": "${PLAYWRIGHT_VERSION}"
},
"scripts": {
"test": "playwright test"
}
}
EOF
cat > "${WORK_DIR}/playwright.config.ts" <<'EOF'
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
use: {
headless: true,
trace: 'retain-on-failure',
},
});
EOF
echo "▶ Replaying Playwright tests"
echo "Image : ${PLAYWRIGHT_IMAGE}"
echo "Workspace : ${WORK_DIR}"
echo "Tests : ${TEST_FILE:-all recordings}"
echo
docker run --rm \
--network host \
--user "${USER_ID}:${GROUP_ID}" \
-e HOME=/tmp \
-v "${WORK_DIR}:/work" \
-w /work \
"${PLAYWRIGHT_IMAGE}" \
bash -lc "npm install --no-audit --no-fund && npx playwright test"
echo
echo "✔ Replay finished"