Webwright
Delegate browser tasks to the webwright CLI. Webwright is a code-as-action web
agent: an LLM writes and runs Playwright scripts to drive a real Chromium browser,
which is more robust and repeatable than click-by-click automation.
When to use
- Multi-step web flows: logins, multi-page forms, checkout/wizard flows.
- Long-horizon navigation across several pages where state must be carried.
- Repeatable site tasks where you want a reusable generated script as the artifact.
When NOT to use
- Simple single-page reads or extraction — use
web_fetch/ built-in web tools. - Anything that does not actually require a driven browser.
Preflight (do this before the first run)
This skill is opt-in. It only becomes available once
skills.entries.webwright.enabled is true (an unset value counts as off), so
enable it first:
openclaw config set skills.entries.webwright.enabled true
Run webwright doctor next as a setup check. Note its key check is
OpenAI-specific: it always runs an OpenAI Key check, so if you intend to use
Anthropic or OpenRouter, a doctor OpenAI Key FAIL is expected and is NOT a
blocker — verify your chosen provider's key separately (step 3). Then confirm:
webwrightis on PATH (this skill is gated on it). If missing, seereferences/setup.md.- Chromium is installed for Playwright:
playwright install chromium. - A provider API key is set in the environment for the model config you pick:
OPENAI_API_KEY(defaultmodel_openai.yaml),ANTHROPIC_API_KEY(model_claude.yaml), orOPENROUTER_API_KEY(model_openrouter.yaml). - The
python,python3, andplaywrightthat webwright's generated scripts will invoke must be webwright's own install (with Chromium). If you installed webwright in a venv, activate it (or prepend itsbintoPATH) before running — otherwise generated scripts can pick up a different system Python that lacks the browser. Seereferences/setup.md. - Choose an output directory INSIDE the current workspace. Never write into
~/.openclaw,$OPENCLAW_STATE_DIR, or any active OpenClaw state directory.
Invocation
The CLI uses a main subcommand:
webwright main \
-t "TASK INSTRUCTION" \
--start-url "https://example.com" \
-c base.yaml -c model_openai.yaml \
--task-id my_task \
-o ./webwright-out/my_task
-c defaults to base.yaml model_openai.yaml. You can also stack inline
overrides, e.g. -c agent.step_limit=20 to cap the agent's step budget.
Then read the run artifacts (generated final_script.py, plan.md, step logs,
screenshots under final_runs/run_<id>/) from the -o directory and report the
generated script path to the user.
See references/cli.md for every flag, config stacking, and the output layout.
Hard rules
- Always pass
-opointing inside the workspace; never inside OpenClaw state dirs. - Always pass
--start-urland a specific, scoped-ttask. - Browser runs take real actions on live sites and spend API tokens. Only run on user-authorized tasks and sites, and avoid destructive actions.
- Never put secrets in the
-ttask text. The task is sent to the model provider and recorded in run artifacts (trajectories, logs, process args), so passwords or tokens placed there are exposed. For login-walled tasks, pass credentials via environment variables and tell the agent the env var NAMES to read in its generated script (e.g. "log in using $SITE_USER / $SITE_PASS"), or pre-authenticate a persistent browser profile — never the literal secret values. - Pick exactly one model config (
model_openai.yaml,model_claude.yaml,model_openrouter.yaml) whose matching API key is present in the environment.
Examples
Search flights and read the results:
webwright main -t "Search flights SEA to JFK departing 2026-08-15 returning 2026-08-20" \
--start-url "https://www.google.com/flights" \
-c base.yaml -c model_openai.yaml --task-id flights -o ./webwright-out/flights
Extract a table behind a multi-step navigation (Claude model):
webwright main -t "Open the docs, go to the pricing page, and list every plan and price" \
--start-url "https://example.com" \
-c base.yaml -c model_claude.yaml --task-id pricing -o ./webwright-out/pricing
Scan to join WeChat group