Liking cljdoc? Tell your friends :D

com.blockether.spel.action-log

Pure functions for action log management and SRT subtitle generation.

The action log records user-facing browser commands with timestamps, enabling SRT subtitle export for video overlays. All functions are pure — no atoms, no side effects, no Playwright dependency.

Action entry shape: {:idx long ;; 1-based sequence number :timestamp long ;; epoch millis (System/currentTimeMillis) :action string ;; command name ("click", "navigate", etc.) :target string|nil ;; ref or selector ("@e12345") :args map|nil ;; additional arguments :session string|nil} ;; session name

SRT format: 1 00:00:01,200 --> 00:00:03,500 click @e12345

2 00:00:03,500 --> 00:00:05,800 fill @e67890 "search text"

Pure functions for action log management and SRT subtitle generation.

The action log records user-facing browser commands with timestamps,
enabling SRT subtitle export for video overlays. All functions are
pure — no atoms, no side effects, no Playwright dependency.

Action entry shape:
  {:idx       long          ;; 1-based sequence number
   :timestamp long          ;; epoch millis (System/currentTimeMillis)
   :action    string        ;; command name ("click", "navigate", etc.)
   :target    string|nil    ;; ref or selector ("@e12345")
   :args      map|nil       ;; additional arguments
   :session   string|nil}   ;; session name

SRT format:
  1
  00:00:01,200 --> 00:00:03,500
  click @e12345

  2
  00:00:03,500 --> 00:00:05,800
  fill @e67890 "search text"
raw docstring

com.blockether.spel.allure

In-test Allure API for enriching test reports with steps, metadata, screenshots, and attachments.

All functions are no-ops when *context* is nil, meaning they are safe to call even when not running under the Allure reporter.

Usage in tests:

(ns my-app.login-test (:require [com.blockether.spel.allure :as allure] [com.blockether.spel.page :as page] [com.blockether.spel.locator :as locator]))

(defdescribe login-flow (allure/epic "Authentication") (allure/feature "Login") (allure/severity :critical)

 (it "logs in with valid credentials"
   (allure/step "Navigate to login page"
     (page/navigate page "https://example.org/login"))
   (allure/step "Enter credentials"
     (allure/parameter "username" "admin")
     (locator/fill (locator/locator page "#username") "admin")
     (locator/fill (locator/locator page "#password") "secret"))
   (allure/step "Submit and verify"
     (locator/click (locator/locator page "button[type=submit]"))
     (allure/screenshot page "After login"))))
In-test Allure API for enriching test reports with steps, metadata,
screenshots, and attachments.

All functions are no-ops when `*context*` is nil, meaning they are
safe to call even when not running under the Allure reporter.

 Usage in tests:

   (ns my-app.login-test
     (:require [com.blockether.spel.allure :as allure]
               [com.blockether.spel.page :as page]
               [com.blockether.spel.locator :as locator]))

   (defdescribe login-flow
     (allure/epic "Authentication")
     (allure/feature "Login")
     (allure/severity :critical)

     (it "logs in with valid credentials"
       (allure/step "Navigate to login page"
         (page/navigate page "https://example.org/login"))
       (allure/step "Enter credentials"
         (allure/parameter "username" "admin")
         (locator/fill (locator/locator page "#username") "admin")
         (locator/fill (locator/locator page "#password") "secret"))
       (allure/step "Submit and verify"
         (locator/click (locator/locator page "button[type=submit]"))
         (allure/screenshot page "After login"))))
raw docstring

com.blockether.spel.allure-reporter

Allure 3 reporter for Lazytest with embedded Playwright trace viewer.

Writes JSON result files to allure-results/, then automatically generates the full HTML report to allure-report/ using Allure 3 CLI (prefers a global install, falls back to npx with pinned 3.3.1). The report embeds a local Playwright trace viewer so trace attachments load instantly without trace.playwright.dev.

Usage: clojure -M:test --output com.blockether.spel.allure-reporter/allure clojure -M:test --output nested --output com.blockether.spel.allure-reporter/allure

Output directory defaults to allure-results/. Override with: -Dlazytest.allure.output=path/to/dir LAZYTEST_ALLURE_OUTPUT=path/to/dir

Allure 3 reporter for Lazytest with embedded Playwright trace viewer.

Writes JSON result files to allure-results/, then automatically generates
the full HTML report to allure-report/ using Allure 3 CLI (prefers a global
install, falls back to npx with pinned 3.3.1). The report embeds a local
Playwright trace viewer so trace
attachments load instantly without trace.playwright.dev.

Usage:
  clojure -M:test --output com.blockether.spel.allure-reporter/allure
  clojure -M:test --output nested --output com.blockether.spel.allure-reporter/allure

Output directory defaults to allure-results/. Override with:
  -Dlazytest.allure.output=path/to/dir
  LAZYTEST_ALLURE_OUTPUT=path/to/dir
raw docstring

com.blockether.spel.annotate

Page annotation with ref labels, bounding boxes, and dimensions.

Injects CSS overlays directly into the page DOM. Overlays persist until explicitly removed with remove-overlays!. No AWT dependency — works in GraalVM native-image without any java.awt configuration.

