Wire nine database-backed web-app roles to the shared SeaweedFS object store
via the engine-agnostic objstore lookup, following the existing consumer recipe
(declare the seaweedfs service, render the app S3 config from
lookup('objstore', application_id, ...), add the e2e test). Each app's S3
config keys were verified against the upstream docs/source, and all honor
SeaweedFS path-style addressing + the internal http endpoint:
- fider: BLOB_STORAGE=s3 + BLOB_STORAGE_S3_*
- snipe-it: split s3_private/s3_public disks, single bucket via BUCKET_ROOT, *_AWS_PATH_STYLE
- mobilizon: Uploader.S3 + ExAws (private)
- decidim: ActiveStorage amazon service, force_path_style
- taiga: django-storages, AWS_S3_ADDRESSING_STYLE=path
- shopware: Flysystem amazon-s3 adapter, use_path_style_endpoint
- magento: remote_storage driver aws-s3 + endpoint
- matrix: s3_storage_provider module baked into the image + media_storage_providers
- gitlab: consolidated object storage, single bucket split into per-type virtual buckets, path_style
Both object-store guards (test_database_requires_seaweedfs,
test_seaweedfs_consumer_playwright) pass; autoformat clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The bespoke `taiga login and logout` test always failed with a 60s
Keycloak-username-field timeout because `page.goto(baseUrl + "/")`
auto-redirects to `/discover` (a public showcase that exposes a top-
of-page `Login` link but NOT the SSO button). The detector matched the
discover-page `Login` link, classified the page as `taiga-login-page`,
clicked it, then immediately waited for the Keycloak username field —
never re-detecting the OIDC entry on `/login`. Trace from the live
stack confirmed: no request to `/oidc/authenticate/` was ever made.
Two-part fix in the OIDC login flow:
- `page.goto(baseUrl + "/login")` directly so the SSO button is on
the first navigated view and the Angular `tg-oidc-login-button`
directive has bound its click handler by the time we click.
- In the `taiga-login-page` branch, re-detect via
`waitForTopLevelLoginRequirement` after the Login-link click so the
SSO entry can be clicked before we expect the Keycloak URL.
Verified empirically against the live taiga stack via `make run` —
the test now passes in 4s and the trace shows the full Keycloak
round-trip (POST `/login-actions/authenticate?session_code=...` →
302 `/oidc/callback/?code=...` → 200 `/login?id=…&username=…`).
Also splits the spec into one file per test scenario, mirroring the
pixelfed layout (a66fb1d48):
- `playwright.spec.js` orchestrator: `test.use` + `beforeEach` +
`require()`
- `_shared.js` env, locator helpers, OIDC + native login/
logout flows, `beforeEach`
- `test-login-oidc.js` OIDC/oauth2 round-trip; skipped when both
services are off
- `test-login-native.js` NEW — drives Taiga's stock `/login` form
(LDAP federation when `loginFormType=ldap`,
local DB otherwise) against the same
`loginUsername` + `loginPassword` env;
skipped when either OIDC or oauth2 is on
(the OIDC test owns that journey)
- `test-public-discover.js`
- `test-themed-routes.js`
- `test-guest-persona.js`
- `test-biber-persona.js`
- `test-administrator-persona.js`
Gating logic on the two login tests is complementary: variant 0
(OIDC on) runs the OIDC test and skips the native one; variant 1
(everything off) does the inverse. Together they cover both auth
flavours without duplication.
The deploy's existing `with_fileglob: "*.js"` copies every companion
module into `tests/`; Playwright's testMatch only discovers
`playwright.spec.js`, so the `test-*.js` modules are pure `require()`
targets, not auto-discovered specs. The persona-naming and
service-env-gate lints already glob the role's playwright dir (set up
in a66fb1d48), so the split layout passes both without further
changes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Matcher in web-app-prometheus's parametrized scrape test now also
reads `labels.app`. Native scrape jobs (set `app="web-app-<id>"` via
each role's `templates/prometheus.yml.j2` fragment) now match alongside
blackbox-healthz targets. A single iteration asserts up=1 for both
surfaces per consumer, so per-app native tests become redundant.
- Scenario I (`/metricz`) iterates `prometheusTargetRoles` and asserts
each consumer's `app="<role_id>"` label is present in the
lua-resty-prometheus output. Subsumes the per-app metricz-label spot
checks.
- Remove four redundant per-app prometheus tests from web-app-gitea and
web-app-mattermost playwright specs (metricz-label + native-scrape
up=1), drop the orphaned `PROMETHEUS_BASE_URL=` declarations from
their env.j2 files, and clean up `OIDC_ISSUER_URL=` in gitea's env.j2
(only used by the removed scenarios).
- Drop the dead `const prometheusBaseUrl` declarations plus their
eslint-disable shut-up comments from web-app-fider, web-app-odoo, and
web-app-taiga playwright specs, along with the matching
`PROMETHEUS_BASE_URL=` blocks in those roles' env.j2.
- Correct the persona-required-envs lint: only `MATOMO_BASE_URL` is
actually consumed (by `personas/utils/csp.js`). `DASHBOARD_BASE_URL`
and `PROMETHEUS_BASE_URL` were aspirationally required by a lint
whose docstring described persona-collapse behaviour that no persona
implements. Update `_REQUIRED_URLS` and the docstring, and drop the
unused `\!dashboardBaseUrl` token from `_ALLOWED_SKIP_GUARDS` in
test_strict_mode.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removes direct process.env.<X>_SERVICE_ENABLED reads (and bespoke
per-role <ROLE>_OIDC_ENABLED / SERVICE_* / OIDC_ENABLED env flags) in
favor of skipUnlessServiceEnabled/isServiceEnabled from
roles/test-e2e-playwright/files/service-gating.js, per
docs/contributing/artefact/files/role/playwright.specs.js.md service-
gating contract.
Per-role changes:
- discourse, matrix, dashboard: replace process.env.<X>_SERVICE_ENABLED
with the helper; drop now-redundant nocheck markers on the canonical
env flags.
- taiga: drop TAIGA_OAUTH2_ENABLED / TAIGA_OIDC_ENABLED env lines;
consume OAUTH2_SERVICE_ENABLED / OIDC_SERVICE_ENABLED via the helper.
- opentalk, opencloud, nextcloud: drop <ROLE>_OIDC_ENABLED (and
NEXTCLOUD_LDAP_ENABLED) env lines; spec switches to
isServiceEnabled('oidc'|'ldap').
- moodle: drop SERVICE_OIDC / SERVICE_LDAP / SERVICE_LAM in favor of
the canonical OIDC_SERVICE_ENABLED / LDAP_SERVICE_ENABLED plus a new
LAM_SERVICE_ENABLED rendered from 'web-app-lam' group membership.
- decidim: drop OIDC_ENABLED env line; SSO-button-visible scenario
uses skipUnlessServiceEnabled('oidc').
Dashboard asset test split:
The previously bundled "dashboard loads core css, javascript,
simpleicons, and logo assets" test triple-gated (css/cdn/logout)
skipped the entire surface when any single shared service was off.
Split into six focused tests so disabling one service skips only its
specific assertion:
- shared CSS injection (gate: css)
- CDN-served role-local stylesheet (gate: cdn)
- logout.js injection (gate: logout)
- simpleicon-backed cards (gate: simpleicons; nocheck dropped)
- role-core JS modules + logos (ungated, role-core)
- iframe-sync postMessage handler (ungated, role-core)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>