blob: 710061d28a9893a39f4216cdc30b76f1b4396440 [file] [log] [blame] [view]
giob7df27f2026-07-28 10:36:17 +04001# auth-ui native end-to-end tests
2
3This directory contains the opt-in, serial browser suite for `auth-ui`. It builds the current application, starts native Ory processes with in-memory SQLite databases, and drives the existing UI with Playwright-managed headless Chromium. Docker and PostgreSQL are not prerequisites.
4
5## Pinned runtime
6
7The harness accepts no `latest` or system-browser fallback:
8
9- Go **1.22 or newer** (the module directive is exactly `go 1.22`)
giof317b892026-07-28 17:53:51 +040010- Kratos **v26.2.0**, SQLite release archive
11- Hydra **v26.2.0**, SQLite release archive
giob7df27f2026-07-28 10:36:17 +040012- `github.com/mxschmitt/playwright-go` **v0.6100.0**
13- embedded Playwright CLI **1.61.1**
14- managed Chromium revision **1228**, Chromium **149.0.7827.55**
15- managed FFmpeg revision **1011**
16
17The Playwright binding, CLI, browser, and installer command are one matched version set. The suite never selects Chrome from `PATH`.
18
19### Ory archives and checksums
20
21Hashes are pinned in `artifacts.go` from the official Kratos and Hydra release `checksums.txt` files.
22
23| Platform | Kratos archive / SHA-256 | Hydra archive / SHA-256 |
24|---|---|---|
giof317b892026-07-28 17:53:51 +040025| linux/amd64 | `kratos_26.2.0-linux_sqlite_64bit.tar.gz` / `c80113f2c861b2fbd80290697d1380000111e297716018617423cca7f2e7e668` | `hydra_26.2.0-linux_sqlite_64bit.tar.gz` / `28baf98c6d5da617c905d5ca77826fe863db9f9edab8f72664c69a56bde56b5a` |
26| linux/arm64 | `kratos_26.2.0-linux_sqlite_arm64.tar.gz` / `fd2cedebc4034ad1aef726f64665052c809fb05f86968e9c8a36372d7578e865` | `hydra_26.2.0-linux_sqlite_arm64.tar.gz` / `18e73ac632d2081b76fbceb03130803a63bdb9b8e2ecc3f06f4a6e6820cabe26` |
27| darwin/amd64 | `kratos_26.2.0-macOS_sqlite_64bit.tar.gz` / `0ac76d0ad85fe452e711a2aafe56b49b0f5d1a57200f4464dcb48e7267c94062` | `hydra_26.2.0-macOS_sqlite_64bit.tar.gz` / `ede453fa15c82cfb23e61b138a0b4d9558127a26ebf51eead97d0c58a7eff422` |
28| darwin/arm64 | `kratos_26.2.0-macOS_sqlite_arm64.tar.gz` / `e198d84bde6e4b7c68714cdad00c8800edd88c2311adde8b08ea5469cea263ec` | `hydra_26.2.0-macOS_sqlite_arm64.tar.gz` / `d45f26be758196e66e98dff06a9eaefcd21d719123f74f43a0f1fabcfb71da60` |
29
30The Kratos fixture declares `version: v26.2.0`; executable identity is independently enforced by archive checksum and binary version verification. These in-memory SQLite tests validate auth-ui compatibility, not production database migrations or rollback.
giob7df27f2026-07-28 10:36:17 +040031
32These four Linux/macOS architecture combinations are the supported selection matrix. Windows and every other `GOOS/GOARCH` fail before downloads, builds, or service startup. Selection and compile checks do not constitute a native real-browser result. The complete native online/offline suite and automated artifact-format checks have been exercised on Linux amd64; Linux arm64 and both macOS rows remain pending and must not be described as empirically green.
33
34## Prerequisites and installation
35
36Required locally:
37
381. Go 1.22 or newer, with access to the normal Go module cache on first use.
392. GitHub network access for an uncached Ory archive.
403. Playwright-managed Chromium and FFmpeg.
414. On Linux, the host libraries required by Chromium.
42
43Install the exactly matched browser runtime:
44
45From the `auth-ui` checkout directory:
46
47```sh
48cd /path/to/repository/auth-ui
49make install-e2e-browser
50```
51
52On a Linux host that lacks Chromium system libraries, install the browser and Playwright-recommended OS packages (the package-manager step may require privileges):
53
54```sh
55make install-e2e-browser-deps
56```
57
58No installer runs during ordinary `go test ./...`, `go vet ./...`, `make test`, builds, or image publishing.
59
60## Commands
61
62Fast, untagged tests and vet (no Ory or browser process startup):
63
64```sh
65make test
66```
67
68Install/check the pinned browser, then run the complete tagged suite:
69
70```sh
71make test-e2e
72```
73
74Run from already populated caches without invoking the online browser installer target:
75
76```sh
77make test-e2e-offline
78```
79
80The suite is deliberately serial: it starts one Kratos process, one Hydra process, one fresh `auth-ui` binary, one Playwright driver, and one Chromium process, then creates an isolated browser context for each test. It does not call `t.Parallel`. Make keeps Go's hard `-timeout=10m` contract. The harness starts its **9-minute internal deadline before stack setup**, so the deadline covers archive preparation, application build, service/browser/UI setup, and test execution before timeout cleanup begins, even though Go starts its own alarm inside `m.Run`. The harness therefore begins timeout cleanup at least one minute before Go's alarm. The shorter `AUTH_UI_E2E_WATCHDOG_TIMEOUT` override is reserved for the harness's timeout subprocess regressions; ordinary runs should retain the documented 9-minute deadline. A warm-cache full run is now approximately 60–65 seconds on the implementation Linux amd64 host because the two nested real watchdog regressions deliberately consume most of that duration; first runs and other machines can be slower.
81
82For focused development:
83
84```sh
85go test -count=1 ./e2e
86go test -tags=e2e -count=1 -run '^TestHydra' -timeout=10m -v ./e2e
87```
88
89The first command runs helper unit tests only. The second requires the installed browser and Ory archives.
90
91## Downloads, caches, and offline behavior
92
93On a cache miss, the harness downloads the selected official Kratos and Hydra release archives from GitHub, enforces a size bound, verifies the pinned SHA-256, and publishes atomically. Every cache reuse recomputes the hash.
94
95The default Ory archive cache is repository-local:
96
97```text
98e2e/cache/ory/<service>/<version>/<archive>
99```
100
101Override its root when needed:
102
103```sh
104AUTH_UI_E2E_CACHE_DIR=/absolute/cache make test-e2e
105AUTH_UI_E2E_CACHE_DIR=/absolute/cache make test-e2e-offline
106```
107
108`AUTH_UI_E2E_OFFLINE=1` disables Ory downloads and reports the missing/invalid path and expected hash. `make test-e2e-offline` intentionally does not depend on `install-e2e-browser`; therefore the Go modules, Playwright driver, Chromium, FFmpeg, Ory archives, and Linux host libraries must already be available. A first-ever run needs network access for every missing Go-module, Ory, Playwright-driver, or browser cache entry.
109
110Playwright's default cache locations are:
111
112| Host | Playwright driver | Managed browsers/FFmpeg |
113|---|---|---|
114| Linux | `~/.cache/ms-playwright-go/1.61.1` | `~/.cache/ms-playwright` |
115| macOS | `~/Library/Caches/ms-playwright-go/1.61.1` | `~/Library/Caches/ms-playwright` |
116
117The Linux paths follow the normal user cache root (for example, `$XDG_CACHE_HOME` when configured). `PLAYWRIGHT_DRIVER_PATH` and `PLAYWRIGHT_BROWSERS_PATH` may point to pre-populated matching caches. Do not point them at a different Playwright release or a system browser. Go honors its standard `GOMODCACHE`/`GOCACHE` settings.
118
119## Workspaces and overrides
120
121Each invocation creates a temporary workspace using the operating system's temporary directory, named like:
122
123```text
124<os-temp>/auth-ui-e2e-*/
125 bin/{auth-ui,kratos,hydra}
126 config/{identity.schema.json,kratos.yml,hydra.yml}
127 logs/{auth-ui.log,kratos.log,hydra.log}
128```
129
130The workspace is removed after success. It is retained after setup/test failure, and `AUTH_UI_E2E_KEEP_TMP=1` retains it after success. The harness prints retained paths when relevant. All generated service and callback URLs use dynamically allocated `127.0.0.1` ports; no fixed client, identity, port, or external origin is required.
131
132## Retained artifacts and sensitivity
133
134Every tagged test retains one artifact set on success and failure under:
135
136```text
137e2e/artifacts/<run-id>/
138 run.json
139 services/{auth-ui,kratos,hydra}.log
140 <test-name>/
141 screenshots/*.png
142 video.webm
143 trace.zip
144 session.json
145```
146
147Use `AUTH_UI_E2E_ARTIFACT_DIR=/absolute/path` to change the run-artifact root. Screenshots, video, traces, DOM/network snapshots, and upstream logs can contain generated credentials, cookies, OAuth challenges, codes, or tokens. Treat the entire artifact tree as **sensitive local test data**; do not publish or attach it without review. Both the default cache and artifact directories are ignored by Git.
148
149After inspecting representative PNG, WebM, trace, and metadata files, remove only default retained runs with:
150
151```sh
152make clean-e2e-artifacts
153```
154
155That target deletes exactly `e2e/artifacts/`. It does not clear `e2e/cache`, Playwright caches, an `AUTH_UI_E2E_ARTIFACT_DIR` override, fixtures, or ordinary build output. No test or ordinary clean target deletes artifacts automatically.
156
157## Cleanup and troubleshooting
158
159The harness registers aggregate lifecycle ownership before setup and records partial stack and Playwright ownership as soon as each becomes available. Service creation and cleanup use one ownership lock across the cleanup-state check, OS process start, and slot publication, so cleanup either prevents a new spawn or observes it. After `m.Run`, normal cleanup must atomically stop and claim the watchdog before cleanup begins; if the timer already fired, timeout cleanup owns the terminal status and exit. Browser sessions use the same claim model: a normal finalization claimed before timeout finishes exactly once and is awaited, while a timeout-claimed session is finalized as failed with attempted failure/final screenshots, trace closure, context/video finalization, and failed metadata. Timeout cleanup then closes owned callback listeners, stops services and browser/driver, copies bounded redacted service logs, records `watchdog_timeout` in `run.json`, retains available workspace/artifact paths, and exits nonzero. Both timeout-triggered cleanup and normal post-`m.Run` cleanup give protocol cleanup 45 seconds. If that bound expires, the emergency path directly kills every recorded service group and every discoverable driver/browser descendant without relying on Playwright protocols. Emergency termination has a separate grace of at most 5 seconds, with an unconditional exit 125 guard armed before descendant enumeration so even a blocked external `ps` command cannot delay final exit indefinitely.
160
161This pre-timeout cleanup covers stalls while the Go test process and its cleanup goroutine can still run. It cannot guarantee cleanup after `SIGKILL`, host shutdown, kernel failure, or another abrupt OS-level termination that prevents the harness from executing. After such an interrupted run, inspect the printed workspace and service logs and verify no process whose command references that workspace remains before deleting it.
162
163Common failures:
164
165- **Unsupported E2E platform:** use Linux/macOS on amd64/arm64. Windows is intentionally unsupported.
166- **Offline cache missing or invalid:** run `make test-e2e` online once with the same `AUTH_UI_E2E_CACHE_DIR`, or place the exact official archive at the reported path; the hash must match.
167- **Playwright driver/browser missing or mismatched:** run `make install-e2e-browser` with the repository's Go environment. Do not substitute system Chrome.
168- **Chromium cannot launch on Linux:** run `make install-e2e-browser-deps` with appropriate package-manager privileges.
169- **GitHub or Go proxy unavailable:** retry when online or populate the Ory, Playwright, and Go caches in advance.
170- **Readiness timeout or early process exit:** inspect `services/*.log` and the retained workspace logs. Port bind conflicts are retried only for owned startup attempts.
171- **Trace inspection:** use the trace viewer from the same Playwright 1.61.1 toolchain; traces from this suite are sensitive.
172- **Artifact growth:** inspect what is needed, then run the explicit cleanup target. Caches remain reusable offline.
173
174## Intentional non-goals
175
176This suite does not cover or introduce CI, Docker/Compose, PostgreSQL, Windows, system browsers, Firefox/WebKit, parallel stacks, pixel baselines, accessibility audits, recovery, verification, settings UI, MFA, social login, registration-disabled mode, PKCE, refresh tokens, revocation, introspection, consent rejection, Hydra logout, device/client-credentials flows, or a public password-change API. It does not change product handlers, templates, selectors, styles, or static assets.