Files
playwright-recorder/scripts/codegen.sh
Kevin Veen-Birkenbach df66e3547e feat: add standalone Playwright recorder tool with Docker-based codegen
- introduce repo-local, ephemeral Playwright codegen workflow
- add executable codegen script using official Playwright Docker image
- persist generated recordings under recordings/ (git-ignored, .gitkeep)
- add minimal Makefile with install and codegen targets
- switch project license to MIT
- improve README with clear usage, requirements, and design rationale
- add MIRRORS file for multi-remote setup
- clean up gitignore for generated artifacts and node tooling
2026-02-05 14:56:46 +01:00

123 lines
3.2 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# -----------------------------------------------------------------------------
# playwright-recorder: Playwright Codegen (fresh, repo-local workspace)
#
# Purpose:
# - ALWAYS start fresh (no dependency on repo state)
# - Do NOT use /tmp for recordings/workspace
# - Use repo-local ignored workspace: recordings/.work
# - Persist generated tests into repo-local ignored dir: recordings/
# - Run everything inside the official Playwright container (version pinned)
# -----------------------------------------------------------------------------
PLAYWRIGHT_VERSION="${PLAYWRIGHT_VERSION:-1.58.1}"
PLAYWRIGHT_IMAGE="${PLAYWRIGHT_IMAGE:-mcr.microsoft.com/playwright:v${PLAYWRIGHT_VERSION}-jammy}"
RECORDINGS_DIR="${RECORDINGS_DIR:-recordings}"
OUTPUT_FILE="${OUTPUT_FILE:-codegen.spec.ts}"
TARGET="${TARGET:-playwright-test}"
START_URL="${1:-}"
die() { echo "ERROR: $*" >&2; exit 1; }
warn() { echo "WARNING: $*" >&2; }
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
require_cmd xhost
: "${DISPLAY:=:0}"
ROOT="$(repo_root)"
REC_DIR="${ROOT}/${RECORDINGS_DIR}"
WORK_DIR="${REC_DIR}/.work"
mkdir -p "${REC_DIR}"
cleanup() {
# revoke X11 permission
xhost -local:docker >/dev/null 2>&1 || true
# remove ephemeral workspace
rm -rf "${WORK_DIR}" >/dev/null 2>&1 || true
}
trap cleanup EXIT
# X11 socket sanity check (helpful hint only)
if [[ "${DISPLAY}" == ":0" && ! -S /tmp/.X11-unix/X0 ]]; then
warn "No /tmp/.X11-unix/X0 socket detected."
warn "You might be on pure Wayland without XWayland."
warn "Playwright codegen requires X11/XWayland (or a nested X server)."
fi
# Always fresh workspace (repo-local, ignored)
rm -rf "${WORK_DIR}"
mkdir -p "${WORK_DIR}/tests"
# Minimal ephemeral Playwright project (workspace-local)
cat > "${WORK_DIR}/package.json" <<EOF
{
"name": "playwright-recorder-ephemeral",
"private": true,
"type": "commonjs",
"devDependencies": {
"@playwright/test": "${PLAYWRIGHT_VERSION}"
}
}
EOF
cat > "${WORK_DIR}/playwright.config.ts" <<'EOF'
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
use: {
trace: 'on-first-retry',
},
});
EOF
# X11 access control for Docker (temporary)
xhost +local:docker >/dev/null
echo "Playwright image : ${PLAYWRIGHT_IMAGE}"
echo "Repo root : ${ROOT}"
echo "Recordings dir : ${REC_DIR}"
echo "Workspace dir : ${WORK_DIR}"
echo "Output file : ${OUTPUT_FILE}"
echo "DISPLAY : ${DISPLAY}"
if [[ -n "${START_URL}" ]]; then
echo "Start URL : ${START_URL}"
fi
echo
INSTALL_CMD="npm install --no-audit --no-fund"
CODEGEN_CMD="./node_modules/.bin/playwright codegen --target=${TARGET} --output=/recordings/${OUTPUT_FILE}"
if [[ -n "${START_URL}" ]]; then
CODEGEN_CMD="${CODEGEN_CMD} ${START_URL}"
fi
docker run --rm -it \
--ipc=host \
--network host \
-e "DISPLAY=${DISPLAY}" \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v "${WORK_DIR}:/work" \
-v "${REC_DIR}:/recordings" \
-w /work \
"${PLAYWRIGHT_IMAGE}" \
bash -lc "${INSTALL_CMD}; ${CODEGEN_CMD}"
echo
echo "✔ Codegen finished"
echo "✔ Generated file: ${RECORDINGS_DIR}/${OUTPUT_FILE}"