Cognito-backed UI login bypass for Playwright integration tests.
The standard SPA login flow takes ~5–10s per test (form fill + Cognito round-trip + token exchange + JS app reinit). For a 10-test suite that's over a minute of pure overhead.
This namespace replaces it with:
AdminInitiateAuth from the JVM (1 HTTPS round-trip).localStorage.auth on the Playwright page with the resulting
token bundle, in the exact shape the SPA writes after a successful
login (see edd-core-web login widget core.cljs:181-187).localStorage.auth and dispatches ::login-succeeded if a non-empty
:id-token is found, so the SPA is fully authenticated by the time
the first page renders — no login form ever appears.This is a pure bypass: tokens are real Cognito tokens, every backend call uses normal JWT auth. Only the UI form is skipped.
Requires:
ADMIN_NO_SRP_AUTH enabled on the user-pool client (samurai's is).Cognito-backed UI login bypass for Playwright integration tests.
The standard SPA login flow takes ~5–10s per test (form fill + Cognito
round-trip + token exchange + JS app reinit). For a 10-test suite that's
over a minute of pure overhead.
This namespace replaces it with:
1. Call Cognito `AdminInitiateAuth` from the JVM (1 HTTPS round-trip).
2. Seed `localStorage.auth` on the Playwright page with the resulting
token bundle, in the exact shape the SPA writes after a successful
login (see edd-core-web login widget core.cljs:181-187).
3. Navigate to the SPA. The login widget's startup code reads
`localStorage.auth` and dispatches `::login-succeeded` if a non-empty
`:id-token` is found, so the SPA is fully authenticated by the time
the first page renders — no login form ever appears.
This is a pure bypass: tokens are real Cognito tokens, every backend
call uses normal JWT auth. Only the UI form is skipped.
Requires:
- The SPA must be using a version of edd-core-web's login widget that
restores from localStorage on init (web/widgets/login/core.cljs/init
calling restore-stored-auth!).
- AWS credentials available to the JVM (env vars / SSO / instance profile).
- The IAM principal must have cognito-idp:AdminInitiateAuth on the pool.
- `ADMIN_NO_SRP_AUTH` enabled on the user-pool client (samurai's is).Playwright-native testing library for Clojure.
Provides:
with-ui — main test macro; manages browser + tracing lifecycle.
Produces a trace.zip per test, viewable in Playwright
Trace Viewer (npx playwright show-trace / trace.playwright.dev).
Binds *current-page* dynamic var for the duration of the test.
(with-pw is a deprecated alias for with-ui.)with-api — macro that provides an APIRequestContext bound to client.
If *current-page* is already bound (i.e. inside with-pw),
derives the client from the existing traced BrowserContext so
HTTP calls appear in the trace. Otherwise starts a lightweight
headless browser+context with tracing and tears it down after body.step — annotate a logical step in the trace (group of actions).
Reads page from *current-page*; no explicit context needed.pw-screenshot — manually attach a labelled screenshot to the trace.
Reads page from *current-page*; no explicit page arg needed.testing.pw-report namespace can aggregate all zips into
a static HTML dashboard.(ns my.tests (:require [clojure.test :refer [deftest is]] [testing.pw :refer [pw-screenshot step with-ui with-api]]))
(deftest homepage-test (with-ui [page] (step "Navigate to example.com" (fn [] (.navigate page "https://example.com") (is (clojure.string/includes? (.title page) "Example"))))
(step "Verify heading"
(fn []
(let [h1 (.locator page "h1")]
(is (= "Example Domain" (.textContent h1))))))))
Playwright-native testing library for Clojure.
Provides:
- `with-ui` — main test macro; manages browser + tracing lifecycle.
Produces a trace.zip per test, viewable in Playwright
Trace Viewer (npx playwright show-trace / trace.playwright.dev).
Binds `*current-page*` dynamic var for the duration of the test.
(`with-pw` is a deprecated alias for `with-ui`.)
- `with-api` — macro that provides an APIRequestContext bound to `client`.
If `*current-page*` is already bound (i.e. inside `with-pw`),
derives the client from the existing traced BrowserContext so
HTTP calls appear in the trace. Otherwise starts a lightweight
headless browser+context with tracing and tears it down after body.
- `step` — annotate a logical step in the trace (group of actions).
Reads page from `*current-page*`; no explicit context needed.
- `pw-screenshot` — manually attach a labelled screenshot to the trace.
Reads page from `*current-page*`; no explicit page arg needed.
Design goals
============
* Zero JUnit dependency — pure Playwright Java API on the JVM.
* Every test automatically produces target/pw-traces/<test-name>-<ts>.zip
* Traces are enriched with custom step annotations via
BrowserContext.tracing().group() / groupEnd(), which appear as named
groups in the Trace Viewer action list.
* A separate `testing.pw-report` namespace can aggregate all zips into
a static HTML dashboard.
Usage
=====
(ns my.tests
(:require [clojure.test :refer [deftest is]]
[testing.pw :refer [pw-screenshot step with-ui with-api]]))
(deftest homepage-test
(with-ui [page]
(step "Navigate to example.com"
(fn []
(.navigate page "https://example.com")
(is (clojure.string/includes? (.title page) "Example"))))
(step "Verify heading"
(fn []
(let [h1 (.locator page "h1")]
(is (= "Example Domain" (.textContent h1))))))))
Aggregate report generator: copies Playwright Trace Viewer assets and builds the HTML report from existing trace zips.
Usage: clojure -M:aggregate
Run tests first with: clojure -M:test
Aggregate report generator: copies Playwright Trace Viewer assets and builds the HTML report from existing trace zips. Usage: clojure -M:aggregate Run tests first with: clojure -M:test
Locates and copies Playwright Trace Viewer static assets.
Shared between testing.pw-report and testing.pw-aggregate so that both can embed the offline viewer without a circular dependency.
Locates and copies Playwright Trace Viewer static assets. Shared between testing.pw-report and testing.pw-aggregate so that both can embed the offline viewer without a circular dependency.
Pure-Java HTTP server that serves the pw-report output directory (target/pw-traces by default) so the embedded offline Trace Viewer works correctly in a browser.
The server is built entirely on com.sun.net.httpserver.HttpServer,
which ships with every JDK — no extra dependencies required.
Usage: clojure -M:traces
JVM properties (all optional): -Dpw.server.port=<n> HTTP port (default: 8080) -Dpw.server.dir=<path> Directory to serve (default: target/pw-traces)
Once started, open http://localhost:<port> in your browser. Press Ctrl-C to stop.
Pure-Java HTTP server that serves the pw-report output directory (target/pw-traces by default) so the embedded offline Trace Viewer works correctly in a browser. The server is built entirely on `com.sun.net.httpserver.HttpServer`, which ships with every JDK — no extra dependencies required. Usage: clojure -M:traces JVM properties (all optional): -Dpw.server.port=<n> HTTP port (default: 8080) -Dpw.server.dir=<path> Directory to serve (default: target/pw-traces) Once started, open http://localhost:<port> in your browser. Press Ctrl-C to stop.
Playwright trace aggregation and HTML dashboard generator.
Scans a directory tree for *.zip trace files produced by testing.pw/with-pw
and emits a self-contained index.html dashboard that:
Usage from the REPL or as a -main entry point:
(require '[testing.pw-report :as rep]) (rep/generate-report) ; default: scans target/pw-traces (rep/generate-report {:traces-dir "target/pw-traces" :output-dir "target/pw-traces" :project "My Project"})
CLI alias (see deps.edn :pw-report): clojure -M:pw-report
Playwright trace aggregation and HTML dashboard generator.
Scans a directory tree for *.zip trace files produced by `testing.pw/with-pw`
and emits a self-contained `index.html` dashboard that:
- Lists every trace with its test name, timestamp, and file size.
- Provides direct links to open each trace in the official online viewer
(https://trace.playwright.dev) — works when you serve the traces over HTTP.
- Shows a local CLI command to open each trace with the Playwright CLI.
- Includes an aggregated status summary (total / by date).
- Copies the Playwright Trace Viewer static assets into <output-dir>/trace/
so that the embedded offline viewer links work immediately.
Usage from the REPL or as a -main entry point:
(require '[testing.pw-report :as rep])
(rep/generate-report) ; default: scans target/pw-traces
(rep/generate-report {:traces-dir "target/pw-traces"
:output-dir "target/pw-traces"
:project "My Project"})
CLI alias (see deps.edn :pw-report):
clojure -M:pw-report
nREPL helper for interactive Playwright browser exploration.
Start with: clj -M:nrepl
Then connect your editor to port 7888 (or whatever is printed).
Quick reference: (require '[testing.repl :refer [page ctx restart stop]])
(.navigate @page "https://example.com") (.textContent (.locator @page "h1")) (.screenshot @page) (.title @page)
(restart) ;; fresh browser (stop) ;; close browser
nREPL helper for interactive Playwright browser exploration. Start with: clj -M:nrepl Then connect your editor to port 7888 (or whatever is printed). Quick reference: (require '[testing.repl :refer [page ctx restart stop]]) (.navigate @page "https://example.com") (.textContent (.locator @page "h1")) (.screenshot @page) (.title @page) (restart) ;; fresh browser (stop) ;; close browser
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |