Liking cljdoc? Tell your friends :D

com.blockether.spel.api

Playwright API testing — APIRequest, APIRequestContext, APIResponse.

Provides idiomatic Clojure wrappers for Playwright's built-in HTTP client. Supports all HTTP methods, form data, query params, custom headers, and lifecycle management via with-api-context.

Usage: (require '[com.blockether.spel.core :as pw] '[com.blockether.spel.api :as api])

(core/with-playwright [playwright] (api/with-api-context [ctx (-> playwright api/api-request (api/new-api-context {:base-url "https://api.example.com"}))] (let [resp (api/get ctx "/users" {:params {:page 1 :limit 10}})] (println (api/response->map resp)))))

;; Response map: ;; {:status 200 ;; :status-text "OK" ;; :url "https://api.example.com/users?page=1&limit=10" ;; :ok? true ;; :headers {"content-type" "application/json"} ;; :body "{...}"}

All HTTP methods accept either a RequestOptions object or a Clojure map:

(api/post ctx "/users" {:headers {"Content-Type" "application/json"} :data "{"name": "Alice"}" :timeout 5000})

(api/put ctx "/users/1" {:form (api/map->form-data {:name "Bob" :email "bob@example.com"})})

(api/delete ctx "/users/1")

Playwright API testing — APIRequest, APIRequestContext, APIResponse.

Provides idiomatic Clojure wrappers for Playwright's built-in HTTP client.
Supports all HTTP methods, form data, query params, custom headers, and
lifecycle management via `with-api-context`.

Usage:
(require '[com.blockether.spel.core :as pw]
         '[com.blockether.spel.api :as api])

(core/with-playwright [playwright]
  (api/with-api-context [ctx (-> playwright api/api-request
                                 (api/new-api-context {:base-url "https://api.example.com"}))]
    (let [resp (api/get ctx "/users" {:params {:page 1 :limit 10}})]
      (println (api/response->map resp)))))

;; Response map:
;; {:status 200
;;  :status-text "OK"
;;  :url "https://api.example.com/users?page=1&limit=10"
;;  :ok? true
;;  :headers {"content-type" "application/json"}
;;  :body "{...}"}

All HTTP methods accept either a RequestOptions object or a Clojure map:

(api/post ctx "/users"
  {:headers {"Content-Type" "application/json"}
   :data    "{\"name\": \"Alice\"}"
   :timeout 5000})

(api/put ctx "/users/1"
  {:form (api/map->form-data {:name "Bob" :email "bob@example.com"})})

(api/delete ctx "/users/1")
raw docstring

*hooks*clj

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 #'api/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 [api/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 #'api/*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 [api/*hooks* {:on-request (fn [_ _ opts]
                                     (update opts :headers
                                       assoc "Authorization" (str "Bearer " (get-token))))}]
  (api-get ctx "/protected"))
sourceraw docstring

*json-encoder*clj

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 [api/json-encoder cheshire.core/generate-string] (api/api-post ctx "/users" {:json {:name "Alice"}}))

;; charred (binding [api/json-encoder charred.api/write-json-str] (api/api-post ctx "/users" {:json {:name "Alice"}}))

;; jsonista (binding [api/json-encoder jsonista.core/write-value-as-string] (api/api-post ctx "/users" {:json {:name "Alice"}}))

;; Set globally for convenience (alter-var-root #'api/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 [api/*json-encoder* cheshire.core/generate-string]
  (api/api-post ctx "/users" {:json {:name "Alice"}}))

;; charred
(binding [api/*json-encoder* charred.api/write-json-str]
  (api/api-post ctx "/users" {:json {:name "Alice"}}))

;; jsonista
(binding [api/*json-encoder* jsonista.core/write-value-as-string]
  (api/api-post ctx "/users" {:json {:name "Alice"}}))

;; Set globally for convenience
(alter-var-root #'api/*json-encoder* (constantly cheshire.core/generate-string))
sourceraw docstring

api-deleteclj

(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.
sourceraw docstring

api-dispose!clj

(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.
sourceraw docstring

api-fetchclj

(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"})
sourceraw docstring

api-getclj

(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"}})
sourceraw docstring

api-headclj

(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.
sourceraw docstring

api-patchclj

(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.
sourceraw docstring

api-postclj

(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"})})
sourceraw docstring

api-putclj

(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.
sourceraw docstring

api-requestclj

(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.
sourceraw docstring

api-response->mapclj

(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\": [...]}"}
sourceraw docstring

api-response-bodyclj

(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.
sourceraw docstring

api-response-dispose!clj

(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.
sourceraw docstring

api-response-headersclj

(api-response-headers resp)

Returns the response headers. Passes through anomaly maps unchanged.

Returns the response headers.
Passes through anomaly maps unchanged.
sourceraw docstring

api-response-headers-arrayclj

(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.
sourceraw docstring

api-response-ok?clj

(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.
sourceraw docstring

api-response-statusclj

(api-response-status resp)

Returns the HTTP status code. Passes through anomaly maps unchanged.

Returns the HTTP status code.
Passes through anomaly maps unchanged.
sourceraw docstring

api-response-status-textclj

(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.
sourceraw docstring

api-response-textclj

(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.
sourceraw docstring

api-response-urlclj

(api-response-url resp)

Returns the response URL. Passes through anomaly maps unchanged.

Returns the response URL.
Passes through anomaly maps unchanged.
sourceraw docstring

context-apiclj

(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: (core/with-playwright [pw] (core/with-browser [browser (core/launch-chromium pw)] (core/with-context [ctx (core/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:
(core/with-playwright [pw]
  (core/with-browser [browser (core/launch-chromium pw)]
    (core/with-context [ctx (core/new-context browser {:base-url "https://api.example.com"})]
      (let [resp (api-get (context-api ctx) "/users")]
        (api-response-status resp)))))
sourceraw docstring

default-retry-optsclj

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.
sourceraw docstring

fd-appendclj

(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.
sourceraw docstring

fd-setclj

(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.
sourceraw docstring

form-dataclj

(form-data)

Creates a new FormData instance.

Returns: FormData instance.

Creates a new FormData instance.

Returns:
FormData instance.
sourceraw docstring

map->form-dataclj

(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.
sourceraw docstring

new-api-contextclj

(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})
sourceraw docstring

page-apiclj

(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: (core/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:
(core/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)))
sourceraw docstring

request!clj

(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])
sourceraw docstring

request-optionsclj

(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 [api/json-encoder cheshire.core/generate-string] (api/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 [api/*json-encoder* cheshire.core/generate-string]
    (api/api-post ctx "/users" {:json {:name "Alice" :age 30}}))

Returns:
RequestOptions instance.
sourceraw docstring

retryclj

(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))))})
sourceraw docstring

run-with-page-apiclj

(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")))
sourceraw docstring

run-with-testing-apiclj

(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.

  • any key accepted by core/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 `core/new-context` (:locale, :timezone-id, etc.)

Examples:
(run-with-testing-api {:base-url "https://api.example.com"}
  (fn [ctx]
    (api-get ctx "/users")))
sourceraw docstring

with-api-contextcljmacro

(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"))
sourceraw docstring

with-api-contextscljmacro

(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"))
sourceraw docstring

with-hookscljmacro

(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"}}))
sourceraw docstring

with-page-apicljmacro

(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"}}))
sourceraw docstring

with-retrycljmacro

(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"))
sourceraw docstring

with-testing-apicljmacro

(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.

  • any key accepted by core/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 `core/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"))
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close