New lint test_no_raw_goto.py forbids raw `page.goto(...)` in role playwright specs + persona flows (the gotoOnion wrapper in personas/utils is exempt) so navigation retries transient Tor-transport errors over onion. Migrates every raw call across ~75 roles (343 sites) to `gotoOnion(page, ...)` and teaches gotoOnion to detect relative onion URLs (`isOnionCanonical`). gotoOnion is a behaviour-identical drop-in on clearnet (single attempt, same return). Verified: no-raw-goto lint green, eslint 0 errors, make test green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The monolithic spec mixed a CSP baseline, an OIDC round-trip, an RBAC-by-group loop, a Multisite placeholder, a WP→Discourse round-trip, and three persona shims behind ~500 lines of shared Keycloak / WordPress / Discourse helpers. Splits the surface into per-test modules around a `_shared.js` that owns the env asserts, the helper library, and the `beforeEach` setup; the orchestrator is now a 15-line `playwright.spec.js`.
Carries the `test.skip(\!discourseApiKey, …)` gate from the previous commit so a `mode=update apps=<other>` run skips the WP→Discourse test with a self-describing reason instead of racing into a teardown failure.
`lint-playwright` confirms Playwright discovers all 10 tests across 8 files; ESLint clean (only the pre-existing playwright/expect-expect warnings on persona shims, identical to other roles).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>