The shared `container pull` of the Playwright image had no timeout. A
wedged registry-proxy tunnel kept a local deploy on that task for 18
minutes with no traffic until the pull was killed by hand; the task's
`retries: 3` never got a chance because the first attempt never
returned.
Run the pull under `timeout -k 60 <lookup('timeout', 1800)>`, the same
shape the compose build handlers use. A stuck pull now exits with 124
and the existing retry loop starts a fresh connection.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Test: E2E Playwright Runner
Description
This Ansible role provides a generic, reusable Playwright end-to-end (E2E) test runner for the Infinito.Nexus ecosystem.
It automatically discovers roles that ship a Playwright test project under:
roles/<application_id>/templates/playwright.env.j2roles/<application_id>/files/playwright/playwright.spec.js
A role is considered Playwright-enabled if it provides:
roles/<application_id>/templates/playwright.env.j2
The role then stages the Playwright project to a local staging directory, renders a .env
file from templates/playwright.env.j2, optionally waits until the application is reachable, and executes
Playwright inside a Docker image derived from the central Playwright package version.
Overview
This role:
- Discovers Playwright-enabled roles by scanning
roles/*/templates/playwright.env.j2 - Supports allow-/deny-lists via
test_e2e_playwright_only_rolesandtest_e2e_playwright_skip_roles - Stages each Playwright project into
TEST_E2E_PLAYWRIGHT_STAGE_BASE_DIR/<application_id> - Renders the central
package.jsontemplate into each staged project and injects the centralplaywright.config.js - Copies every role-specific
files/playwright/*.js(theplaywright.spec.jsaggregator plus itstest-*.jsscenario modules) into the stagedtests/directory, and stagesfiles/playwright/fixtures/(binary assets such as sample images/videos) alongside them - Renders
.envfromtemplates/playwright.env.j2using Ansible variables (application_id,domains,users,applications) - Optionally waits until the application responds with HTTP
200or302 - Injects CA trust automatically for
TLS_MODE=self_signed(viaCA_TRUST.*), so Playwright accepts self-signed cert chains - Runs Playwright in Docker with stable browser settings (
--ipc=host,--shm-size=1g) - Stores per-role reports/artifacts under
TEST_E2E_PLAYWRIGHT_REPORTS_BASE_DIR/<application_id>
Cosmos
The diagram places Test: E2E Playwright Runner in the Infinito.Nexus cosmos: the components it deploys (capabilities), the central services it consumes (dependencies), and its outward reach (federation and bridged external networks).
flowchart LR
subgraph role [test-e2e-playwright 💻]
svc_test_e2e_playwright["test-e2e-playwright"]
svc_playwright["playwright"]
end
Solid 1:1 edges are fixed relationships; dashed 0..1 edges are conditional (enabled only in matching deployments); red 0..0 edges are turned off in this role. Node markers show the role's deploy modes (💻 host, 🐳 compose, 🐝 swarm); ❌ marks a service that is explicitly turned off, and ⚙️ an Ansible role dependency declared in meta/main.yml.
Features
- Automated provisioning: Configured by Ansible without manual steps.
Purpose
The purpose of this role is to provide a central E2E test primitive that can be executed at the end of a deployment (for example, as a post task), without hardcoding tests in the runner itself.
Each application role stays responsible for its own Playwright tests and configuration. This role only provides the execution framework.
Role contract (what application roles must provide)
A Playwright-enabled role must provide:
roles/<application_id>/
templates/playwright.env.j2
files/playwright/playwright.spec.js
For the file-level contract, use Contributing playwright.env.j2 and Contributing playwright.spec.js.
package.json and playwright.config.js are provided centrally by this role:
roles/test-e2e-playwright/templates/package.json.j2(rendered per-deploy; pins@playwright/testfrommeta/services.yml.playwright.version)roles/test-e2e-playwright/files/playwright.config.js(copied as-is)
Included files
This role ships central Playwright defaults:
templates/package.json.j2:@playwright/testversion derived frommeta/services.yml.playwright.versionfiles/playwright.config.js: shared Playwright configuration
Both are used as central defaults for every app role.
Variables
Staging & reports
TEST_E2E_PLAYWRIGHT_STAGE_BASE_DIR(default:/tmp/test-e2e-playwright)TEST_E2E_PLAYWRIGHT_REPORTS_BASE_DIR(default:/var/lib/infinito/logs/test-e2e-playwright)
Playwright runtime
TEST_E2E_PLAYWRIGHT_IMAGE(resolved invars/main.ymlfrommeta/services.yml.playwright.image+.versionvialookup('config', 'test-e2e-playwright', 'services.playwright.image|version'))TEST_E2E_PLAYWRIGHT_IMAGE_DISTRO(default:noble)TEST_E2E_PLAYWRIGHT_COMMAND(default:npm install --no-fund --no-audit && npx playwright test)
Discovery filters
test_e2e_playwright_only_roles(default:lookup('deployment').running, every role the round deploys, dependencies included)test_e2e_playwright_skip_roles(default:[])
Design notes
- The runner is intentionally test-agnostic at runtime: it executes only tests provided by application roles.
playwright.versioninmeta/services.ymlis the single source of truth for the default Playwright version; the centraltemplates/package.json.j2pins it via theimage_versionfilter.templates/playwright.env.j2acts as the stable marker for discovery and as the source of environment configuration.- Playwright is executed in Docker for reproducibility and consistent browser dependencies.
- In
TLS_MODE=self_signed, the role requiresCA_TRUST.cert_host,CA_TRUST.wrapper_host, andCA_TRUST.trust_nameand fails early if cert/wrapper files are missing.
How to use
- Add the two app-specific files:
roles/<application_id>/templates/playwright.env.j2roles/<application_id>/files/playwright/playwright.spec.jsFollow Contributingplaywright.env.j2and Contributingplaywright.spec.jswhile creating them.
- Deploy a round that includes your app (e.g.
make compose-deploy apps=<application_id>); its specs run with those of every other role the round deploys. - Keep
package.jsonandplaywright.config.jscentralized inroles/test-e2e-playwright/(templates/package.json.j2andfiles/playwright.config.js).
Example override for running only one spec:
-e TEST_E2E_PLAYWRIGHT_COMMAND='npm install --no-fund --no-audit && npx playwright test tests/login.spec.js'
Recording
For interactive Playwright recording, use the external repository:
This role no longer ships its own local recording wrapper.
Credits
Implemented by Kevin Veen-Birkenbach. Part of the Infinito.Nexus Project and maintained by Kevin Veen-Birkenbach. Licensed under the Infinito.Nexus Community License (Non-Commercial).