The bespoke `pixelfed oidc login (biber)` test always timed out at the 1200s Ansible-task wrapper because pixelfed's first-time OIDC user- creation runs Laravel's `email:strict,filter_unicode,dns,spoof` validator. Egulias `DNSCheckValidation` hard-rejects any TLD in its RESERVED_DNS_TOP_LEVEL_NAMES list (`test`, `example`, `invalid`, …) BEFORE any DNS lookup, so `biber@infinito.example` always fails and Laravel auto-redirects `back()` to the Keycloak Referer — breaking the SSO callback chain and never returning to pixelfed. The fix mutates biber's Keycloak profile to `biber@infinito.nexus` for the duration of this spec (real TLD, real MX) and restores the original afterwards via the Keycloak admin API. Verified empirically against the live stack: `pixelfed oidc login (biber)` was 1200s timeout, is now 20s pass; the `afterAll` restorer puts `biber@infinito.example` + `emailVerified=true` back cleanly. Also splits the spec into one file per test so each scenario stays atomar and individually inspectable: - `playwright.spec.js` orchestrator: `test.use` + lifecycle + `require()` - `_shared.js` env, locator candidates, login/logout flow, keycloak admin helpers, `beforeAll`/`afterAll` - `test-oidc-login-biber.js` - `test-oidc-login-administrator.js` - `test-native-login-administrator.js` new — exercises pixelfed's stock email+password `/login` form (no infinito-specific selectors), gated to run only when OIDC is disabled - `test-guest-persona.js` - `test-biber-persona.js` - `test-administrator-persona.js` The deploy's existing `with_fileglob: "*.js"` copies the companions into `tests/`; Playwright's testMatch only discovers `playwright.spec.js` so the `test-*.js` modules are pure `require()` targets, not auto- discovered specs. Updates two lints to scan the whole `files/playwright/` directory so both monolithic and split layouts pass: - `tests/lint/ansible/roles/web-app/playwright/persona/test_naming.py` aggregates persona titles across all sibling `.js` files. - `tests/integration/roles/playwright/test_spec_env_gates.py` globs `*.js` for service-gate helper calls instead of reading only the main spec. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Role Structure Tests 📚
Integration tests that enforce structural invariants of every role under roles/: folder-name conventions and include_tasks / import_tasks target existence.
Tests in this directory MUST only cover role-level structural rules (folder naming, role-name regex). meta/main.yml presence and field checks MUST live under meta/. Dependency-graph checks (self-, circular, unnecessary dependencies, run_after) MUST live under meta/dependencies/ (and the sibling meta/services/run_after/). Application-specific role rules (web-app README, applications[...] / group_names usage, application_id identity) MUST live under applications/. run_once_<role> flag lifecycle checks MUST live under run_once/. Block-level when: hygiene (guard blocks, duplication, size) MUST live under when/. include_tasks / import_tasks / include_role / import_role target existence MUST live under includes/. Compose- or handler-specific checks MUST live in their respective topical clusters.
For framework, directory layout, and make test-integration usage see integration.md.