Liking cljdoc? Tell your friends :D

spel logo

spel - The Swiss Army Knife browser tool for AI agents and Clojure developers.
Browser automation · E2E and API testing · Allure reporting · Accessibility snapshots · Inline Clojure scripting · Record and Generate - one native binary, three browser engines.
Accessibility SnapshotsInline Clojure via --evalVisual AnnotationsAgent Scaffolding
spel snapshot demospel eval demospel annotate demospel agents demo

Rationale

Playwright's Java API is imperative and verbose — option builders, checked exceptions, manual resource cleanup. Clojure deserves better. And AI agents deserve more than a shell wrapper.

spel wraps Playwright Java with idiomatic Clojure: maps for options, anomaly maps for errors, with-* macros for lifecycle, and a native CLI binary for instant browser automation. It does everything a modern agentic workflow needs — in one tool.

  • Swiss Army Knife for agents: Browser automation, API testing, test reporting, agentic search and verification, accessibility snapshots, inline code execution, and test generation — all in a single native binary. No stitching tools together.
  • Agentic by design: Accessibility snapshots with numbered refs let AI agents see the page as a structured document, not raw HTML. Persistent daemon, --eval scripting, and zero brittle CSS selectors — agents reason and act in a loop without restarting.
  • Inline Clojure execution: Run arbitrary Clojure expressions in the browser context via --eval — mix business logic with automation, call any GraalVM-bound function, compose scripts on the fly. No other browser tool lets an agent write and execute real code mid-session.
  • Record, then generate: Capture any browser session to JSONL and auto-generate idiomatic Clojure tests or reusable scripts. Record once, replay forever.
  • Allure reports with network inspection: Full Allure reporting with embedded Playwright traces, network request/response visualization (method, status, headers, JSON body), and visual diffs. Debug failures from the report, not from logs.
  • API testing built in: Intercept, assert, and inspect HTTP traffic in the same tool as your browser tests — no separate client needed.
  • Native CLI binary: GraalVM native image, zero JVM startup, persistent daemon — fast enough for interactive agentic loops and CI alike.
  • Not a port: Wraps Playwright Java directly — full API coverage, all three engines (Chromium, Firefox, WebKit).

Quick Start

Install

Clojure library:

;; deps.edn
{:deps {com.blockether/spel {:mvn/version "0.4.0"}}}

Native CLI (download from GitHub releases):

# macOS (Apple Silicon)
curl -LO https://github.com/Blockether/spel/releases/latest/download/spel-macos-arm64
chmod +x spel-macos-arm64 && mv spel-macos-arm64 ~/.local/bin/spel

# Linux (amd64)
curl -LO https://github.com/Blockether/spel/releases/latest/download/spel-linux-amd64
chmod +x spel-linux-amd64 && mv spel-linux-amd64 ~/.local/bin/spel

# Linux (arm64)
curl -LO https://github.com/Blockether/spel/releases/latest/download/spel-linux-arm64
chmod +x spel-linux-arm64 && mv spel-linux-arm64 ~/.local/bin/spel

# Windows (PowerShell)
Invoke-WebRequest -Uri https://github.com/Blockether/spel/releases/latest/download/spel-windows-amd64.exe -OutFile spel.exe
Move-Item spel.exe "$env:LOCALAPPDATA\Microsoft\WindowsApps\spel.exe"

Add ~/.local/bin to your PATH:

export PATH="$HOME/.local/bin:$PATH"  # add to ~/.bashrc or ~/.zshrc

macOS Gatekeeper (binaries are not Apple-signed):

xattr -d com.apple.quarantine ~/.local/bin/spel

Post-install:

spel install   # install browsers
spel version   # verify installation
Corporate Proxy / Custom CA Certificates

Behind a corporate SSL-inspecting proxy, spel install may fail with "PKIX path building failed". Use these env vars to add corporate CA certs:

Env VarFormatOn missing fileDescription
SPEL_CA_BUNDLEPEM fileErrorExtra CA certs (merged with defaults)
NODE_EXTRA_CA_CERTSPEM fileWarning, skipsShared with Node.js subprocess
SPEL_TRUSTSTOREJKS/PKCS12ErrorTruststore (merged with defaults)
SPEL_TRUSTSTORE_TYPEStringDefault: JKS
SPEL_TRUSTSTORE_PASSWORDStringDefault: empty
export SPEL_CA_BUNDLE=/path/to/corporate-ca.pem
export NODE_EXTRA_CA_CERTS=/path/to/corporate-ca.pem
spel install --with-deps