Usage: (def snap (snapshot/capture-snapshot page)) (inject-overlays! page (:refs snap)) ;; overlays now visible on page ;; ... inspect, screenshot, etc. ... (remove-overlays! page) ;; clean up

Page annotation with ref labels, bounding boxes, and dimensions.

Injects CSS overlays directly into the page DOM. Overlays persist until
explicitly removed with `remove-overlays!`. No AWT dependency — works in
GraalVM native-image without any java.awt configuration.

Usage:
  (def snap (snapshot/capture-snapshot page))
  (inject-overlays! page (:refs snap))   ;; overlays now visible on page
  ;; ... inspect, screenshot, etc. ...
  (remove-overlays! page)                ;; clean up
raw docstring

com.blockether.spel.assertions

Playwright test assertions - LocatorAssertions, PageAssertions, APIResponseAssertions.

Entry point is assert-that which returns the appropriate assertions object for the given Playwright type. Chain with assertion functions and use not- variants for negation.

All assertion functions wrap calls in safe to return anomaly maps on assertion failure rather than throwing.

Playwright test assertions - LocatorAssertions, PageAssertions,
APIResponseAssertions.

Entry point is `assert-that` which returns the appropriate assertions
object for the given Playwright type. Chain with assertion functions
and use `not-` variants for negation.

All assertion functions wrap calls in `safe` to return anomaly maps
on assertion failure rather than throwing.
raw docstring

com.blockether.spel.ci

CI utilities for assembling Allure report sites.

Replaces Python scripts in GitHub Actions workflow with native Clojure.

Usage: spel ci-assemble --help spel ci-assemble --site-dir=gh-pages-site --run=123 ...

CI utilities for assembling Allure report sites.

Replaces Python scripts in GitHub Actions workflow with native Clojure.

Usage:
  spel ci-assemble --help
  spel ci-assemble --site-dir=gh-pages-site --run=123 ...
raw docstring

com.blockether.spel.cli

CLI client for the spel daemon.

Parses command-line arguments into JSON commands, sends them to the daemon over a Unix domain socket, and pretty-prints the results.

If the daemon isn't running, it auto-starts one in the background.

Usage: spel open https://example.org spel snapshot spel click @ref spel fill @ref "search text" spel screenshot shot.png spel close

CLI client for the spel daemon.

Parses command-line arguments into JSON commands, sends them to the
daemon over a Unix domain socket, and pretty-prints the results.

If the daemon isn't running, it auto-starts one in the background.

Usage:
  spel open https://example.org
  spel snapshot
  spel click @ref
  spel fill @ref "search text"
  spel screenshot shot.png
  spel close
raw docstring

com.blockether.spel.codegen

Transforms Playwright JSONL recordings into idiomatic Clojure test code.

Reads JSONL produced by playwright codegen --target=jsonl and emits Clojure code using the com.blockether.spel API.

Two usage modes:

A) Library:

(set! warn-on-reflection true)

  (require '[com.blockether.spel.codegen :as codegen])
  (codegen/jsonl->clojure "recording.jsonl")
  (codegen/jsonl-str->clojure jsonl-string {:format :script})

B) CLI: clojure -M -m com.blockether.spel.codegen recording.jsonl clojure -M -m com.blockether.spel.codegen --format=script recording.jsonl cat recording.jsonl | clojure -M -m com.blockether.spel.codegen

Workflow: clojure -M -m com.blockether.spel.cli codegen --target=jsonl -o recording.jsonl https://example.org clojure -M -m com.blockether.spel.codegen recording.jsonl > test/my_test.clj

Any unrecognized action, unsupported signal, or unimplemented feature causes an IMMEDIATE hard error with details about what failed.

Transforms Playwright JSONL recordings into idiomatic Clojure test code.

   Reads JSONL produced by `playwright codegen --target=jsonl` and emits
   Clojure code using the com.blockether.spel API.

   Two usage modes:

   A) Library:

(set! *warn-on-reflection* true)

      (require '[com.blockether.spel.codegen :as codegen])
      (codegen/jsonl->clojure "recording.jsonl")
      (codegen/jsonl-str->clojure jsonl-string {:format :script})

   B) CLI:
      clojure -M -m com.blockether.spel.codegen recording.jsonl
      clojure -M -m com.blockether.spel.codegen --format=script recording.jsonl
      cat recording.jsonl | clojure -M -m com.blockether.spel.codegen

   Workflow:
      clojure -M -m com.blockether.spel.cli codegen --target=jsonl -o recording.jsonl https://example.org
      clojure -M -m com.blockether.spel.codegen recording.jsonl > test/my_test.clj

   Any unrecognized action, unsupported signal, or unimplemented feature
   causes an IMMEDIATE hard error with details about what failed.
raw docstring

com.blockether.spel.config

Config file loader for spel.json — agent-browser parity.

Layered precedence (lowest → highest):

  1. ~/.spel/config.json (user-level defaults)
  2. ./spel.json (project-level overrides)
  3. SPEL_* environment vars (shell overrides)
  4. CLI flags (explicit per-invocation)

Config values use camelCase keys (headed, userAgent, allowedDomains) and are normalized to the same kebab-case keywords the CLI flag parser already uses, so a single merged map feeds both layers.

