Guidance for coding agents working in this repository.
This is the Try Playwright monorepo. It contains:
- Go microservices (
control-service,file-service) - Go worker launchers for multiple language runtimes (
worker-*) - Shared Go packages under
internal/ - React + Vite frontend (
frontend/) - Playwright end-to-end tests (
e2e/) - Kubernetes manifests and generation scripts (
k8/)
- Go
1.26.x(seego.mod) - Node.js
20+and npm - Docker for image builds
kubectl+ k3s for full integration/e2e flows
control-service/: control API servicefile-service/: file upload/validation serviceinternal/: shared Go code (echoutils, worker helpers, and types)worker-javascript/,worker-java/,worker-python/,worker-csharp/: language-specific worker containersfrontend/: React app and Playwright component testse2e/: browser/API Playwright tests against a running stackk8/: deployment templates/generated manifestsupdate_pw.mjs: Playwright update/autocomplete helper
- Keep changes focused to the requested scope.
- Reuse existing patterns in the touched service/package.
- Avoid committing secrets, certificates, or local environment files.
- Prefer
internal/for shared Go logic used by multiple services/workers. - For Playwright version/autocomplete updates, use
node update_pw.mjsinstead of ad-hoc manual edits.
Run only the checks that match the area you changed.
go test ./...
go build ./...npm ci
npm run build
npx playwright testnpm ci
npm testNotes:
- E2E tests require a reachable deployed stack (default base URL is
http://localhost:8080). - CI commonly sets
ROOT_TEST_URLwhen running e2e tests against k3s.
These notes apply when working in a Cursor Cloud Agent VM.
- The Cloud Agent environment is defined in
.cursor/environment.json. Itsinstallstep prepares Go modules, frontend/e2e npm deps, the Playwright Chromium browser, andgettext-base(forenvsubst). Thefrontend-devterminal serves the Vite dev server on port5173. - The frontend dev server proxies
/service/to production, which is protected by Turnstile, so it cannot execute snippets on its own. To exercise the backend end-to-end, run the full stack on k3s (below).
Not every task needs the full stack, so k3s is not started automatically. When you need to run/test the backend (control-service, file-service, workers, RabbitMQ, RustFS, etcd, frontend) end-to-end, bring it up with:
bash k8/dev-k3s-up.shThe script is idempotent and encodes the settings required to run k3s inside the sandboxed, nested-container VM (which has no systemd):
- Run
k3s serverdirectly (no systemd service). --snapshotter=fuse-overlayfs: nestedoverlayfsis unsupported, and thenativesnapshotter makes the image count against the worker pod's 512Mi ephemeral-storage limit (causing eviction).--flannel-backend=host-gw: VXLAN device creation is blocked in the sandbox.--disable-network-policy:ipsetis blocked in the sandbox.- Images are pulled prebuilt from
ghcr.io/mxschmitt/try-playwright/*(no local build needed). k8/generate.shis run withCI=1, leavingTURNSTILE_SECRET_KEYempty socontrol-serviceskips Turnstile validation (seecontrol-service/turnstile.go) and snippets run without a captcha token.- Defaults to
WORKER_LANGUAGES=javascriptandWORKER_COUNT=1to keep image pulls and resource usage small; override via env vars.
Verify end-to-end after kubectl port-forward svc/frontend 8080:8080:
curl -s -X POST http://localhost:8080/service/control/run \
-H 'Content-Type: application/json' \
-d '{"language":"javascript","token":"","code":"const { chromium } = require(\"playwright\");(async () => { const b = await chromium.launch(); const p = await b.newPage(); await p.setContent(\"<h1>hi</h1>\"); await p.screenshot({ path: \"out.png\" }); console.log(await p.title()); await b.close(); })();"}'A successful response has "success": true, a Playwright version, console output, and a screenshot artifact under files[].publicURL (served via the frontend /file-uploads/ proxy).
- Ensure modified Go files are
gofmtformatted. - Update docs/config when behavior changes.
- In change summaries, list the commands/tests you actually ran.