All options merge with built-in defaults — public CDN certs continue to work.

Browser Automation

(require '[com.blockether.spel.core :as core]
         '[com.blockether.spel.page :as page])

(core/with-testing-page [pg]
  (page/navigate pg "https://example.com")
  (page/title pg))
;; => "Example Domain"

Pass an opts map for device emulation:

(core/with-testing-page {:device :iphone-14 :locale "fr-FR"} [pg]
  (page/navigate pg "https://example.com"))

For explicit lifecycle control, with-playwright/with-browser/with-context/with-page nesting is available. See the full API reference.

API Testing & Writing Tests

Browser testing:

(core/with-testing-page [pg]
  (page/navigate pg "https://example.com")
  (page/title pg))

API testing:

(core/with-testing-api {:base-url "https://api.example.com"} [ctx]
  (core/api-get ctx "/users"))

Combined UI + API — use page-api or with-page-api to share a single Playwright trace:

;; page-api: same context, same trace
(core/with-testing-page [pg]
  (page/navigate pg "https://example.com/login")
  (core/api-get (core/page-api pg) "/api/me"))

;; with-page-api: same context, different base-url
(core/with-testing-page [pg]
  (page/navigate pg "https://example.com/login")
  (core/with-page-api pg {:base-url "https://api.example.com"} [ctx]
    (core/api-get ctx "/me")))

Important: Do NOT nest with-testing-page inside with-testing-api (or vice versa). Each creates its own Playwright instance, browser, and context — you get two separate traces instead of one. Use page-api/with-page-api to combine UI and API testing under a single trace.

Test example using spel.allure (defdescribe, describe, it, expect):

(ns my-app.test
  (:require
   [com.blockether.spel.page :as page]
   [com.blockether.spel.test-fixtures :refer [*page* with-playwright with-browser with-page]]
   [com.blockether.spel.allure :refer [defdescribe describe expect it]]))

(defdescribe my-test
  (describe "example.com"
    {:context [with-playwright with-browser with-page]}
    (it "navigates and asserts"
      (page/navigate *page* "https://example.com")
      (expect (= "Example Domain" (page/title *page*))))))
clojure -M:test --output nested --output com.blockether.spel.allure-reporter/allure

See SKILL.md for fixtures, steps, and attachments.

Native CLI

spel compiles to a native binary via GraalVM - no JVM startup, instant execution. The CLI provides commands for browser automation (open, screenshot, snapshot, annotate), a persistent browser daemon, session recording (codegen), PDF generation, and an --eval mode for inline Clojure scripting via SCI. Run spel --help for the full command list.

Agent Scaffolding

Point your AI agent at spel and let it write your E2E tests.

spel init-agents                              # OpenCode (default)
spel init-agents --loop=claude                # Claude Code
spel init-agents --loop=vscode                # VS Code / Copilot
spel init-agents --flavour=clojure-test       # clojure.test instead of Lazytest
spel init-agents --no-tests                   # SKILL only (interactive dev)
FlagDefaultPurpose
--loop TARGETopencodeAgent format: opencode, claude, vscode
--ns NSdir nameBase namespace for generated tests
--flavour FLAVOURlazytestTest framework: lazytest or clojure-test
--no-testsScaffold only the SKILL (API reference) — no test agents
--dry-runPreview files without writing
--forceOverwrite existing files
--test-dir DIRtest-e2eE2E test output directory
--specs-dir DIRtest-e2e/specsTest plans directory

Video Recording

Record browser sessions as WebM files for debugging and CI artifacts.

(def ctx (core/new-context browser {:record-video-dir "videos"}))

See recording options and test fixtures.

Test Generation (Codegen)

Record browser sessions and transform them to idiomatic Clojure code.

spel codegen record -o recording.jsonl https://example.com
spel codegen recording.jsonl > my_test.clj

See full actions and output formats.

Building from Source

# Install browsers (via Playwright Java CLI)
clojure -M -e "(com.microsoft.playwright.CLI/main (into-array String [\"install\" \"--with-deps\"]))"

# Build JAR
clojure -T:build jar

# Build native image (requires GraalVM)
clojure -T:build native-image

# Run tests
make test
make test-allure

# Start REPL
make repl

Changelog

See CHANGELOG.md.

License

Apache License 2.0 — see LICENSE.

Can you improve this documentation? These fine people already did:
Karol Wojcik, Michał Kruk & blockether-deployer
Edit on GitHub

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