Unknown keys are silently ignored for forward compatibility. The extensions array merges by concatenation (user + project) rather than replacement so you can add project extensions on top of your user config.

Config file loader for `spel.json` — agent-browser parity.

Layered precedence (lowest → highest):
  1. `~/.spel/config.json`      (user-level defaults)
  2. `./spel.json`              (project-level overrides)
  3. `SPEL_*` environment vars  (shell overrides)
  4. CLI flags                  (explicit per-invocation)

Config values use camelCase keys (`headed`, `userAgent`, `allowedDomains`)
and are normalized to the same kebab-case keywords the CLI flag parser
already uses, so a single merged map feeds both layers.

Unknown keys are silently ignored for forward compatibility. The
`extensions` array merges by concatenation (user + project) rather than
replacement so you can add project extensions on top of your user config.
raw docstring

com.blockether.spel.constants

Clojure vars wrapping Playwright enum values as flat, documented names.

Eliminates the need for Java enum interop in eval-sci mode. Flat naming: constants/<category>-<value>.

Usage: (require '[com.blockether.spel.constants :as constants]) (page/wait-for-load-state pg constants/load-state-networkidle) (page/navigate pg url {:wait-until constants/wait-until-commit})

Clojure vars wrapping Playwright enum values as flat, documented names.

Eliminates the need for Java enum interop in eval-sci mode.
Flat naming: `constants/<category>-<value>`.

Usage:
  (require '[com.blockether.spel.constants :as constants])
  (page/wait-for-load-state pg constants/load-state-networkidle)
  (page/navigate pg url {:wait-until constants/wait-until-commit})
raw docstring

com.blockether.spel.core

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.org") (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.org")
      (text-content page "h1"))))

All operations return anomaly maps on failure instead of throwing exceptions.
raw docstring

com.blockether.spel.daemon

Background daemon that keeps a Playwright browser alive between CLI calls.

Listens on a Unix domain socket for JSON commands, executes them against the browser, and returns JSON responses. Each command is one JSON line; each response is one JSON line.

Usage: (start-daemon! {:session "default" :headless true}) ;; blocks (daemon-running? "default") ;; check (stop-daemon!) ;; cleanup

Background daemon that keeps a Playwright browser alive between CLI calls.

Listens on a Unix domain socket for JSON commands, executes them against
the browser, and returns JSON responses. Each command is one JSON line;
each response is one JSON line.

Usage:
  (start-daemon! {:session "default" :headless true})   ;; blocks
  (daemon-running? "default")                           ;; check
  (stop-daemon!)                                         ;; cleanup
raw docstring

com.blockether.spel.dashboard

Embedded HTTP server for the spel Observability Dashboard.

Serves a single-page web UI that shows live browser state: viewport screenshot, action log, console messages, and uncaught errors.

Uses only JDK built-in com.sun.net.httpserver — no external deps, GraalVM native-image safe.

Usage: (start-dashboard! 4848 state-fn) ;; starts HTTP server (stop-dashboard!) ;; stops it (dashboard-running?) ;; status check

Embedded HTTP server for the spel Observability Dashboard.

Serves a single-page web UI that shows live browser state: viewport
screenshot, action log, console messages, and uncaught errors.

Uses only JDK built-in com.sun.net.httpserver — no external deps,
GraalVM native-image safe.

Usage:
  (start-dashboard! 4848 state-fn)  ;; starts HTTP server
  (stop-dashboard!)                  ;; stops it
  (dashboard-running?)              ;; status check
raw docstring

com.blockether.spel.data

Datafy/nav extensions for Playwright Java objects.

Require this namespace to enable clojure.core.protocols/Datafiable for key Playwright classes. After requiring, (clojure.datafy/datafy obj) returns a Clojure map representation of the object.

Datafied classes:

  • Page, Browser, BrowserContext, BrowserType
  • Request, Response, APIResponse
  • ConsoleMessage, Download, WebError, WebSocketFrame, Worker
  • ElementHandle, Locator (basic info)
  • PlaywrightException, TimeoutError
Datafy/nav extensions for Playwright Java objects.

Require this namespace to enable `clojure.core.protocols/Datafiable`
for key Playwright classes. After requiring, `(clojure.datafy/datafy obj)`
returns a Clojure map representation of the object.

Datafied classes:
- Page, Browser, BrowserContext, BrowserType
- Request, Response, APIResponse
- ConsoleMessage, Download, WebError, WebSocketFrame, Worker
- ElementHandle, Locator (basic info)
- PlaywrightException, TimeoutError
raw docstring

No vars found in this namespace.

com.blockether.spel.devices

Device and viewport presets for browser context emulation.

Provides keyword-based device presets (e.g. :iphone-14, :pixel-7) and viewport presets (e.g. :desktop-hd, :tablet, :mobile) that can be used with with-testing-page and new-context options.

Each device preset includes: viewport dimensions, device-scale-factor, is-mobile, has-touch, and user-agent string.

Viewport presets are simpler — just :width and :height.

Device and viewport presets for browser context emulation.

Provides keyword-based device presets (e.g. `:iphone-14`, `:pixel-7`)
and viewport presets (e.g. `:desktop-hd`, `:tablet`, `:mobile`) that
can be used with `with-testing-page` and `new-context` options.

