name: weblens description: | Use WebLens to explore, audit, and automate web pages from the CLI. Activate this skill whenever you need to interact with a browser programmatically — scraping interactive elements, running actions/assertions, crawling a site, fuzzing forms, running accessibility audits, or generating Playwright tests.
Trigger for:
- Exploring what interactive elements exist on a page (buttons, inputs, links).
- Executing browser actions: click, fill, navigate, press key, scroll.
- Writing natural-language instructions resolved by an LLM (ai: prefix).
- Mapping site structure recursively (crawl).
- Scanning forms for required fields and input types.
- Running accessibility audits (axe-core).
- Comparing screenshots for visual regression.
- Fuzzing form inputs for crash/XSS vectors.
- Generating Playwright TypeScript tests from recorded sessions.
- Stealth mode to bypass bot-detection (Cloudflare, DataDome, etc.).
DO NOT trigger for: - Backend API testing (use Playwright test directly). - Unit testing JavaScript functions. - CI/CD pipelines or Docker configuration.
WebLens — Agent Skill Guide
WebLens is a CLI-powered browser utility built on Playwright. Run it via:
npm run weblens -- <command> [options]
The project lives at /Users/abhinavsharma/gitRepos/tester-buddy.
Core Rules for Agents
- Always use
--json— Text output is for humans. JSON is for you. - Always use
--session ./session.json— Persist cookies/localStorage across commands. Without it, every command starts a fresh browser. - Always check
urlin JSON output — Verify navigation succeeded after click/goto actions. - Use
--monitor-errors— Catch hidden 4xx/5xx or console exceptions after critical form submissions. - Execute commands sequentially — State is bridged by the session file.
Command Reference
explore <url> — The Eyes and Hands
Scrape a page and optionally perform actions/assertions.
# Headless element map
npm run weblens -- explore https://example.com/ --json --session ./s.json
# Action chain + assertions
npm run weblens -- explore https://example.com/ \
--do "fill:#username:admin" \
--do "fill:#password:secret" \
--do "click:#login-btn" \
--expect "url:dashboard" \
--json --session ./s.json
# Natural-language actions via LLM (requires llm config)
npm run weblens -- explore https://example.com/ \
--do "ai:log in as admin" \
--do "ai:click the first Add to Cart button" \
--json --session ./s.json
# Interactive headed mode for manual QA
npm run weblens -- explore https://example.com/ --interactive
Key options:
| Option | Description |
|---|---|
--json |
Machine-readable output |
--session <path> |
Load/save cookies + history |
--do <action> |
Action to run (repeatable) |
--expect <criteria> |
Assertion to verify (repeatable) |
--monitor-errors |
Fail on console/network errors |
--performance |
Include LCP/FCP/DCL metrics |
--stealth |
Hide automation signals |
--screenshot |
Save screenshot to screenshot.png |
--interactive |
Open headed browser (manual QA) |
--role <name> |
Inject a session role for interactive mode |
Action formats (--do):
| Action | Format | Example |
|---|---|---|
| Click | click:<selector> |
click:#submit |
| Fill | fill:<selector>:<value> |
fill:#email:test@example.com |
| Navigate | goto:<url> |
goto:https://example.com/cart |
| Press key | press:<key> |
press:Enter |
| Scroll | scroll:<top|bottom|selector> |
scroll:bottom |
| Wait | wait:<ms> |
wait:2000 |
| Loop | loop:<count>:<action> |
loop:3:click:#load-more |
| Conditional | if:<selector>:<action> |
if:#cookie-banner:click:#accept |
| Retry | retry:<count>:<action> |
retry:3:click:#submit |
| Semantic (AI) | ai:<instruction> |
ai:add the cheapest item to cart |
Expectation formats (--expect):
| Type | Format | Example |
|---|---|---|
| Text on page | text:<string> |
text:Welcome back |
| Selector visible | selector:<selector> |
selector:.dashboard |
| URL contains | url:<string> |
url:inventory |
crawl <url> — Site Mapping
npm run weblens -- crawl https://example.com/ --depth 2 --json
npm run weblens -- crawl https://example.com/ --visual # Mermaid diagram
Output includes status codes, link counts, and broken-link detection.
forms <url> — Form Analysis
npm run weblens -- forms https://example.com/checkout --json --session ./s.json
Returns all form groups with input names, types, required flags, and current values.
audit <url> — Accessibility Audit
npm run weblens -- audit https://example.com/ --json
Runs axe-core. Returns violations with impact levels and help URLs.
fuzz <url> — Form Fuzzing
npm run weblens -- fuzz https://example.com/register --json
Injects XSS payloads, boundary integers, SQL strings. Reports crashes and unexpected responses.
visual <url> — Screenshot & Regression
# Capture baseline
npm run weblens -- visual https://example.com/ --out baseline.png
# Compare against baseline
npm run weblens -- visual https://example.com/ --base baseline.png --out diff.png --threshold 0.1
repl <url> — Interactive REPL
npm run weblens -- repl https://example.com/
Live command loop: type explore/click/fill commands in the terminal.
codegen — Generate Playwright Tests
# From session history → raw Playwright TypeScript
npm run weblens -- codegen --session ./s.json --out tests/flow.spec.ts
# LLM-cleaned version with assertions
npm run weblens -- codegen --session ./s.json --out tests/flow.spec.ts --llm
# Print LLM prompt instead of running it
npm run weblens -- codegen --session ./s.json --prompt
Self-Healing Selectors
If a click: or fill: action fails, WebLens automatically:
- Extracts a keyword from the failed selector (e.g.
#btn-submit→submit). - Searches the DOM for elements with matching text, aria-label, or placeholder.
- Re-executes the action with the healed selector and logs the resolution.
This is transparent — no extra flags needed.
Semantic Actions (ai: prefix)
When selectors are unknown or brittle, use natural-language instructions:
--do "ai:log in with standard_user and secret_sauce"
--do "ai:add the backpack to the cart"
--do "ai:go to the checkout page"
How it works:
- Scrapes visible interactive elements on the current page.
- Sends them + the instruction to the configured LLM (OpenAI / Anthropic / Ollama).
- Parses the LLM response into a concrete action string and executes it.
- If the resolved action fails, self-healing kicks in as a fallback.
LLM configuration — set in weblens.config.json or env vars:
{ "llm": { "openaiKey": "sk-..." } }
Env vars: OPENAI_API_KEY, ANTHROPIC_API_KEY, OLLAMA_MODEL.
Stealth Mode
Passes --disable-blink-features=AutomationControlled to Chromium and injects scripts that:
- Set
navigator.webdrivertoundefined. - Mock
window.chromeruntime properties. - Spoof PDF viewer plugins and language headers.
- Override WebGL vendor/renderer to hardware values.
Enable per-command with --stealth, or set globally in weblens.config.json:
{ "stealth": true }
Configuration File (weblens.config.json)
{
"stealth": false,
"roles": {
"admin": {
"cookies": [{ "name": "session", "value": "abc", "domain": "example.com", "path": "/" }],
"localStorage": { "user_role": "admin" }
}
},
"mocks": [
{
"urlPattern": "**/api/payment",
"method": "POST",
"response": { "status": 500, "contentType": "application/json", "body": "{\"error\":\"mocked\"}" }
}
],
"llm": {
"openaiKey": "",
"anthropicKey": "",
"ollamaModel": "",
"ollamaUrl": "http://localhost:11434/api/chat"
}
}
Typical Agent Workflow
# 1. Explore a login page
npm run weblens -- explore https://app.example.com/login --json --session ./s.json
# 2. Log in
npm run weblens -- explore https://app.example.com/login \
--do "fill:#username:testuser" \
--do "fill:#password:pass123" \
--do "click:#login-btn" \
--expect "url:dashboard" \
--json --session ./s.json
# 3. Audit the dashboard for accessibility violations
npm run weblens -- audit https://app.example.com/dashboard --json --session ./s.json
# 4. Crawl the site to find broken links
npm run weblens -- crawl https://app.example.com/ --depth 2 --json
# 5. Generate a Playwright test from the recorded session
npm run weblens -- codegen --session ./s.json --out tests/login.spec.ts --llm
Troubleshooting
| Symptom | Fix |
|---|---|
Selector not found |
Re-run explore without --do to see current DOM state. |
Session not found |
The first explore creates the file — check the path. |
| Navigation loop (same page) | The click may not trigger. Try goto:<href> directly. |
LLM configuration is missing |
Set OPENAI_API_KEY / ANTHROPIC_API_KEY / OLLAMA_MODEL env var. |
| Page loads slowly | Add --do "wait:2000" before scraping. |
| Bot detection blocking | Add --stealth flag. |