test(news): gate deployment on an isolated real browser publication journey
CI / check (push) Successful in 3m28s
CI / deploy (push) Successful in 18s
CI / publish-container (push) Successful in 2m47s

This commit is contained in:
Simo committed 2026-09-13 20:27:04 +02:00
1 parent 60e49c1ec9
commit 7867bf6b72
11 files changed
+980 -2

No files matched your search

+37
View File
@@ -0,0 +1,37 @@
# Real news browser gate
Run `pnpm test:news:real` with `NEWS_E2E_IMAGE=epicnext-cms:<candidate-tag>`. Docker CLI, a working Docker daemon, the OpenSSL CLI with `-addext` support, installed project dependencies and Playwright Chromium are required. The runner deliberately fails when the image or Docker is unavailable. It never silently skips the browser journey.
`NEWS_E2E_RELEASE=<full-commit-sha>` additionally verifies the image revision label. The runner resolves the local image to its immutable ID before starting it. It does not build or pull the application image. MariaDB 11.4.5 and Redis 7.4.2 Alpine are disposable Testcontainers dependencies and may be pulled when absent.
The deployment script runs this gate after building the candidate and extracting its performance report, before live database migrations and container cutover. The general Playwright suite excludes `e2e/news-real`; this suite has its own configuration and requires the runner.
## What the browser proves
One Chromium journey exercises the candidate's normal Docker entrypoint and standalone Next server:
1. An anonymous request to the staff editor reaches the login page.
2. The browser signs in through the actual login form, credential precheck and Auth.js handler. The test verifies the real Secure/HttpOnly session cookie and database login record.
3. A rank 7 editor, below an occupied rank 9 owner, accesses news through three explicit ACL grants: `admin.dashboard`, `admin.news.view` and `admin.news.edit`.
4. The browser types Unicode content into the bundled TinyMCE editor and saves a draft through the real server action. The persisted HTML must equal what the form submitted.
5. An independent anonymous browser sees the not-found screen; the public articles API returns an empty list. Redis contains the cached null article. Next can stream a not-found screen with HTTP 200, so this check verifies the rendered 404 screen as well as absence from the API.
6. The editor reopens and previews the saved draft in the real preview iframe. Its title, summary and rendered body match; it remains a draft with no article revision created by previewing.
7. Publishing through the editor produces one article, a publication timestamp, one previous-draft revision, a before/after audit entry, two completed operation results and two news-refresh outbox entries.
8. The anonymous page and API immediately show the article, using a new shared Redis cache revision. The browser remains signed out.
No authentication, application HTTP responses, mutations, database calls or cache calls are mocked. The browser blocks resources outside the local fixture origin, such as external avatars. This does not replace any application response. A local HTTPS edge passes requests to Next and sets trusted forwarding headers, allowing the production Secure-cookie behavior to run normally.
## Isolation and cleanup
- Each run creates a random Docker network and fresh MariaDB, Redis and candidate containers. All mapped ports are allocated dynamically. The HTTPS listener binds only to `127.0.0.1`.
- No production container, database, volume or credentials are reused. Container configuration is explicit. Child processes receive a small environment whitelist; checkout `.env` and installation service credentials are not forwarded.
- The database uses the current ORM column definitions for 29 tables needed by login, site/admin layouts and news. Unique constraints and composite primary keys are preserved. The emulator-owned `permission_ranks` fixture provides the rank authority columns this flow queries. Real CMS migrations 0026 and 0031 create the recovery/revision and operation/outbox tables. This is a focused fixture, not a replacement for the emulator's complete schema or migration coverage.
- Passwords, Redis credentials and the Auth.js secret are generated per run. The owner has an unknown random password and is never used to bypass ACL checks. Email verification is enabled with a verified fixture staff account. CAPTCHA and forced staff 2FA use their ordinary disabled installation settings; their challenges are outside this flow.
- OpenSSL generates a fresh localhost certificate and private key in the OS temporary directory for each run. The certificate lasts one day and covers `127.0.0.1` and `localhost`. Playwright trusts this self-signed endpoint only in this suite. No certificate or key is committed or copied into build artifacts; cleanup removes both with the temporary credentials.
- Credentials used by the test worker are stored in an OS temporary directory with a mode-0600 file, then removed. Cleanup stops only containers and the network created by this runner; Testcontainers also registers them with its resource reaper.
- Failure artifacts are under `test-results/news-real` and `playwright-report/news-real`. Server logs redact generated passwords/secrets. Playwright traces can contain the short-lived fixture login/session data; all associated services are destroyed after the run.
This browser gate checks the synchronous editor/publication path and durable delivery intent. Scheduler concurrency, rollback, duplicate requests, worker delivery and Redis outage/recovery remain covered by `pnpm test:integration`. It does not claim to test emulator connectivity, external notifications, CAPTCHA/2FA challenges or production data.
The local workstation currently has no working Docker daemon. Type checks, lint and fixture/bootstrap checks can run there; a passing real browser result must come from the Docker-capable CI gate.