Each device preset includes: viewport dimensions, device-scale-factor,
is-mobile, has-touch, and user-agent string.

Viewport presets are simpler — just :width and :height.
raw docstring

com.blockether.spel.driver

External Playwright driver management for native-image builds.

Instead of bundling Playwright's ~600MB Node.js driver in the native binary, this module downloads and caches it on first use.

Cache: ~/.cache/spel/<version>/<platform>/ CDN: https://cdn.playwright.dev/builds/driver/playwright-<version>-<platform>.zip

Configuration (checked in order):

  1. playwright.cli.dir system property — points to pre-installed driver dir
  2. SPEL_DRIVER_DIR env var — overrides cache location
  3. Default: ~/.cache/spel/<version>/<platform>/
External Playwright driver management for native-image builds.

Instead of bundling Playwright's ~600MB Node.js driver in the native binary,
this module downloads and caches it on first use.

 Cache:  ~/.cache/spel/<version>/<platform>/
 CDN:    https://cdn.playwright.dev/builds/driver/playwright-<version>-<platform>.zip

 Configuration (checked in order):
   1. playwright.cli.dir system property — points to pre-installed driver dir
   2. SPEL_DRIVER_DIR env var — overrides cache location
   3. Default: ~/.cache/spel/<version>/<platform>/
raw docstring

com.blockether.spel.gen-docs

Generates API reference markdown from source code introspection.

Three categories of API docs:

  1. Library API — public vars from all spel namespaces
  2. SCI eval API — functions available in spel eval-sci mode
  3. CLI commands — commands available via the spel binary

Usage: clojure -T:build gen-docs make gen-docs

Generates API reference markdown from source code introspection.

Three categories of API docs:
1. Library API — public vars from all spel namespaces
2. SCI eval API — functions available in `spel eval-sci` mode
3. CLI commands — commands available via the `spel` binary

Usage:
  clojure -T:build gen-docs
  make gen-docs
raw docstring

com.blockether.spel.helpers

High-level agent helpers — opinionated one-shot commands that replace multi-step agent workflows with deterministic, correct-by-default operations.

These functions compose lower-level primitives (screenshot, scroll, snapshot, annotate, evaluate) into the operations AI agents need most often but get wrong when composing manually.

All functions take an explicit Page argument (library layer). SCI wrappers in sci_env.clj provide implicit-page versions.

High-level agent helpers — opinionated one-shot commands that replace
multi-step agent workflows with deterministic, correct-by-default operations.

These functions compose lower-level primitives (screenshot, scroll, snapshot,
annotate, evaluate) into the operations AI agents need most often but get wrong
when composing manually.

All functions take an explicit Page argument (library layer).
SCI wrappers in sci_env.clj provide implicit-page versions.
raw docstring

com.blockether.spel.init-agents

CLI command to scaffold agent definitions for E2E testing.

Supports multiple agent loop targets via --loop:

  • opencode (default) — .opencode/agents/, .opencode/prompts/, .opencode/skills/
  • claude — .claude/agents/, .claude/prompts/, .claude/docs/

Supports test framework flavours via --flavour:

  • lazytest (default) — defdescribe/it/expect from spel.allure, :context fixtures
  • clojure-test — deftest/testing/is from clojure.test, use-fixtures

Also generates:

  • test-e2e/<ns>/e2e/ — seed test (path derived from --ns)

Usage: spel init-agents --ns my-app spel init-agents --ns my-app --loop=claude spel init-agents --ns my-app --flavour=clojure-test spel init-agents --ns my-app --no-tests spel init-agents --ns my-app --test-dir test-e2e spel init-agents --dry-run

CLI command to scaffold agent definitions for E2E testing.

Supports multiple agent loop targets via --loop:
- opencode (default) — .opencode/agents/, .opencode/prompts/, .opencode/skills/
- claude             — .claude/agents/, .claude/prompts/, .claude/docs/

Supports test framework flavours via --flavour:
- lazytest (default) — defdescribe/it/expect from spel.allure, :context fixtures
- clojure-test       — deftest/testing/is from clojure.test, use-fixtures

Also generates:
- test-e2e/<ns>/e2e/ — seed test (path derived from --ns)

Usage:
  spel init-agents --ns my-app
  spel init-agents --ns my-app --loop=claude
  spel init-agents --ns my-app --flavour=clojure-test
  spel init-agents --ns my-app --no-tests
  spel init-agents --ns my-app --test-dir test-e2e
  spel init-agents --dry-run
raw docstring

com.blockether.spel.junit-reporter

JUnit XML reporter for Lazytest.

