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.j2Supports allow-/deny-lists via
test_e2e_playwright_only_rolesandtest_e2e_playwright_skip_rolesStages 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.jsCopies 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 themRenders
.envfromtemplates/playwright.env.j2using Ansible variables (application_id,domains,users,applications)Optionally waits until the application responds with HTTP
200or302Injects CA trust automatically for
TLS_MODE=self_signed(viaCA_TRUST.*), so Playwright accepts self-signed cert chainsRuns 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).