Playwright lifecycle management and browser launching.
Entry point for all Playwright operations. Creates Playwright instances and launches browsers (Chromium, Firefox, WebKit).
Usage: (with-playwright [pw (create)] (with-browser [browser (launch-chromium pw {:headless true})] (with-page [page (new-page browser)] (navigate page "https://example.com") (text-content page "h1"))))
All operations return anomaly maps on failure instead of throwing exceptions.
Playwright lifecycle management and browser launching.
Entry point for all Playwright operations. Creates Playwright instances
and launches browsers (Chromium, Firefox, WebKit).
Usage:
(with-playwright [pw (create)]
(with-browser [browser (launch-chromium pw {:headless true})]
(with-page [page (new-page browser)]
(navigate page "https://example.com")
(text-content page "h1"))))
All operations return anomaly maps on failure instead of throwing exceptions.Map of hook functions invoked during the API request lifecycle.
All hooks are optional (nil = no-op). Each hook receives context about the current operation and can observe or transform it.
Keys:
:on-request (fn [method url opts]) -> opts Called before every request. Receives the HTTP method keyword (:get, :post, ...), the URL string, and the opts map. Return value replaces opts. Return nil to keep original. Use for: logging, auth token injection, request transformation.
:on-response (fn [method url response]) -> response
Called after every successful request. Receives the method,
URL, and the APIResponse (or response map from request!).
Return value replaces the response. Return nil to keep original.
Use for: logging, metrics, response transformation.
:on-error (fn [method url anomaly]) -> anomaly Called when a request returns an anomaly (network error, timeout, etc.). Return value replaces the anomaly. Return nil to keep original. Use for: error logging, alerting, error transformation.
:on-retry (fn [{:keys [attempt max-attempts delay-ms result]}]) Called before each retry sleep. Side-effect only, return value ignored. Use for: logging retry attempts, metrics.
Examples:
;; Global logging (alter-var-root #'hooks (constantly {:on-request (fn [m url _] (println "→" m url)) :on-response (fn [m url r] (println "←" m url (.status r)) r)}))
;; Per-scope auth injection (binding [hooks {:on-request (fn [_ _ opts] (update opts :headers assoc "Authorization" (str "Bearer " (get-token))))}] (api-get ctx "/protected"))
Map of hook functions invoked during the API request lifecycle.
All hooks are optional (nil = no-op). Each hook receives context
about the current operation and can observe or transform it.
Keys:
:on-request (fn [method url opts]) -> opts
Called before every request. Receives the HTTP method keyword
(:get, :post, ...), the URL string, and the opts map.
Return value replaces opts. Return nil to keep original.
Use for: logging, auth token injection, request transformation.
:on-response (fn [method url response]) -> response
Called after every successful request. Receives the method,
URL, and the APIResponse (or response map from `request!`).
Return value replaces the response. Return nil to keep original.
Use for: logging, metrics, response transformation.
:on-error (fn [method url anomaly]) -> anomaly
Called when a request returns an anomaly (network error,
timeout, etc.). Return value replaces the anomaly.
Return nil to keep original.
Use for: error logging, alerting, error transformation.
:on-retry (fn [{:keys [attempt max-attempts delay-ms result]}])
Called before each retry sleep. Side-effect only, return
value ignored.
Use for: logging retry attempts, metrics.
Examples:
;; Global logging
(alter-var-root #'*hooks*
(constantly
{:on-request (fn [m url _] (println "→" m url))
:on-response (fn [m url r] (println "←" m url (.status r)) r)}))
;; Per-scope auth injection
(binding [*hooks* {:on-request (fn [_ _ opts]
(update opts :headers
assoc "Authorization" (str "Bearer " (get-token))))}]
(api-get ctx "/protected"))Function that encodes Clojure data to a JSON string. Bind to your preferred JSON library's encode function.
Must accept any Clojure data (maps, vectors, strings, numbers, etc.) and return a String.
Examples: ;; cheshire (binding [json-encoder cheshire.core/generate-string] (api-post ctx "/users" {:json {:name "Alice"}}))
;; charred (binding [json-encoder charred.api/write-json-str] (api-post ctx "/users" {:json {:name "Alice"}}))
;; jsonista (binding [json-encoder jsonista.core/write-value-as-string] (api-post ctx "/users" {:json {:name "Alice"}}))
;; Set globally for convenience (alter-var-root #'json-encoder (constantly cheshire.core/generate-string))
Function that encodes Clojure data to a JSON string.
Bind to your preferred JSON library's encode function.
Must accept any Clojure data (maps, vectors, strings, numbers, etc.)
and return a String.
Examples:
;; cheshire
(binding [*json-encoder* cheshire.core/generate-string]
(api-post ctx "/users" {:json {:name "Alice"}}))
;; charred
(binding [*json-encoder* charred.api/write-json-str]
(api-post ctx "/users" {:json {:name "Alice"}}))
;; jsonista
(binding [*json-encoder* jsonista.core/write-value-as-string]
(api-post ctx "/users" {:json {:name "Alice"}}))
;; Set globally for convenience
(alter-var-root #'*json-encoder* (constantly cheshire.core/generate-string))When bound to an atom, execute-request stores request metadata here.
Used by allure/api-step to capture request details (method, URL, headers,
body) alongside the response for rich HTTP exchange reporting.
The atom is reset to a map with keys: :method - String. HTTP method ("GET", "POST", etc.). :url - String. Request URL. :request-headers - Map or nil. Request headers from opts. :request-body - String or nil. Request body (from :data or encoded :json).
When bound to an atom, `execute-request` stores request metadata here.
Used by `allure/api-step` to capture request details (method, URL, headers,
body) alongside the response for rich HTTP exchange reporting.
The atom is reset to a map with keys:
:method - String. HTTP method ("GET", "POST", etc.).
:url - String. Request URL.
:request-headers - Map or nil. Request headers from opts.
:request-body - String or nil. Request body (from :data or encoded :json).Returns true if x is an anomaly map (has a recognized anomaly category). Re-exported from com.blockether.anomaly.core for caller convenience.
Returns true if x is an anomaly map (has a recognized anomaly category). Re-exported from com.blockether.anomaly.core for caller convenience.
(api-delete ctx url)(api-delete ctx url opts)Sends a DELETE request.
Params:
ctx - APIRequestContext instance.
url - String. URL path.
opts - RequestOptions or map, optional. See request-options.
Returns: APIResponse or anomaly map.
Sends a DELETE request. Params: `ctx` - APIRequestContext instance. `url` - String. URL path. `opts` - RequestOptions or map, optional. See `request-options`. Returns: APIResponse or anomaly map.
(api-dispose! ctx)Disposes the APIRequestContext and all responses.
Params:
ctx - APIRequestContext instance.
Returns: nil.
Disposes the APIRequestContext and all responses. Params: `ctx` - APIRequestContext instance. Returns: nil.
(api-fetch ctx url)(api-fetch ctx url opts)Sends a request with custom method (set via :method in opts).
Params:
ctx - APIRequestContext instance.
url - String. URL path.
opts - RequestOptions or map, optional. See request-options.
Returns: APIResponse or anomaly map.
Examples: (api-fetch ctx "/resource" {:method "OPTIONS"})
Sends a request with custom method (set via :method in opts).
Params:
`ctx` - APIRequestContext instance.
`url` - String. URL path.
`opts` - RequestOptions or map, optional. See `request-options`.
Returns:
APIResponse or anomaly map.
Examples:
(api-fetch ctx "/resource" {:method "OPTIONS"})(api-get ctx url)(api-get ctx url opts)Sends a GET request.
Params:
ctx - APIRequestContext instance.
url - String. URL path (resolved against base-url if set).
opts - RequestOptions or map, optional. See request-options.
Returns: APIResponse or anomaly map.
Examples: (api-get ctx "/users") (api-get ctx "/users" {:params {:page 1 :limit 10} :headers {"Authorization" "Bearer token"}})
Sends a GET request.
Params:
`ctx` - APIRequestContext instance.
`url` - String. URL path (resolved against base-url if set).
`opts` - RequestOptions or map, optional. See `request-options`.
Returns:
APIResponse or anomaly map.
Examples:
(api-get ctx "/users")
(api-get ctx "/users" {:params {:page 1 :limit 10}
:headers {"Authorization" "Bearer token"}})(api-head ctx url)(api-head ctx url opts)Sends a HEAD request.
Params:
ctx - APIRequestContext instance.
url - String. URL path.
opts - RequestOptions or map, optional. See request-options.
Returns: APIResponse or anomaly map.
Sends a HEAD request. Params: `ctx` - APIRequestContext instance. `url` - String. URL path. `opts` - RequestOptions or map, optional. See `request-options`. Returns: APIResponse or anomaly map.
(api-patch ctx url)(api-patch ctx url opts)Sends a PATCH request.
Params:
ctx - APIRequestContext instance.
url - String. URL path.
opts - RequestOptions or map, optional. See request-options.
Returns: APIResponse or anomaly map.
Sends a PATCH request. Params: `ctx` - APIRequestContext instance. `url` - String. URL path. `opts` - RequestOptions or map, optional. See `request-options`. Returns: APIResponse or anomaly map.
(api-post ctx url)(api-post ctx url opts)Sends a POST request.
Params:
ctx - APIRequestContext instance.
url - String. URL path.
opts - RequestOptions or map, optional. See request-options.
Returns: APIResponse or anomaly map.
Examples: (api-post ctx "/users" {:data "{"name": "Alice"}" :headers {"Content-Type" "application/json"}}) (api-post ctx "/login" {:form (map->form-data {:user "admin" :pass "secret"})})
Sends a POST request.
Params:
`ctx` - APIRequestContext instance.
`url` - String. URL path.
`opts` - RequestOptions or map, optional. See `request-options`.
Returns:
APIResponse or anomaly map.
Examples:
(api-post ctx "/users" {:data "{\"name\": \"Alice\"}"
:headers {"Content-Type" "application/json"}})
(api-post ctx "/login" {:form (map->form-data {:user "admin" :pass "secret"})})(api-put ctx url)(api-put ctx url opts)Sends a PUT request.
Params:
ctx - APIRequestContext instance.
url - String. URL path.
opts - RequestOptions or map, optional. See request-options.
Returns: APIResponse or anomaly map.
Sends a PUT request. Params: `ctx` - APIRequestContext instance. `url` - String. URL path. `opts` - RequestOptions or map, optional. See `request-options`. Returns: APIResponse or anomaly map.
(api-request pw)Returns the APIRequest for the Playwright instance.
Params:
pw - Playwright instance.
Returns: APIRequest instance.
Returns the APIRequest for the Playwright instance. Params: `pw` - Playwright instance. Returns: APIRequest instance.
(api-response->map resp)Converts an APIResponse to a Clojure map.
Reads the response body as text and includes all metadata. Useful for logging, debugging, and test assertions.
Params:
resp - APIResponse instance.
Returns: Map with keys: :status - Long. HTTP status code. :status-text - String. HTTP status text. :url - String. Response URL. :ok? - Boolean. True if status is 2xx. :headers - Map. Response headers. :body - String. Response body text (nil on read failure).
Examples: (let [resp (api-get ctx "/users")] (api-response->map resp)) ;; => {:status 200 ;; :status-text "OK" ;; :url "https://api.example.com/users" ;; :ok? true ;; :headers {"content-type" "application/json"} ;; :body "{"users": [...]}"}
Converts an APIResponse to a Clojure map.
Reads the response body as text and includes all metadata.
Useful for logging, debugging, and test assertions.
Params:
`resp` - APIResponse instance.
Returns:
Map with keys:
:status - Long. HTTP status code.
:status-text - String. HTTP status text.
:url - String. Response URL.
:ok? - Boolean. True if status is 2xx.
:headers - Map. Response headers.
:body - String. Response body text (nil on read failure).
Examples:
(let [resp (api-get ctx "/users")]
(api-response->map resp))
;; => {:status 200
;; :status-text "OK"
;; :url "https://api.example.com/users"
;; :ok? true
;; :headers {"content-type" "application/json"}
;; :body "{\"users\": [...]}"}(api-response-body resp)Returns the response body as bytes. Passes through anomaly maps unchanged.
Returns the response body as bytes. Passes through anomaly maps unchanged.
(api-response-dispose! resp)Disposes the APIResponse. No-op on anomaly maps.
Params:
resp - APIResponse instance.
Returns: nil.
Disposes the APIResponse. No-op on anomaly maps. Params: `resp` - APIResponse instance. Returns: nil.
(api-response-headers resp)Returns the response headers. Passes through anomaly maps unchanged.
Returns the response headers. Passes through anomaly maps unchanged.
(api-response-headers-array resp)Returns the response headers as a vector of {:name :value} maps.
Preserves duplicate headers (unlike api-response-headers which
keeps only the last value for each name).
Passes through anomaly maps unchanged.
Params:
resp - APIResponse instance.
Returns: Vector of maps, or anomaly map.
Returns the response headers as a vector of {:name :value} maps.
Preserves duplicate headers (unlike `api-response-headers` which
keeps only the last value for each name).
Passes through anomaly maps unchanged.
Params:
`resp` - APIResponse instance.
Returns:
Vector of maps, or anomaly map.(api-response-ok? resp)Returns whether the response is OK (2xx). Passes through anomaly maps unchanged.
Returns whether the response is OK (2xx). Passes through anomaly maps unchanged.
(api-response-status resp)Returns the HTTP status code. Passes through anomaly maps unchanged.
Returns the HTTP status code. Passes through anomaly maps unchanged.
(api-response-status-text resp)Returns the HTTP status text. Passes through anomaly maps unchanged.
Returns the HTTP status text. Passes through anomaly maps unchanged.
(api-response-text resp)Returns the response body as text. Passes through anomaly maps unchanged.
Returns the response body as text. Passes through anomaly maps unchanged.
(api-response-url resp)Returns the response URL. Passes through anomaly maps unchanged.
Returns the response URL. Passes through anomaly maps unchanged.
(browser-connected? browser)Returns true if the browser is connected.
Params:
browser - Browser instance.
Returns: Boolean.
Returns true if the browser is connected. Params: `browser` - Browser instance. Returns: Boolean.
(browser-contexts browser)Returns all browser contexts.
Params:
browser - Browser instance.
Returns: Vector of BrowserContext instances.
Returns all browser contexts. Params: `browser` - Browser instance. Returns: Vector of BrowserContext instances.
(browser-type-name bt)Returns the name of the browser type.
Params:
bt - BrowserType instance.
Returns: String. "chromium", "firefox", or "webkit".
Returns the name of the browser type. Params: `bt` - BrowserType instance. Returns: String. "chromium", "firefox", or "webkit".
(browser-version browser)Returns the browser version string.
Params:
browser - Browser instance.
Returns: String. Browser version.
Returns the browser version string. Params: `browser` - Browser instance. Returns: String. Browser version.
(cdp-detach! session)Detaches the CDP session.
Params:
session - CDPSession instance.
Detaches the CDP session. Params: `session` - CDPSession instance.
(cdp-on session event handler)Registers a handler for CDP events.
Params:
session - CDPSession instance.
event - String. Event name.
handler - Function that receives the event data.
Registers a handler for CDP events. Params: `session` - CDPSession instance. `event` - String. Event name. `handler` - Function that receives the event data.
(cdp-send session method)(cdp-send session method params)Sends a Chrome DevTools Protocol command.
Params:
session - CDPSession instance.
method - String. CDP method name.
params - Map, optional. CDP parameters.
Returns: JSON result or anomaly map.
Sends a Chrome DevTools Protocol command. Params: `session` - CDPSession instance. `method` - String. CDP method name. `params` - Map, optional. CDP parameters. Returns: JSON result or anomaly map.
(chromium pw)Returns the Chromium BrowserType.
Params:
pw - Playwright instance.
Returns: BrowserType for Chromium.
Returns the Chromium BrowserType. Params: `pw` - Playwright instance. Returns: BrowserType for Chromium.
(close! pw)Closes a Playwright instance and releases all resources.
Params:
pw - Playwright instance.
Returns: nil.
Closes a Playwright instance and releases all resources. Params: `pw` - Playwright instance. Returns: nil.
(close-browser! browser)Closes a browser and all its pages.
Params:
browser - Browser instance.
Returns: nil.
Closes a browser and all its pages. Params: `browser` - Browser instance. Returns: nil.
(close-context! context)Closes a browser context and all its pages.
Params:
context - BrowserContext instance.
Returns: nil.
Closes a browser context and all its pages. Params: `context` - BrowserContext instance. Returns: nil.
(close-page! page)Closes a page.
Params:
page - Page instance.
Returns: nil.
Closes a page. Params: `page` - Page instance. Returns: nil.
(context-api ctx)Returns the APIRequestContext for a BrowserContext.
The returned context shares cookies and storage with the browser context. API calls through it appear in Playwright traces automatically.
Params:
ctx - BrowserContext instance.
Returns: APIRequestContext bound to the browser context.
Examples: (with-playwright [pw] (with-browser [browser (launch-chromium pw)] (with-context [ctx (new-context browser {:base-url "https://api.example.com"})] (let [resp (api-get (context-api ctx) "/users")] (api-response-status resp)))))
Returns the APIRequestContext for a BrowserContext.
The returned context shares cookies and storage with the browser context.
API calls through it appear in Playwright traces automatically.
Params:
`ctx` - BrowserContext instance.
Returns:
APIRequestContext bound to the browser context.
Examples:
(with-playwright [pw]
(with-browser [browser (launch-chromium pw)]
(with-context [ctx (new-context browser {:base-url "https://api.example.com"})]
(let [resp (api-get (context-api ctx) "/users")]
(api-response-status resp)))))(context-browser context)Returns the browser that owns this context.
Params:
context - BrowserContext instance.
Returns: Browser instance.
Returns the browser that owns this context. Params: `context` - BrowserContext instance. Returns: Browser instance.
(context-clear-cookies! context)Clears all cookies in the context.
Params:
context - BrowserContext instance.
Clears all cookies in the context. Params: `context` - BrowserContext instance.
(context-clear-permissions! context)Clears all granted permissions.
Params:
context - BrowserContext instance.
Clears all granted permissions. Params: `context` - BrowserContext instance.
(context-cookies context)Returns all cookies in the context.
Params:
context - BrowserContext instance.
Returns: Vector of cookie maps.
Returns all cookies in the context. Params: `context` - BrowserContext instance. Returns: Vector of cookie maps.
(context-grant-permissions! context permissions)Grants permissions to the context.
Params:
context - BrowserContext instance.
permissions - Collection of strings (e.g. ["geolocation"]).
Grants permissions to the context. Params: `context` - BrowserContext instance. `permissions` - Collection of strings (e.g. ["geolocation"]).
(context-pages context)Returns all pages in a context.
Params:
context - BrowserContext instance.
Returns: Vector of Page instances.
Returns all pages in a context. Params: `context` - BrowserContext instance. Returns: Vector of Page instances.
(context-route-from-har! context har)(context-route-from-har! context har route-opts)Routes requests in the context from a HAR file. Replays recorded responses for matching requests.
Use with :update true to record actual responses into the HAR for later replay.
Params:
context - BrowserContext instance.
har - String. Path to the HAR file.
opts - Map, optional. RouteFromHAR options:
:url - String glob or regex Pattern.
:not-found - Keyword. :abort or :fallback.
:update - Boolean. Whether to update HAR with actual network data.
:update-content - Keyword. :embed or :attach.
:update-mode - Keyword. :full or :minimal.
Routes requests in the context from a HAR file. Replays recorded responses
for matching requests.
Use with :update true to record actual responses into the HAR for later replay.
Params:
`context` - BrowserContext instance.
`har` - String. Path to the HAR file.
`opts` - Map, optional. RouteFromHAR options:
:url - String glob or regex Pattern.
:not-found - Keyword. :abort or :fallback.
:update - Boolean. Whether to update HAR with actual network data.
:update-content - Keyword. :embed or :attach.
:update-mode - Keyword. :full or :minimal.(context-route-web-socket! context pattern handler)Registers a handler for WebSocket connections matching a URL pattern in the browser context (applies to all pages in this context).
The handler receives a WebSocketRoute that can be used to mock the WebSocket connection (send messages, intercept client messages, etc.).
Params:
context - BrowserContext instance.
pattern - String glob, regex Pattern, or predicate fn.
handler - Function that receives a WebSocketRoute.
Registers a handler for WebSocket connections matching a URL pattern in the browser context (applies to all pages in this context). The handler receives a WebSocketRoute that can be used to mock the WebSocket connection (send messages, intercept client messages, etc.). Params: `context` - BrowserContext instance. `pattern` - String glob, regex Pattern, or predicate fn. `handler` - Function that receives a WebSocketRoute.
(context-save-storage-state! context path)Saves the storage state (cookies, localStorage) to a file.
Params:
context - BrowserContext instance.
path - String. File path to save the JSON state to.
Returns: The storage state JSON string.
Saves the storage state (cookies, localStorage) to a file. Params: `context` - BrowserContext instance. `path` - String. File path to save the JSON state to. Returns: The storage state JSON string.
(context-set-default-navigation-timeout! context timeout)Sets the default navigation timeout.
Params:
context - BrowserContext instance.
timeout - Double. Timeout in milliseconds.
Sets the default navigation timeout. Params: `context` - BrowserContext instance. `timeout` - Double. Timeout in milliseconds.
(context-set-default-timeout! context timeout)Sets the default timeout for context operations.
Params:
context - BrowserContext instance.
timeout - Double. Timeout in milliseconds.
Sets the default timeout for context operations. Params: `context` - BrowserContext instance. `timeout` - Double. Timeout in milliseconds.
(context-set-extra-http-headers! context headers)Sets extra HTTP headers for all requests in the context.
Params:
context - BrowserContext instance.
headers - Map of string->string.
Sets extra HTTP headers for all requests in the context. Params: `context` - BrowserContext instance. `headers` - Map of string->string.
(context-set-offline! context offline)Sets the context to offline or online mode.
Params:
context - BrowserContext instance.
offline - Boolean.
Sets the context to offline or online mode. Params: `context` - BrowserContext instance. `offline` - Boolean.
(context-storage-state context)Returns the storage state (cookies, localStorage) as a JSON string.
Params:
context - BrowserContext instance.
Returns: JSON string containing cookies and origins with localStorage.
Returns the storage state (cookies, localStorage) as a JSON string. Params: `context` - BrowserContext instance. Returns: JSON string containing cookies and origins with localStorage.
(context-tracing context)Returns the Tracing for a context.
Params:
context - BrowserContext instance.
Returns: Tracing instance.
Returns the Tracing for a context. Params: `context` - BrowserContext instance. Returns: Tracing instance.
(create)Creates a new Playwright instance.
Automatically detects Clojure source directories (src, test, test-e2e, dev) and configures Playwright tracing to include .clj source files. When a trace is captured with {:sources true}, the Trace Viewer Source tab will show the actual Clojure source code for each action.
Respects the PLAYWRIGHT_JAVA_SRC environment variable if already set.
Returns: Playwright instance or anomaly map on failure.
Examples: (def pw (create)) ;; Use pw for browser launching, then (.close pw) when done.
Creates a new Playwright instance.
Automatically detects Clojure source directories (src, test, test-e2e, dev) and
configures Playwright tracing to include .clj source files. When a trace
is captured with {:sources true}, the Trace Viewer Source tab will show
the actual Clojure source code for each action.
Respects the PLAYWRIGHT_JAVA_SRC environment variable if already set.
Returns:
Playwright instance or anomaly map on failure.
Examples:
(def pw (create))
;; Use pw for browser launching, then (.close pw) when done.Default retry configuration.
:max-attempts - Total attempts including the first (default: 3). :delay-ms - Initial delay between retries in ms (default: 200). :backoff - Backoff strategy (default: :exponential). :fixed — constant delay. :linear — delay * attempt. :exponential — delay * 2^attempt. :max-delay-ms - Ceiling on delay (default: 10000). :retry-when - Predicate (fn [result] -> truthy to retry). Default: retries on anomalies and 5xx status codes.
Default retry configuration.
:max-attempts - Total attempts including the first (default: 3).
:delay-ms - Initial delay between retries in ms (default: 200).
:backoff - Backoff strategy (default: :exponential).
:fixed — constant delay.
:linear — delay * attempt.
:exponential — delay * 2^attempt.
:max-delay-ms - Ceiling on delay (default: 10000).
:retry-when - Predicate (fn [result] -> truthy to retry).
Default: retries on anomalies and 5xx status codes.(fd-append fd name value)Appends a field to FormData.
Params:
fd - FormData instance.
name - String. Field name.
value - String. Field value.
Returns: FormData instance.
Appends a field to FormData. Params: `fd` - FormData instance. `name` - String. Field name. `value` - String. Field value. Returns: FormData instance.
(fd-set fd name value)Sets a field in FormData.
Params:
fd - FormData instance.
name - String. Field name.
value - String. Field value.
Returns: FormData instance.
Sets a field in FormData. Params: `fd` - FormData instance. `name` - String. Field name. `value` - String. Field value. Returns: FormData instance.
(firefox pw)Returns the Firefox BrowserType.
Params:
pw - Playwright instance.
Returns: BrowserType for Firefox.
Returns the Firefox BrowserType. Params: `pw` - Playwright instance. Returns: BrowserType for Firefox.
(form-data)Creates a new FormData instance.
Returns: FormData instance.
Creates a new FormData instance. Returns: FormData instance.
(launch browser-type)(launch browser-type launch-opts)Launches a browser of the given type.
Params:
browser-type - BrowserType instance.
opts - Map, optional. Launch options (see options/->launch-options).
Returns: Browser instance or anomaly map on failure.
Launches a browser of the given type. Params: `browser-type` - BrowserType instance. `opts` - Map, optional. Launch options (see options/->launch-options). Returns: Browser instance or anomaly map on failure.
(launch-chromium pw)(launch-chromium pw opts)Launches Chromium browser.
Params:
pw - Playwright instance.
opts - Map, optional. Launch options.
Returns: Browser instance or anomaly map on failure.
Examples: (launch-chromium pw) (launch-chromium pw {:headless false :slow-mo 100})
Launches Chromium browser.
Params:
`pw` - Playwright instance.
`opts` - Map, optional. Launch options.
Returns:
Browser instance or anomaly map on failure.
Examples:
(launch-chromium pw)
(launch-chromium pw {:headless false :slow-mo 100})(launch-firefox pw)(launch-firefox pw opts)Launches Firefox browser.
Params:
pw - Playwright instance.
opts - Map, optional. Launch options.
Returns: Browser instance or anomaly map on failure.
Launches Firefox browser. Params: `pw` - Playwright instance. `opts` - Map, optional. Launch options. Returns: Browser instance or anomaly map on failure.
(launch-persistent-context browser-type user-data-dir)(launch-persistent-context browser-type user-data-dir opts)Launches a browser with a persistent user data directory (Chrome profile).
Unlike launch + new-context, this uses a real Chrome profile directory
that persists cookies, localStorage, extensions, saved passwords, bookmarks,
and other browser data across sessions.
Returns a BrowserContext directly (not a Browser). Closing the context automatically closes the browser.
Params:
browser-type - BrowserType instance (from chromium, firefox, webkit).
user-data-dir - String. Path to Chrome user data directory.
Pass empty string for a temporary profile.
opts - Map, optional. Combined launch + context options
(see options/->launch-persistent-context-options).
Returns: BrowserContext instance or anomaly map on failure.
Examples: (launch-persistent-context (chromium pw) "/tmp/my-profile") (launch-persistent-context (chromium pw) "/tmp/my-profile" {:headless false :user-agent "MyAgent/1.0"})
Launches a browser with a persistent user data directory (Chrome profile).
Unlike `launch` + `new-context`, this uses a real Chrome profile directory
that persists cookies, localStorage, extensions, saved passwords, bookmarks,
and other browser data across sessions.
Returns a BrowserContext directly (not a Browser). Closing the context
automatically closes the browser.
Params:
`browser-type` - BrowserType instance (from `chromium`, `firefox`, `webkit`).
`user-data-dir` - String. Path to Chrome user data directory.
Pass empty string for a temporary profile.
`opts` - Map, optional. Combined launch + context options
(see options/->launch-persistent-context-options).
Returns:
BrowserContext instance or anomaly map on failure.
Examples:
(launch-persistent-context (chromium pw) "/tmp/my-profile")
(launch-persistent-context (chromium pw) "/tmp/my-profile"
{:headless false :user-agent "MyAgent/1.0"})(launch-webkit pw)(launch-webkit pw opts)Launches WebKit browser.
Params:
pw - Playwright instance.
opts - Map, optional. Launch options.
Returns: Browser instance or anomaly map on failure.
Launches WebKit browser. Params: `pw` - Playwright instance. `opts` - Map, optional. Launch options. Returns: Browser instance or anomaly map on failure.
(map->form-data m)Converts a Clojure map to FormData.
Params:
m - Map of string->string.
Returns: FormData instance.
Converts a Clojure map to FormData. Params: `m` - Map of string->string. Returns: FormData instance.
(new-api-context api-req)(new-api-context api-req opts)Creates a new APIRequestContext.
Params:
api-req - APIRequest instance (from api-request).
opts - Map, optional. Context options:
:base-url - String. Base URL for all requests.
:extra-http-headers - Map. Headers sent with every request.
:ignore-https-errors - Boolean. Ignore SSL certificate errors.
:timeout - Double. Default timeout in ms (default: 30000).
:user-agent - String. User-Agent header.
:max-redirects - Long. Max redirects to follow (default: 20).
:fail-on-status-code - Boolean. Throw on non-2xx/3xx status.
:storage-state - String. Storage state JSON or path.
Returns: APIRequestContext or anomaly map.
Examples: (new-api-context (api-request pw) {:base-url "https://api.example.com" :extra-http-headers {"Authorization" "Bearer token"} :timeout 10000})
Creates a new APIRequestContext.
Params:
`api-req` - APIRequest instance (from `api-request`).
`opts` - Map, optional. Context options:
:base-url - String. Base URL for all requests.
:extra-http-headers - Map. Headers sent with every request.
:ignore-https-errors - Boolean. Ignore SSL certificate errors.
:timeout - Double. Default timeout in ms (default: 30000).
:user-agent - String. User-Agent header.
:max-redirects - Long. Max redirects to follow (default: 20).
:fail-on-status-code - Boolean. Throw on non-2xx/3xx status.
:storage-state - String. Storage state JSON or path.
Returns:
APIRequestContext or anomaly map.
Examples:
(new-api-context (api-request pw)
{:base-url "https://api.example.com"
:extra-http-headers {"Authorization" "Bearer token"}
:timeout 10000})(new-context browser)(new-context browser context-opts)Creates a new browser context with optional configuration.
Params:
browser - Browser instance.
opts - Map, optional. Context options (see options/->new-context-options).
Returns: BrowserContext instance or anomaly map on failure.
Creates a new browser context with optional configuration. Params: `browser` - Browser instance. `opts` - Map, optional. Context options (see options/->new-context-options). Returns: BrowserContext instance or anomaly map on failure.
(new-page browser)(new-page browser context-opts)Creates a new page in a browser (creates implicit context).
Params:
browser - Browser instance.
Returns: Page instance or anomaly map on failure.
Creates a new page in a browser (creates implicit context). Params: `browser` - Browser instance. Returns: Page instance or anomaly map on failure.
(new-page-from-context context)Creates a new page in the given context.
Params:
context - BrowserContext instance.
Returns: Page instance or anomaly map on failure.
Creates a new page in the given context. Params: `context` - BrowserContext instance. Returns: Page instance or anomaly map on failure.
(page-api pg)Returns the APIRequestContext for a Page.
The returned context shares cookies and storage with the page's browser context. API calls through it appear in Playwright traces automatically.
Params:
pg - Page instance.
Returns: APIRequestContext bound to the page's browser context.
Examples: (with-testing-page [pg] (page/navigate pg "https://example.com/login") ;; API calls share the browser session (cookies, auth) (let [resp (api-get (page-api pg) "/api/me")] (api-response-status resp)))
Returns the APIRequestContext for a Page.
The returned context shares cookies and storage with the page's browser
context. API calls through it appear in Playwright traces automatically.
Params:
`pg` - Page instance.
Returns:
APIRequestContext bound to the page's browser context.
Examples:
(with-testing-page [pg]
(page/navigate pg "https://example.com/login")
;; API calls share the browser session (cookies, auth)
(let [resp (api-get (page-api pg) "/api/me")]
(api-response-status resp)))(request! pw method url)(request! pw method url opts)Fire-and-forget HTTP request. Creates an ephemeral context, makes the request, reads the full response into a Clojure map, and disposes everything. No context management needed.
Params:
pw - Playwright instance.
method - Keyword. :get :post :put :patch :delete :head.
url - String. Full URL (not relative — no base-url).
opts - Map, optional. See request-options for all keys.
Returns:
Response map (same shape as api-response->map) or anomaly map.
Examples: ;; Simple GET — no setup, no cleanup (request! pw :get "https://api.example.com/health") ;; => {:status 200 :ok? true :body "OK" ...}
;; POST with JSON body (request! pw :post "https://api.example.com/users" {:data "{"name": "Alice"}" :headers {"Content-Type" "application/json" "Authorization" "Bearer token"}})
;; Hit multiple domains without any context setup (let [users (request! pw :get "https://users.example.com/me" {:headers {"Authorization" "Bearer user-token"}}) invoices (request! pw :get "https://billing.example.com/invoices" {:headers {"X-API-Key" "billing-key"}})] [users invoices])
Fire-and-forget HTTP request. Creates an ephemeral context, makes the
request, reads the full response into a Clojure map, and disposes
everything. No context management needed.
Params:
`pw` - Playwright instance.
`method` - Keyword. :get :post :put :patch :delete :head.
`url` - String. Full URL (not relative — no base-url).
`opts` - Map, optional. See `request-options` for all keys.
Returns:
Response map (same shape as `api-response->map`) or anomaly map.
Examples:
;; Simple GET — no setup, no cleanup
(request! pw :get "https://api.example.com/health")
;; => {:status 200 :ok? true :body "OK" ...}
;; POST with JSON body
(request! pw :post "https://api.example.com/users"
{:data "{\"name\": \"Alice\"}"
:headers {"Content-Type" "application/json"
"Authorization" "Bearer token"}})
;; Hit multiple domains without any context setup
(let [users (request! pw :get "https://users.example.com/me"
{:headers {"Authorization" "Bearer user-token"}})
invoices (request! pw :get "https://billing.example.com/invoices"
{:headers {"X-API-Key" "billing-key"}})]
[users invoices])(request-options opts)Creates RequestOptions from a map.
Params:
opts - Map with optional:
:method - String. HTTP method override.
:headers - Map. HTTP headers ({"Authorization" "Bearer ..."}).
:data - String, bytes, or Object. Request body.
Objects are auto-serialized to JSON by Playwright.
:json - Any Clojure data. Encoded via *json-encoder*,
sets Content-Type to application/json automatically.
Mutually exclusive with :data, :form, :multipart.
:form - FormData. URL-encoded form data.
:multipart - FormData. Multipart form data (file uploads).
:timeout - Double. Timeout in ms (default: 30000).
:params - Map. Query parameters.
:max-redirects - Long. Max redirects to follow (default: 20).
:max-retries - Long. Retry network errors (default: 0).
:fail-on-status-code - Boolean. Throw on non-2xx/3xx status.
:ignore-https-errors - Boolean. Ignore SSL certificate errors.
The :json key requires *json-encoder* to be bound:
(binding [json-encoder cheshire.core/generate-string] (api-post ctx "/users" {:json {:name "Alice" :age 30}}))
Returns: RequestOptions instance.
Creates RequestOptions from a map.
Params:
`opts` - Map with optional:
:method - String. HTTP method override.
:headers - Map. HTTP headers ({"Authorization" "Bearer ..."}).
:data - String, bytes, or Object. Request body.
Objects are auto-serialized to JSON by Playwright.
:json - Any Clojure data. Encoded via `*json-encoder*`,
sets Content-Type to application/json automatically.
Mutually exclusive with :data, :form, :multipart.
:form - FormData. URL-encoded form data.
:multipart - FormData. Multipart form data (file uploads).
:timeout - Double. Timeout in ms (default: 30000).
:params - Map. Query parameters.
:max-redirects - Long. Max redirects to follow (default: 20).
:max-retries - Long. Retry network errors (default: 0).
:fail-on-status-code - Boolean. Throw on non-2xx/3xx status.
:ignore-https-errors - Boolean. Ignore SSL certificate errors.
The :json key requires `*json-encoder*` to be bound:
(binding [*json-encoder* cheshire.core/generate-string]
(api-post ctx "/users" {:json {:name "Alice" :age 30}}))
Returns:
RequestOptions instance.(retry f)(retry f opts)Execute f (a no-arg function) with retry logic.
Params:
f - No-arg function that returns a result.
opts - Map, optional. Override keys from default-retry-opts:
:max-attempts - Total attempts (default: 3).
:delay-ms - Initial delay in ms (default: 200).
:backoff - :fixed, :linear, or :exponential (default).
:max-delay-ms - Max delay ceiling in ms (default: 10000).
:retry-when - (fn [result]) → truthy to retry.
Returns: The result of the last attempt.
Examples: ;; Retry a flaky endpoint (retry #(api-get ctx "/flaky"))
;; Custom: retry on 429 Too Many Requests with linear backoff (retry #(api-get ctx "/rate-limited") {:max-attempts 5 :delay-ms 1000 :backoff :linear :retry-when (fn [r] (= 429 (:status (api-response->map r))))})
Execute `f` (a no-arg function) with retry logic.
Params:
`f` - No-arg function that returns a result.
`opts` - Map, optional. Override keys from `default-retry-opts`:
:max-attempts - Total attempts (default: 3).
:delay-ms - Initial delay in ms (default: 200).
:backoff - :fixed, :linear, or :exponential (default).
:max-delay-ms - Max delay ceiling in ms (default: 10000).
:retry-when - (fn [result]) → truthy to retry.
Returns:
The result of the last attempt.
Examples:
;; Retry a flaky endpoint
(retry #(api-get ctx "/flaky"))
;; Custom: retry on 429 Too Many Requests with linear backoff
(retry #(api-get ctx "/rate-limited")
{:max-attempts 5
:delay-ms 1000
:backoff :linear
:retry-when (fn [r] (= 429 (:status (api-response->map r))))})(run-with-page-api pg opts f)Functional core of with-page-api. Creates an APIRequestContext from a Page
with custom options (base-url, headers, etc.) while sharing cookies via
storage-state.
Copies storage-state (cookies, localStorage) from the page's browser context, creates a new APIRequestContext with the provided opts, and disposes it after.
Params:
pg - Page instance to extract cookies from.
opts - Map. Options for the new APIRequestContext:
:base-url - String. Base URL for all requests.
:extra-http-headers - Map. Headers sent with every request.
:ignore-https-errors - Boolean.
:json-encoder - Function. Binds *json-encoder* for the body.
f - Function receiving the new APIRequestContext.
Returns:
Result of calling f.
Examples: (run-with-page-api pg {:base-url "https://api.example.com"} (fn [ctx] (api-get ctx "/users")))
Functional core of `with-page-api`. Creates an APIRequestContext from a Page
with custom options (base-url, headers, etc.) while sharing cookies via
storage-state.
Copies storage-state (cookies, localStorage) from the page's browser context,
creates a new APIRequestContext with the provided opts, and disposes it after.
Params:
`pg` - Page instance to extract cookies from.
`opts` - Map. Options for the new APIRequestContext:
:base-url - String. Base URL for all requests.
:extra-http-headers - Map. Headers sent with every request.
:ignore-https-errors - Boolean.
:json-encoder - Function. Binds `*json-encoder*` for the body.
`f` - Function receiving the new APIRequestContext.
Returns:
Result of calling `f`.
Examples:
(run-with-page-api pg {:base-url "https://api.example.com"}
(fn [ctx]
(api-get ctx "/users")))(run-with-testing-api opts f)Functional core of with-testing-api. Sets up a complete Playwright stack
for API testing and calls (f api-request-context).
Creates: Playwright → Browser (headless Chromium) → BrowserContext → APIRequestContext.
The APIRequestContext comes from BrowserContext.request(), so all API calls
share cookies with the context and appear in Playwright traces.
When the Allure reporter is active, automatically enables tracing (DOM snapshots + sources) and HAR recording — zero configuration.
Opts:
:base-url - String. Base URL for all requests.
:extra-http-headers - Map. Headers sent with every request.
:ignore-https-errors - Boolean. Ignore SSL certificate errors.
:json-encoder - Function. Binds *json-encoder* for the body.
:storage-state - String. Storage state JSON or path.
new-context (:locale, :timezone-id, etc.)Examples: (run-with-testing-api {:base-url "https://api.example.com"} (fn [ctx] (api-get ctx "/users")))
Functional core of `with-testing-api`. Sets up a complete Playwright stack
for API testing and calls `(f api-request-context)`.
Creates: Playwright → Browser (headless Chromium) → BrowserContext → APIRequestContext.
The APIRequestContext comes from `BrowserContext.request()`, so all API calls
share cookies with the context and appear in Playwright traces.
When the Allure reporter is active, automatically enables tracing
(DOM snapshots + sources) and HAR recording — zero configuration.
Opts:
:base-url - String. Base URL for all requests.
:extra-http-headers - Map. Headers sent with every request.
:ignore-https-errors - Boolean. Ignore SSL certificate errors.
:json-encoder - Function. Binds `*json-encoder*` for the body.
:storage-state - String. Storage state JSON or path.
+ any key accepted by `new-context` (:locale, :timezone-id, etc.)
Examples:
(run-with-testing-api {:base-url "https://api.example.com"}
(fn [ctx]
(api-get ctx "/users")))(run-with-testing-page opts f)Functional core of with-testing-page. Sets up a complete Playwright stack
and calls (f page).
Two modes:
When the Allure reporter is active, automatically enables Playwright tracing (screenshots + DOM snapshots + sources) and HAR recording, and binds the allure dynamic vars so traces/HARs are attached to the test result.
Opts: :browser-type - :chromium (default), :firefox, or :webkit :headless - Boolean (default true) :slow-mo - Millis to slow down operations :device - Device preset keyword (e.g. :iphone-14, :pixel-7) :viewport - Viewport keyword (:mobile, :desktop-hd) or {:width :height} :profile - String. Path to persistent user data dir (Chrome profile). Pass empty string for a temporary profile. :executable-path - String. Path to browser executable. :channel - String. Browser channel (e.g. "chrome", "msedge"). :proxy - Map with :server, :bypass, :username, :password. :args - Vector of additional browser args. :downloads-path - String. Path to download files. :timeout - Double. Max time in ms to wait for browser launch. :chromium-sandbox - Boolean. Enable Chromium sandbox.
new-context (e.g. :locale, :color-scheme,
:timezone-id, :storage-state)When :device is given, its viewport/user-agent/device-scale-factor/is-mobile/has-touch are merged into context opts. Explicit :viewport overrides the device viewport.
Functional core of `with-testing-page`. Sets up a complete Playwright stack
and calls `(f page)`.
Two modes:
- **Normal** (no :profile): playwright → launch browser → new-context → page
- **Persistent** (:profile given): playwright → launch-persistent-context → page
When the Allure reporter is active, automatically enables Playwright tracing
(screenshots + DOM snapshots + sources) and HAR recording, and binds the
allure dynamic vars so traces/HARs are attached to the test result.
Opts:
:browser-type - :chromium (default), :firefox, or :webkit
:headless - Boolean (default true)
:slow-mo - Millis to slow down operations
:device - Device preset keyword (e.g. :iphone-14, :pixel-7)
:viewport - Viewport keyword (:mobile, :desktop-hd) or {:width :height}
:profile - String. Path to persistent user data dir (Chrome profile).
Pass empty string for a temporary profile.
:executable-path - String. Path to browser executable.
:channel - String. Browser channel (e.g. "chrome", "msedge").
:proxy - Map with :server, :bypass, :username, :password.
:args - Vector of additional browser args.
:downloads-path - String. Path to download files.
:timeout - Double. Max time in ms to wait for browser launch.
:chromium-sandbox - Boolean. Enable Chromium sandbox.
+ any key accepted by `new-context` (e.g. :locale, :color-scheme,
:timezone-id, :storage-state)
When :device is given, its viewport/user-agent/device-scale-factor/is-mobile/has-touch
are merged into context opts. Explicit :viewport overrides the device viewport.(safe & body)Wraps body in try/catch, returning anomaly map on Playwright errors.
Returns the result of body on success, or an anomaly map on failure. Catches TimeoutError, TargetClosedError, PlaywrightException, and any other Exception. All anomaly maps include the original exception, its class name, and full stack trace.
Wraps body in try/catch, returning anomaly map on Playwright errors. Returns the result of body on success, or an anomaly map on failure. Catches TimeoutError, TargetClosedError, PlaywrightException, and any other Exception. All anomaly maps include the original exception, its class name, and full stack trace.
(selectors pw)Returns the Selectors for a Playwright instance.
Params:
pw - Playwright instance.
Returns: Selectors instance.
Returns the Selectors for a Playwright instance. Params: `pw` - Playwright instance. Returns: Selectors instance.
(selectors-register! sels name script)Registers a custom selector engine.
Params:
sels - Selectors instance.
name - String. Selector engine name.
script - String. JavaScript for the selector engine.
Registers a custom selector engine. Params: `sels` - Selectors instance. `name` - String. Selector engine name. `script` - String. JavaScript for the selector engine.
(tracing-start! tracing)(tracing-start! tracing trace-opts)Starts tracing.
Params:
tracing - Tracing instance.
opts - Map, optional. Tracing options.
Starts tracing. Params: `tracing` - Tracing instance. `opts` - Map, optional. Tracing options.
(tracing-stop! tracing)(tracing-stop! tracing stop-opts)Stops tracing and saves the trace file.
Params:
tracing - Tracing instance.
opts - Map, optional. {:path "trace.zip"}.
Stops tracing and saves the trace file.
Params:
`tracing` - Tracing instance.
`opts` - Map, optional. {:path "trace.zip"}.(video-delete! page)Deletes the video file for a page.
Params:
page - Page instance.
Returns: nil.
Deletes the video file for a page. Params: `page` - Page instance. Returns: nil.
(video-obj-delete! video)Deletes the video file from a Video instance.
Params:
video - Video instance.
Deletes the video file from a Video instance. Params: `video` - Video instance.
(video-obj-path video)Returns the path to the video file from a Video instance.
Params:
video - Video instance.
Returns: Path or anomaly map.
Returns the path to the video file from a Video instance. Params: `video` - Video instance. Returns: Path or anomaly map.
(video-obj-save-as! video path)Saves the video to the given path from a Video instance.
Params:
video - Video instance.
path - String. Destination path.
Saves the video to the given path from a Video instance. Params: `video` - Video instance. `path` - String. Destination path.
(video-path page)Returns the video file path for a page, or nil if not recording. Video is finalized when the browser context closes.
Params:
page - Page instance.
Returns: String path to video file, or nil.
Returns the video file path for a page, or nil if not recording. Video is finalized when the browser context closes. Params: `page` - Page instance. Returns: String path to video file, or nil.
(video-save-as! page path)Saves the video to the specified path. Context must be closed first.
Params:
page - Page instance.
path - String destination path.
Returns: nil.
Saves the video to the specified path. Context must be closed first. Params: `page` - Page instance. `path` - String destination path. Returns: nil.
(webkit pw)Returns the WebKit BrowserType.
Params:
pw - Playwright instance.
Returns: BrowserType for WebKit.
Returns the WebKit BrowserType. Params: `pw` - Playwright instance. Returns: BrowserType for WebKit.
(with-api-context [sym expr] & body)Binds a single APIRequestContext and ensures disposal.
Usage: (with-api-context [ctx (new-api-context (api-request pw) {:base-url "https://api.example.com"})] (api-get ctx "/users"))
Binds a single APIRequestContext and ensures disposal.
Usage:
(with-api-context [ctx (new-api-context (api-request pw) {:base-url "https://api.example.com"})]
(api-get ctx "/users"))(with-api-contexts bindings & body)Binds multiple APIRequestContexts and disposes all on exit.
Same shape as with-open — flat pairs of [name expr].
Usage: (with-api-contexts [users (new-api-context (api-request pw) {:base-url "https://users.example.com" :extra-http-headers {"Authorization" "Bearer token"}}) billing (new-api-context (api-request pw) {:base-url "https://billing.example.com" :extra-http-headers {"X-API-Key" "key"}}) public (new-api-context (api-request pw) {:base-url "https://public.example.com"})] (api-get users "/me") (api-get billing "/invoices") (api-get public "/catalog"))
Binds multiple APIRequestContexts and disposes all on exit.
Same shape as `with-open` — flat pairs of [name expr].
Usage:
(with-api-contexts [users (new-api-context (api-request pw)
{:base-url "https://users.example.com"
:extra-http-headers {"Authorization" "Bearer token"}})
billing (new-api-context (api-request pw)
{:base-url "https://billing.example.com"
:extra-http-headers {"X-API-Key" "key"}})
public (new-api-context (api-request pw)
{:base-url "https://public.example.com"})]
(api-get users "/me")
(api-get billing "/invoices")
(api-get public "/catalog"))(with-browser [sym expr] & body)Binds a browser instance and ensures cleanup.
Usage: (with-browser [browser (launch-chromium pw)] (new-page browser))
Binds a browser instance and ensures cleanup. Usage: (with-browser [browser (launch-chromium pw)] (new-page browser))
(with-context [sym expr] & body)Binds a browser context and ensures cleanup.
Usage: (with-context [ctx (new-context browser)] (new-page-from-context ctx))
Binds a browser context and ensures cleanup. Usage: (with-context [ctx (new-context browser)] (new-page-from-context ctx))
(with-hooks hooks & body)Execute body with the given hooks merged into *hooks*.
Merges with (not replaces) any existing hooks so outer bindings are preserved for keys you don't override.
Usage: (with-hooks {:on-request (fn [m url opts] (log/info m url) opts) :on-response (fn [m url resp] (metrics/inc! :api-calls) resp)} (api-get ctx "/users") (api-post ctx "/users" {:json {:name "Alice"}}))
Execute body with the given hooks merged into `*hooks*`.
Merges with (not replaces) any existing hooks so outer bindings
are preserved for keys you don't override.
Usage:
(with-hooks {:on-request (fn [m url opts] (log/info m url) opts)
:on-response (fn [m url resp] (metrics/inc! :api-calls) resp)}
(api-get ctx "/users")
(api-post ctx "/users" {:json {:name "Alice"}}))(with-page [sym expr] & body)Binds a page instance and ensures cleanup.
Usage: (with-page [page (new-page browser)] (navigate page "https://example.com"))
Binds a page instance and ensures cleanup. Usage: (with-page [page (new-page browser)] (navigate page "https://example.com"))
(with-page-api pg opts binding-vec & body)Create an APIRequestContext from a Page with custom options.
Copies cookies from the page's browser context (via storage-state), creates a new APIRequestContext with the provided options, and disposes it after.
This lets you use a custom base-url while still sharing the browser's login session / cookies.
Params:
pg - Page instance (shares cookies from its browser context).
opts - Map of options for the new context:
:base-url - String. Base URL for all requests.
:extra-http-headers - Map. Headers sent with every request.
:ignore-https-errors - Boolean.
:json-encoder - Function. Binds *json-encoder* for the body.
Usage: ;; API calls to different domain, sharing browser cookies (with-testing-page [pg] (page/navigate pg "https://example.com/login") ;; ... login via UI ... (with-page-api pg {:base-url "https://api.example.com"} [ctx] ;; ctx has cookies from the browser session (api-get ctx "/me")))
;; With JSON encoder (with-page-api pg {:base-url "https://api.example.com" :json-encoder cheshire.core/generate-string} [ctx] (api-post ctx "/users" {:json {:name "Alice"}}))
Create an APIRequestContext from a Page with custom options.
Copies cookies from the page's browser context (via storage-state), creates
a new APIRequestContext with the provided options, and disposes it after.
This lets you use a custom base-url while still sharing the browser's
login session / cookies.
Params:
`pg` - Page instance (shares cookies from its browser context).
`opts` - Map of options for the new context:
:base-url - String. Base URL for all requests.
:extra-http-headers - Map. Headers sent with every request.
:ignore-https-errors - Boolean.
:json-encoder - Function. Binds `*json-encoder*` for the body.
Usage:
;; API calls to different domain, sharing browser cookies
(with-testing-page [pg]
(page/navigate pg "https://example.com/login")
;; ... login via UI ...
(with-page-api pg {:base-url "https://api.example.com"} [ctx]
;; ctx has cookies from the browser session
(api-get ctx "/me")))
;; With JSON encoder
(with-page-api pg {:base-url "https://api.example.com"
:json-encoder cheshire.core/generate-string} [ctx]
(api-post ctx "/users" {:json {:name "Alice"}}))(with-playwright binding-vec & body)Binds a Playwright instance and ensures cleanup.
Usage: (with-playwright [pw] ;; creates Playwright internally (launch-chromium pw)) (with-playwright [pw (create)] ;; uses provided expression (launch-chromium pw))
Binds a Playwright instance and ensures cleanup. Usage: (with-playwright [pw] ;; creates Playwright internally (launch-chromium pw)) (with-playwright [pw (create)] ;; uses provided expression (launch-chromium pw))
(with-retry opts-or-body & body)Execute body with retry logic.
Usage: ;; Default: 3 attempts, exponential backoff, retry on anomalies + 5xx (with-retry {} (api-get ctx "/flaky-endpoint"))
;; Custom retry config (with-retry {:max-attempts 5 :delay-ms 500 :backoff :linear :retry-when (fn [r] (and (map? r) (>= (:status r) 500)))} (api-post ctx "/idempotent-endpoint" {:json {:action "process"}}))
;; Retry standalone requests too (with-retry {:max-attempts 3} (request! pw :get "https://api.example.com/health"))
Execute body with retry logic.
Usage:
;; Default: 3 attempts, exponential backoff, retry on anomalies + 5xx
(with-retry {}
(api-get ctx "/flaky-endpoint"))
;; Custom retry config
(with-retry {:max-attempts 5
:delay-ms 500
:backoff :linear
:retry-when (fn [r] (and (map? r) (>= (:status r) 500)))}
(api-post ctx "/idempotent-endpoint"
{:json {:action "process"}}))
;; Retry standalone requests too
(with-retry {:max-attempts 3}
(request! pw :get "https://api.example.com/health"))(with-testing-api opts-or-binding & args)All-in-one macro for API testing with automatic resource management.
Creates a complete Playwright stack (playwright → browser → context),
extracts the context-bound APIRequestContext, binds it to sym,
executes body, and tears everything down.
The APIRequestContext comes from BrowserContext.request(), so all API
calls share cookies with the context and appear in Playwright traces.
When the Allure reporter is active, tracing (DOM snapshots + sources) and HAR recording are enabled automatically — zero configuration.
Opts (an optional map expression, evaluated at runtime):
:base-url - String. Base URL for all requests.
:extra-http-headers - Map. Headers sent with every request.
:ignore-https-errors - Boolean. Ignore SSL certificate errors.
:json-encoder - Function. Binds *json-encoder* for the body.
:storage-state - String. Storage state JSON or path.
new-context (:locale, :timezone-id, etc.)Usage: ;; Minimal — hit a base URL (with-testing-api {:base-url "https://api.example.com"} [ctx] (api-get ctx "/users"))
;; With custom headers and JSON encoder (with-testing-api {:base-url "https://api.example.com" :extra-http-headers {"Authorization" "Bearer token"} :json-encoder cheshire.core/generate-string} [ctx] (api-post ctx "/users" {:json {:name "Alice"}}))
;; Minimal — no opts (with-testing-api [ctx] (api-get ctx "https://api.example.com/health"))
All-in-one macro for API testing with automatic resource management.
Creates a complete Playwright stack (playwright → browser → context),
extracts the context-bound APIRequestContext, binds it to `sym`,
executes body, and tears everything down.
The APIRequestContext comes from `BrowserContext.request()`, so all API
calls share cookies with the context and appear in Playwright traces.
When the Allure reporter is active, tracing (DOM snapshots + sources)
and HAR recording are enabled automatically — zero configuration.
Opts (an optional map expression, evaluated at runtime):
:base-url - String. Base URL for all requests.
:extra-http-headers - Map. Headers sent with every request.
:ignore-https-errors - Boolean. Ignore SSL certificate errors.
:json-encoder - Function. Binds `*json-encoder*` for the body.
:storage-state - String. Storage state JSON or path.
+ any key accepted by `new-context` (:locale, :timezone-id, etc.)
Usage:
;; Minimal — hit a base URL
(with-testing-api {:base-url "https://api.example.com"} [ctx]
(api-get ctx "/users"))
;; With custom headers and JSON encoder
(with-testing-api {:base-url "https://api.example.com"
:extra-http-headers {"Authorization" "Bearer token"}
:json-encoder cheshire.core/generate-string} [ctx]
(api-post ctx "/users" {:json {:name "Alice"}}))
;; Minimal — no opts
(with-testing-api [ctx]
(api-get ctx "https://api.example.com/health"))(with-testing-page opts-or-binding & args)All-in-one macro for quick browser testing with automatic resource management.
Creates a complete Playwright stack (playwright → browser → context → page),
binds the page to sym, executes body, and tears everything down.
Two modes:
When the Allure reporter is active, automatically enables Playwright tracing (screenshots + DOM snapshots + network) and HAR recording — zero configuration.
Opts (an optional map expression, evaluated at runtime): :browser-type - :chromium (default), :firefox, or :webkit :headless - Boolean (default true) :slow-mo - Millis to slow down operations :device - Device preset keyword (e.g. :iphone-14, :pixel-7) :viewport - Viewport keyword (:mobile, :desktop-hd) or {:width :height} :profile - String. Path to persistent user data dir (Chrome profile). When set, uses launch-persistent-context instead of launch + new-context. :executable-path - String. Path to browser executable. :channel - String. Browser channel (e.g. "chrome", "msedge"). :proxy - Map with :server, :bypass, :username, :password. :args - Vector of additional browser args. :downloads-path - String. Path to download files. :timeout - Double. Max time in ms to wait for browser launch. :chromium-sandbox - Boolean. Enable Chromium sandbox.
new-context (:locale, :color-scheme, :timezone-id,
:storage-state, etc.)Usage: ;; Minimal — headless Chromium, default viewport (opts omitted) (with-testing-page [page] (page/navigate page "https://example.com") (page/title page))
;; With device emulation (with-testing-page {:device :iphone-14} [page] (page/navigate page "https://example.com"))
;; With viewport preset (with-testing-page {:viewport :desktop-hd :locale "fr-FR"} [page] (page/navigate page "https://example.com"))
;; Firefox, headed mode (with-testing-page {:browser-type :firefox :headless false} [page] (page/navigate page "https://example.com"))
;; Persistent profile (keeps login sessions across runs) (with-testing-page {:profile "/tmp/my-chrome-profile"} [page] (page/navigate page "https://example.com"))
;; Custom browser executable + extra args (with-testing-page {:executable-path "/usr/bin/chromium" :args ["--disable-gpu"]} [page] (page/navigate page "https://example.com"))
All-in-one macro for quick browser testing with automatic resource management.
Creates a complete Playwright stack (playwright → browser → context → page),
binds the page to `sym`, executes body, and tears everything down.
Two modes:
- **Normal** (no :profile): playwright → launch browser → new-context → page
- **Persistent** (:profile given): playwright → launch-persistent-context → page
Use :profile for persistent user data (login sessions, cookies, extensions).
When the Allure reporter is active, automatically enables Playwright tracing
(screenshots + DOM snapshots + network) and HAR recording — zero configuration.
Opts (an optional map expression, evaluated at runtime):
:browser-type - :chromium (default), :firefox, or :webkit
:headless - Boolean (default true)
:slow-mo - Millis to slow down operations
:device - Device preset keyword (e.g. :iphone-14, :pixel-7)
:viewport - Viewport keyword (:mobile, :desktop-hd) or {:width :height}
:profile - String. Path to persistent user data dir (Chrome profile).
When set, uses launch-persistent-context instead of launch + new-context.
:executable-path - String. Path to browser executable.
:channel - String. Browser channel (e.g. "chrome", "msedge").
:proxy - Map with :server, :bypass, :username, :password.
:args - Vector of additional browser args.
:downloads-path - String. Path to download files.
:timeout - Double. Max time in ms to wait for browser launch.
:chromium-sandbox - Boolean. Enable Chromium sandbox.
+ any key accepted by `new-context` (:locale, :color-scheme, :timezone-id,
:storage-state, etc.)
Usage:
;; Minimal — headless Chromium, default viewport (opts omitted)
(with-testing-page [page]
(page/navigate page "https://example.com")
(page/title page))
;; With device emulation
(with-testing-page {:device :iphone-14} [page]
(page/navigate page "https://example.com"))
;; With viewport preset
(with-testing-page {:viewport :desktop-hd :locale "fr-FR"} [page]
(page/navigate page "https://example.com"))
;; Firefox, headed mode
(with-testing-page {:browser-type :firefox :headless false} [page]
(page/navigate page "https://example.com"))
;; Persistent profile (keeps login sessions across runs)
(with-testing-page {:profile "/tmp/my-chrome-profile"} [page]
(page/navigate page "https://example.com"))
;; Custom browser executable + extra args
(with-testing-page {:executable-path "/usr/bin/chromium"
:args ["--disable-gpu"]} [page]
(page/navigate page "https://example.com"))(wrap-error e)Wraps Playwright exceptions into anomaly maps.
Includes the exception message, class, stack trace, and the original exception object for programmatic access.
Params:
e - Exception from Playwright.
Returns: Anomaly map with appropriate category.
Wraps Playwright exceptions into anomaly maps. Includes the exception message, class, stack trace, and the original exception object for programmatic access. Params: `e` - Exception from Playwright. Returns: Anomaly map with appropriate category.
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 |