Produces JUnit XML output fully compliant with the Apache Ant JUnit schema (https://github.com/windyroad/JUnit-Schema) and compatible with CI systems: GitHub Actions, Jenkins, GitLab CI.

Usage: clojure -M:test --output com.blockether.spel.junit-reporter/junit clojure -M:test --output nested --output com.blockether.spel.junit-reporter/junit

Output file defaults to test-results/junit.xml. Override with: -Dlazytest.junit.output=path/to/output.xml LAZYTEST_JUNIT_OUTPUT=path/to/output.xml

JUnit XML reporter for Lazytest.

Produces JUnit XML output fully compliant with the Apache Ant JUnit
schema (https://github.com/windyroad/JUnit-Schema) and compatible
with CI systems: GitHub Actions, Jenkins, GitLab CI.

Usage:
  clojure -M:test --output com.blockether.spel.junit-reporter/junit
  clojure -M:test --output nested --output com.blockether.spel.junit-reporter/junit

Output file defaults to test-results/junit.xml. Override with:
  -Dlazytest.junit.output=path/to/output.xml
  LAZYTEST_JUNIT_OUTPUT=path/to/output.xml
raw docstring

com.blockether.spel.leveldb

Minimal read-only LevelDB parser for Chrome's localStorage.

Reads .log (WAL) and .ldb (SSTable) files from a LevelDB directory, returning raw key-value records with sequence numbers and state.

Implements:

  • Log file parsing (32KB blocks with CRC32/length/type headers)
  • SSTable parsing (footer, index, data blocks with prefix compression)
  • Snappy decompression (pure Java, no native dependencies)
  • Varint encoding (protobuf-style little-endian varints)

Reference: https://github.com/google/leveldb/blob/master/doc/ Based on: ccl_chromium_reader by CCL Forensics (MIT license)

Minimal read-only LevelDB parser for Chrome's localStorage.

Reads .log (WAL) and .ldb (SSTable) files from a LevelDB directory,
returning raw key-value records with sequence numbers and state.

Implements:
- Log file parsing (32KB blocks with CRC32/length/type headers)
- SSTable parsing (footer, index, data blocks with prefix compression)
- Snappy decompression (pure Java, no native dependencies)
- Varint encoding (protobuf-style little-endian varints)

Reference: https://github.com/google/leveldb/blob/master/doc/
Based on: ccl_chromium_reader by CCL Forensics (MIT license)
raw docstring

com.blockether.spel.markdown

Parse and generate GitHub-flavored markdown tables.

Converts between markdown table strings and Clojure data:

  • from-markdown-table : markdown string → vector of maps
  • to-markdown-table : vector of maps → markdown string

Useful in eval-sci scripts for processing tabular data from web pages, API responses, or LLM output.

Parse and generate GitHub-flavored markdown tables.

Converts between markdown table strings and Clojure data:
- `from-markdown-table` : markdown string → vector of maps
- `to-markdown-table`   : vector of maps → markdown string

Useful in eval-sci scripts for processing tabular data from web pages,
API responses, or LLM output.
raw docstring

com.blockether.spel.markdownify

Convert HTML documents into readable Markdown using the browser runtime.

Convert HTML documents into readable Markdown using the browser runtime.
raw docstring

com.blockether.spel.native

Native-image entry point for spel.

Provides a CLI tool (spel) for browser automation with persistent browser sessions.

Modes:

  • CLI commands (default): Send commands to the browser process
  • Eval: Evaluate a Clojure expression and exit

Usage: spel open https://example.org # Navigate (auto-starts browser) spel snapshot # ARIA snapshot with refs spel click @ref # Click by ref spel fill @ref "search text" # Fill input by ref spel screenshot shot.png # Take screenshot spel close # Close browser spel eval-sci '(+ 1 2)' # Evaluate and exit spel install # Install Playwright browsers spel --help # Show help

Native-image entry point for spel.

Provides a CLI tool (spel) for browser automation with persistent browser sessions.

Modes:
- CLI commands (default): Send commands to the browser process
- Eval: Evaluate a Clojure expression and exit

Usage:
  spel open https://example.org   # Navigate (auto-starts browser)
  spel snapshot                    # ARIA snapshot with refs
  spel click @ref                  # Click by ref
  spel fill @ref "search text" # Fill input by ref
  spel screenshot shot.png         # Take screenshot
  spel close                       # Close browser
  spel eval-sci '(+ 1 2)'            # Evaluate and exit
  spel install                     # Install Playwright browsers
  spel --help                      # Show help
raw docstring

com.blockether.spel.network

Request, Response, Route, WebSocket operations.

All response and request accessor functions participate in the anomaly railway pattern: if passed an anomaly map (e.g. from a failed navigate), they pass it through unchanged instead of throwing ClassCastException.

Request, Response, Route, WebSocket operations.

All response and request accessor functions participate in the anomaly
railway pattern: if passed an anomaly map (e.g. from a failed navigate),
they pass it through unchanged instead of throwing ClassCastException.
raw docstring

com.blockether.spel.options

Option map to Playwright Java options object conversion.

Converts idiomatic Clojure maps to Playwright's typed option objects. All functions use reflection-free type hints.

Option map to Playwright Java options object conversion.

Converts idiomatic Clojure maps to Playwright's typed option objects.
All functions use reflection-free type hints.
raw docstring

com.blockether.spel.page

Page operations - navigation, content, evaluation, screenshots, events, and utility classes (Dialog, Download, ConsoleMessage, Clock, FileChooser, Worker, WebError). The Page class is the central API surface of Playwright. Wraps all Page methods with idiomatic Clojure functions.

Page operations - navigation, content, evaluation, screenshots,
events, and utility classes (Dialog, Download, ConsoleMessage,
Clock, FileChooser, Worker, WebError).
The Page class is the central API surface of Playwright. Wraps all
Page methods with idiomatic Clojure functions.
raw docstring

com.blockether.spel.platform

Platform detection and CDP discovery utilities. Pure functions with no dependency on daemon state, browser sessions, or SCI context.

Extracted from daemon.clj to break the circular dependency between sci_env.clj (which needs WSL + CDP functions for the spel namespace) and daemon.clj (which requires sci_env.clj for evaluation).

Both daemon.clj and sci_env.clj can safely require this namespace.

Platform detection and CDP discovery utilities. Pure functions with
no dependency on daemon state, browser sessions, or SCI context.

Extracted from daemon.clj to break the circular dependency between
sci_env.clj (which needs WSL + CDP functions for the spel namespace)
and daemon.clj (which requires sci_env.clj for evaluation).

Both daemon.clj and sci_env.clj can safely require this namespace.
raw docstring

com.blockether.spel.profile

Chrome/Chromium user-profile lookup and cloning for --profile <name>.

Matches the semantics of vercel-labs/agent-browser:

  1. Three-tier resolution of the user-supplied string to an on-disk profile directory (exact match → case-insensitive display name → case-insensitive directory name). Ambiguous display-name matches raise an error.

  2. Selective copy to a fresh temp user-data directory. Large cache/non-auth subdirectories are skipped (e.g. Cache, Code Cache, GPUCache, Service Worker) because they are not needed for login-state reuse and would bloat the copy by hundreds of MB. See exclude-dirs.

  3. The clone function returns BOTH the temp user-data dir path AND the resolved profile directory name. The caller is responsible for passing --profile-directory=<dir> to Chrome so it picks the right profile from the cloned user-data dir (without this, Chrome always defaults to Default and ignores other profiles in the clone).

Platform-specific Chrome user-data roots: macOS ~/Library/Application Support/Google/Chrome Linux ~/.config/google-chrome Windows %LOCALAPPDATA%/Google/Chrome/User Data

Chrome/Chromium user-profile lookup and cloning for `--profile <name>`.

Matches the semantics of vercel-labs/agent-browser:

1. Three-tier resolution of the user-supplied string to an on-disk profile
   directory (exact match → case-insensitive display name → case-insensitive
   directory name). Ambiguous display-name matches raise an error.

2. Selective copy to a fresh temp user-data directory. Large cache/non-auth
   subdirectories are skipped (e.g. `Cache`, `Code Cache`, `GPUCache`,
   `Service Worker`) because they are not needed for login-state reuse and
   would bloat the copy by hundreds of MB. See `exclude-dirs`.

3. The clone function returns BOTH the temp user-data dir path AND the
   resolved profile directory name. The caller is responsible for passing
   `--profile-directory=<dir>` to Chrome so it picks the right profile from
   the cloned user-data dir (without this, Chrome always defaults to
   `Default` and ignores other profiles in the clone).

Platform-specific Chrome user-data roots:
  macOS   ~/Library/Application Support/Google/Chrome
  Linux   ~/.config/google-chrome
  Windows %LOCALAPPDATA%/Google/Chrome/User Data
raw docstring

com.blockether.spel.roles

Clojure vars wrapping Playwright's AriaRole enum values.

Eliminates the need for (:import [com.microsoft.playwright.options AriaRole]).

Usage: (require '[com.blockether.spel.roles :as role]) (page/get-by-role pg role/button) (page/get-by-role pg role/heading {:name "Title"})

Clojure vars wrapping Playwright's AriaRole enum values.

Eliminates the need for `(:import [com.microsoft.playwright.options AriaRole])`.

Usage:
  (require '[com.blockether.spel.roles :as role])
  (page/get-by-role pg role/button)
  (page/get-by-role pg role/heading {:name "Title"})
raw docstring

com.blockether.spel.sci-env

SCI (Small Clojure Interpreter) environment for native-image REPL.

Registers all spel functions as SCI namespaces so they can be evaluated in a native-image compiled REPL without JVM startup.

The SCI context wraps a stateful Playwright session with managed atoms for the Playwright, Browser, BrowserContext, and Page instances.

Namespaces available in eval-sci mode: spel/ - Simplified API (implicit page/context from atoms) snapshot/ - Accessibility snapshot capture annotate/ - Screenshot annotation input/ - Keyboard, Mouse, Touchscreen (raw pass-throughs) frame/ - Frame and FrameLocator operations (raw pass-throughs) net/ - Network request/response/route (raw pass-throughs) loc/ - Locator operations (raw pass-throughs, explicit Locator arg) assert/ - Assertion functions (raw pass-throughs, explicit assertion obj) core/ - Lifecycle stubs + utility pass-throughs

Usage: (def ctx (create-sci-ctx)) (eval-string ctx "(spel/start!)") (eval-string ctx "(spel/navigate "https://example.org")") (eval-string ctx "(spel/capture-snapshot)") (eval-string ctx "(spel/stop!)")

SCI (Small Clojure Interpreter) environment for native-image REPL.

Registers all spel functions as SCI namespaces so they
can be evaluated in a native-image compiled REPL without JVM startup.

The SCI context wraps a stateful Playwright session with managed
atoms for the Playwright, Browser, BrowserContext, and Page instances.

 Namespaces available in eval-sci mode:
   spel/     - Simplified API (implicit page/context from atoms)
  snapshot/ - Accessibility snapshot capture
  annotate/ - Screenshot annotation
  input/    - Keyboard, Mouse, Touchscreen (raw pass-throughs)
  frame/    - Frame and FrameLocator operations (raw pass-throughs)
  net/      - Network request/response/route (raw pass-throughs)
  loc/      - Locator operations (raw pass-throughs, explicit Locator arg)
  assert/   - Assertion functions (raw pass-throughs, explicit assertion obj)
  core/     - Lifecycle stubs + utility pass-throughs

Usage:
  (def ctx (create-sci-ctx))
   (eval-string ctx "(spel/start!)")
   (eval-string ctx "(spel/navigate \"https://example.org\")")
   (eval-string ctx "(spel/capture-snapshot)")
   (eval-string ctx "(spel/stop!)")
raw docstring

com.blockether.spel.search

Google Search automation using Playwright.

Provides functions for searching Google, extracting results, handling pagination, and supporting web, image, and news search types — all without any API key. Uses Playwright browser automation to navigate Google Search and extract structured data from the results pages.

Library functions take a Page as the first argument. The -main entry point provides a standalone CLI tool.

Usage (library): (search! page "clojure programming") (search! page "cats" {:type :images}) (next-page! page) (search-and-collect! page "clojure" {:max-pages 3})

Usage (CLI): spel search "clojure programming" spel search "cats" --images spel search "news topic" --news --json spel search "query" --page 2 --num 20

Google Search automation using Playwright.

Provides functions for searching Google, extracting results, handling
pagination, and supporting web, image, and news search types — all
without any API key. Uses Playwright browser automation to navigate
Google Search and extract structured data from the results pages.

Library functions take a Page as the first argument.
The -main entry point provides a standalone CLI tool.

Usage (library):
  (search! page "clojure programming")
  (search! page "cats" {:type :images})
  (next-page! page)
  (search-and-collect! page "clojure" {:max-pages 3})

Usage (CLI):
  spel search "clojure programming"
  spel search "cats" --images
  spel search "news topic" --news --json
  spel search "query" --page 2 --num 20
raw docstring

com.blockether.spel.security

Security helpers for agent-safe browser deployments.

Three independent, opt-in features:

  1. Domain allowlist — restrict navigation and sub-resource fetches to a list of trusted domains. Used by the daemon at context creation time. *.example.com wildcards match example.com AND any subdomain.

  2. Content boundaries — wrap tool output in XML-style delimiters so downstream LLMs can distinguish trusted tool output from untrusted page content. Mitigates prompt-injection from malicious page text.

  3. Max output truncation — cap tool output at N characters to protect the agent's context window from runaway pages (e.g., a 2MB snapshot).

All functions are pure and side-effect free. Used by cli (print-result wrapping + truncation) and daemon (route handler for allowed-domains).

Security helpers for agent-safe browser deployments.

Three independent, opt-in features:

1. **Domain allowlist** — restrict navigation and sub-resource fetches to
   a list of trusted domains. Used by the daemon at context creation time.
   `*.example.com` wildcards match `example.com` AND any subdomain.

2. **Content boundaries** — wrap tool output in XML-style delimiters so
   downstream LLMs can distinguish trusted tool output from untrusted page
   content. Mitigates prompt-injection from malicious page text.

3. **Max output truncation** — cap tool output at N characters to protect
   the agent's context window from runaway pages (e.g., a 2MB snapshot).

All functions are pure and side-effect free. Used by `cli` (print-result
wrapping + truncation) and `daemon` (route handler for allowed-domains).
raw docstring

com.blockether.spel.snapshot

Accessibility snapshot with content-hash stable refs.

Walks the DOM tree via JavaScript injection and builds a YAML-like accessibility tree with content-hash refs (deterministic across page states). Elements are tagged with data-pw-ref attributes for later interaction.

Usage: (def snap (capture-snapshot page)) (:tree snap) ;; YAML-like string with [@eXXXXX] annotations (:refs snap) ;; {ref-id {:role :name :tag :bbox} ...} (resolve-ref page ref-id) ;; returns Locator for the element

Accessibility snapshot with content-hash stable refs.

Walks the DOM tree via JavaScript injection and builds a YAML-like
accessibility tree with content-hash refs (deterministic across page states).
Elements are tagged with `data-pw-ref` attributes for later interaction.

Usage:
  (def snap (capture-snapshot page))
  (:tree snap)      ;; YAML-like string with [@eXXXXX] annotations
  (:refs snap)      ;; {ref-id {:role :name :tag :bbox} ...}
  (resolve-ref page ref-id) ;; returns Locator for the element
raw docstring

com.blockether.spel.spel-allure-alternative-html-report

Blockether Allure report renderer. Reads allure-results/ JSON files and generates a standalone HTML report with a clean neutral palette, search, sorting, compact investigation-first layout, and shared attachment UX reused from the standard Allure report helpers.

Blockether Allure report renderer.
Reads allure-results/ JSON files and generates a standalone HTML report
with a clean neutral palette, search, sorting, compact investigation-first
layout, and shared attachment UX reused from the standard Allure report
helpers.
raw docstring

com.blockether.spel.ssl

Custom SSL/TLS certificate support for corporate proxy environments.

When spel install downloads the Playwright driver from cdn.playwright.dev, GraalVM native-image uses a TrustStore baked at build time. Corporate SSL-inspecting proxies use internal CAs not in that store, causing 'PKIX path building failed'.

This namespace provides a composite TrustManager that merges the built-in default CAs with user-provided certificates (PEM or JKS/PKCS12), so both public CDN certs and corporate certs are trusted.

Environment variables (checked in order): SPEL_CA_BUNDLE — PEM file with extra CA certs (merged with defaults) NODE_EXTRA_CA_CERTS — same as above, also respected by Node.js subprocess SPEL_TRUSTSTORE — JKS/PKCS12 truststore path (merged with defaults) SPEL_TRUSTSTORE_TYPE — truststore type (default: JKS) SPEL_TRUSTSTORE_PASSWORD — truststore password (default: empty)

Custom SSL/TLS certificate support for corporate proxy environments.

When `spel install` downloads the Playwright driver from cdn.playwright.dev,
GraalVM native-image uses a TrustStore baked at build time. Corporate
SSL-inspecting proxies use internal CAs not in that store, causing
'PKIX path building failed'.

This namespace provides a composite TrustManager that merges the built-in
default CAs with user-provided certificates (PEM or JKS/PKCS12), so both
public CDN certs and corporate certs are trusted.

Environment variables (checked in order):
  SPEL_CA_BUNDLE           — PEM file with extra CA certs (merged with defaults)
  NODE_EXTRA_CA_CERTS      — same as above, also respected by Node.js subprocess
  SPEL_TRUSTSTORE          — JKS/PKCS12 truststore path (merged with defaults)
  SPEL_TRUSTSTORE_TYPE     — truststore type (default: JKS)
  SPEL_TRUSTSTORE_PASSWORD — truststore password (default: empty)
raw docstring

com.blockether.spel.stealth

Stealth mode for browser automation anti-detection.

Provides Chrome launch arguments, default-arg suppressions, and JavaScript init scripts that hide Playwright/automation signals from bot-detection systems. Based on puppeteer-extra-plugin-stealth evasions.

Usage: (stealth-args) ;; Chrome launch args (stealth-ignore-default-args) ;; args to suppress (stealth-init-script) ;; JS evasion script for addInitScript

Stealth mode for browser automation anti-detection.

Provides Chrome launch arguments, default-arg suppressions, and JavaScript
init scripts that hide Playwright/automation signals from bot-detection
systems. Based on puppeteer-extra-plugin-stealth evasions.

Usage:
  (stealth-args)                ;; Chrome launch args
  (stealth-ignore-default-args) ;; args to suppress
  (stealth-init-script)         ;; JS evasion script for addInitScript
raw docstring

com.blockether.spel.stitch

Vertical image stitching via Playwright browser rendering. Combines multiple screenshot PNGs into one by rendering them as HTML and taking a full-page screenshot — no AWT/ImageIO dependency.

Vertical image stitching via Playwright browser rendering.
Combines multiple screenshot PNGs into one by rendering them as HTML
and taking a full-page screenshot — no AWT/ImageIO dependency.
raw docstring

com.blockether.spel.vault

Encrypted credential store for spel auth save/login/list/delete.

Goal: the LLM never sees the password. Credentials are encrypted at rest with AES-256-GCM. The decryption key comes from:

  1. Env SPEL_ENCRYPTION_KEY (64-char hex = 32 bytes), or
  2. Auto-generated file at ~/.spel/.encryption-key (chmod 600 on POSIX).

Records live in ~/.spel/vault/<name>.json.enc as:

[12-byte IV][ciphertext][16-byte GCM tag]

The JSON payload (before encryption) has :name :url :username :password.

Threat model: this protects credentials from casual disk inspection and from the LLM driving the CLI — NOT from a local attacker with filesystem read. Use OS-level keyring for stronger guarantees.

Encrypted credential store for `spel auth save/login/list/delete`.

Goal: the LLM never sees the password. Credentials are encrypted at rest
with AES-256-GCM. The decryption key comes from:

1. Env `SPEL_ENCRYPTION_KEY` (64-char hex = 32 bytes), or
2. Auto-generated file at `~/.spel/.encryption-key` (chmod 600 on POSIX).

Records live in `~/.spel/vault/<name>.json.enc` as:

  [12-byte IV][ciphertext][16-byte GCM tag]

The JSON payload (before encryption) has `:name :url :username :password`.

Threat model: this protects credentials from casual disk inspection and
from the LLM driving the CLI — NOT from a local attacker with filesystem
read. Use OS-level keyring for stronger guarantees.
raw docstring

com.blockether.spel.visual-diff

Pixel-level screenshot comparison using the pixelmatch algorithm. Runs inside Playwright's Canvas API — no AWT/ImageIO dependency, GraalVM native-image safe.

Based on pixelmatch by Mapbox (ISC license): https://github.com/mapbox/pixelmatch

Pixel-level screenshot comparison using the pixelmatch algorithm.
Runs inside Playwright's Canvas API — no AWT/ImageIO dependency,
GraalVM native-image safe.

Based on pixelmatch by Mapbox (ISC license):
https://github.com/mapbox/pixelmatch
raw 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