blob: 5e2a8ac92e41c8d58f29450e6b70ef57e01bde36 [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`)
10- Kratos **v1.1.0**, SQLite release archive
11- Hydra **v2.2.0**, SQLite release archive
12- `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|---|---|---|
25| linux/amd64 | `kratos_1.1.0-linux_sqlite_64bit.tar.gz` / `6fb3077252dde7578c3100d2cd4eb52364ca6b3c1b0b76987e6d586e29008cbd` | `hydra_2.2.0-linux_sqlite_64bit.tar.gz` / `0fe0539fa452496ac5d98b558f93eb2dbb4cf43733da0b09f8f2bdb4445fc31e` |
26| linux/arm64 | `kratos_1.1.0-linux_sqlite_arm64.tar.gz` / `fde8a1a1aebd153baff88b1232e0c2a34fdaaafe90b5364f4ea580151e74898e` | `hydra_2.2.0-linux_sqlite_arm64.tar.gz` / `c499ffdaae0f2ab85eff0567214734515b741a393bef89115c16018f4dc0560d` |
27| darwin/amd64 | `kratos_1.1.0-macOS_sqlite_64bit.tar.gz` / `ebdc94f27cb6e6a3087ed756accfb7837465ac8e30af9433b4414101814f7769` | `hydra_2.2.0-macOS_sqlite_64bit.tar.gz` / `3d40ca8e99e2a6d840130928d5e0245212dba0eea9c26a0d7186ebb4382e673d` |
28| darwin/arm64 | `kratos_1.1.0-macOS_sqlite_arm64.tar.gz` / `6681d7b15dd04686d10764750ce3ad69672b3962553223399a3a315ba5370517` | `hydra_2.2.0-macOS_sqlite_arm64.tar.gz` / `89732ad1494c57ea39348f62dc5ef5c48de129cd205b17cb12bb67ad27094bb7` |
29
30These 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.
31
32## Prerequisites and installation
33
34Required locally:
35
361. Go 1.22 or newer, with access to the normal Go module cache on first use.
372. GitHub network access for an uncached Ory archive.
383. Playwright-managed Chromium and FFmpeg.
394. On Linux, the host libraries required by Chromium.
40
41Install the exactly matched browser runtime:
42
43From the `auth-ui` checkout directory:
44
45```sh
46cd /path/to/repository/auth-ui
47make install-e2e-browser
48```
49
50On a Linux host that lacks Chromium system libraries, install the browser and Playwright-recommended OS packages (the package-manager step may require privileges):
51
52```sh
53make install-e2e-browser-deps
54```
55
56No installer runs during ordinary `go test ./...`, `go vet ./...`, `make test`, builds, or image publishing.
57
58## Commands
59
60Fast, untagged tests and vet (no Ory or browser process startup):
61
62```sh
63make test
64```
65
66Install/check the pinned browser, then run the complete tagged suite:
67
68```sh
69make test-e2e
70```
71
72Run from already populated caches without invoking the online browser installer target:
73
74```sh
75make test-e2e-offline
76```
77
78The 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.
79
80For focused development:
81
82```sh
83go test -count=1 ./e2e
84go test -tags=e2e -count=1 -run '^TestHydra' -timeout=10m -v ./e2e
85```
86
87The first command runs helper unit tests only. The second requires the installed browser and Ory archives.
88
89## Downloads, caches, and offline behavior
90
91On 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.
92
93The default Ory archive cache is repository-local:
94
95```text
96e2e/cache/ory/<service>/<version>/<archive>
97```
98
99Override its root when needed:
100
101```sh
102AUTH_UI_E2E_CACHE_DIR=/absolute/cache make test-e2e
103AUTH_UI_E2E_CACHE_DIR=/absolute/cache make test-e2e-offline
104```
105
106`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.
107
108Playwright's default cache locations are:
109
110| Host | Playwright driver | Managed browsers/FFmpeg |
111|---|---|---|
112| Linux | `~/.cache/ms-playwright-go/1.61.1` | `~/.cache/ms-playwright` |
113| macOS | `~/Library/Caches/ms-playwright-go/1.61.1` | `~/Library/Caches/ms-playwright` |
114
115The 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.
116
117## Workspaces and overrides
118
119Each invocation creates a temporary workspace using the operating system's temporary directory, named like:
120
121```text
122<os-temp>/auth-ui-e2e-*/
123 bin/{auth-ui,kratos,hydra}
124 config/{identity.schema.json,kratos.yml,hydra.yml}
125 logs/{auth-ui.log,kratos.log,hydra.log}
126```
127
128The 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.
129
130## Retained artifacts and sensitivity
131
132Every tagged test retains one artifact set on success and failure under:
133
134```text
135e2e/artifacts/<run-id>/
136 run.json
137 services/{auth-ui,kratos,hydra}.log
138 <test-name>/
139 screenshots/*.png
140 video.webm
141 trace.zip
142 session.json
143```
144
145Use `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.
146
147After inspecting representative PNG, WebM, trace, and metadata files, remove only default retained runs with:
148
149```sh
150make clean-e2e-artifacts
151```
152
153That 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.
154
155## Cleanup and troubleshooting
156
157The 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.
158
159This 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.
160
161Common failures:
162
163- **Unsupported E2E platform:** use Linux/macOS on amd64/arm64. Windows is intentionally unsupported.
164- **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.
165- **Playwright driver/browser missing or mismatched:** run `make install-e2e-browser` with the repository's Go environment. Do not substitute system Chrome.
166- **Chromium cannot launch on Linux:** run `make install-e2e-browser-deps` with appropriate package-manager privileges.
167- **GitHub or Go proxy unavailable:** retry when online or populate the Ory, Playwright, and Go caches in advance.
168- **Readiness timeout or early process exit:** inspect `services/*.log` and the retained workspace logs. Port bind conflicts are retried only for owned startup attempts.
169- **Trace inspection:** use the trace viewer from the same Playwright 1.61.1 toolchain; traces from this suite are sensitive.
170- **Artifact growth:** inspect what is needed, then run the explicit cleanup target. Caches remain reusable offline.
171
172## Intentional non-goals
173
174This 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.