Help us improve
Share bugs, ideas, or general feedback.
From qa-use
Automates E2E testing and browser interactions with qa-use CLI. Create sessions, navigate pages, snapshot DOM for element refs, perform clicks/fills, and debug test failures.
npx claudepluginhub joshuarweaver/cascade-code-testing-misc --plugin desplega-ai-qa-useHow this skill is triggered — by the user, by Claude, or both
Slash command
/qa-use:qa-useThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
E2E testing and browser automation for AI-driven development workflows.
Runs AI-powered adversarial UI testing via the browse CLI — analyzes git diffs, explores full apps, and tests functional correctness, accessibility, responsive layout, and UX heuristics. Use for QA pull requests, auditing accessibility, or exploratory testing.
Automates headless browser via agent-browser CLI: open/navigate sites, snapshot interactive elements for refs, click/fill forms, verify UI, scrape data, e2e test web apps.
Tests local web applications using Playwright: verifies frontend functionality, debugs UI behavior, captures screenshots, views logs. Mandatory before declaring implementation complete.
Share bugs, ideas, or general feedback.
E2E testing and browser automation for AI-driven development workflows.
For AI Harnesses (codex, opencode, etc.):
Plugin commands (slash commands like /qa-use:verify) are convenience shortcuts that wrap CLI workflows. Harnesses with only the Bash tool can access ALL functionality via CLI commands documented below.
Pattern throughout this document:
Before using any qa-use commands, verify configuration is in place:
# Check current configuration (no-op if already configured)
qa-use setup
# Configure with API key (validates against server)
qa-use setup --api-key <key>
# View full configuration details
qa-use info
Environment Variables (alternative to config file):
| Variable | Description |
|---|---|
QA_USE_API_KEY | API key for authentication |
QA_USE_REGION | Region: us (default) or auto |
QA_USE_API_URL | Override API base URL |
Config file: .qa-use.json in the project directory or ~/.qa-use.json in the home directory. Precedence: env vars > project .qa-use.json > ~/.qa-use.json.
If you encounter "API key not configured", 401, or auth errors: Run qa-use setup to check config state. NEVER fabricate or guess API keys.
CLI Workflow:
# Create browser session
qa-use browser create --viewport desktop
# For localhost testing
qa-use browser create --tunnel --no-headless
# Navigate
qa-use browser goto https://example.com
# Snapshot to get element refs (ALWAYS do this before interacting)
qa-use browser snapshot
# Interact by ref
qa-use browser click e3
qa-use browser fill e5 "text"
# Close
qa-use browser close
Plugin Shortcut:
/qa-use:explore https://example.com
(Wraps create + goto + snapshot with autonomous exploration)
Critical: Always run snapshot before your first interaction on a page. Never guess element refs.
Snapshot Diff Feature (use it to avoid unnecessary snapshots): After each action (goto, click, fill, etc.), the browser automatically shows DOM changes:
+ [e54] generic "Thanks for agreeing!" (green)~ [e18] checkbox "I agree..." with +attrs: checked, active (yellow)- [e99] button "Submit" (red)When you can skip a full snapshot: If the diff output from your last action already shows the element ref you need to interact with next, use it directly — no need for an intermediate snapshot. For example, if clicking a button shows + [e54] button "Submit" in the diff, you can click e54 immediately.
When you still need a full snapshot: Run snapshot when you need to find elements that weren't in the diff (e.g., pre-existing elements you haven't interacted with yet), or when the diff was truncated (shows "... and N more changes").
What are blocks?
Blocks are atomic recorded interactions from a browser session. They are:
qa-use browser get-blocksWhy blocks matter:
How blocks work:
# 1. Create session and interact
qa-use browser create --tunnel --no-headless
qa-use browser goto https://example.com
qa-use browser snapshot # Returns: [ref=e1] button
qa-use browser click e1 # Records as block
qa-use browser fill e5 "text" # Records as block
# 2. Retrieve blocks (JSON array)
qa-use browser get-blocks
# Returns:
# [
# {"type": "goto", "url": "...", "timestamp": "..."},
# {"type": "click", "ref": "e1", "timestamp": "..."},
# {"type": "fill", "ref": "e5", "value": "text", "timestamp": "..."}
# ]
# 3. Generate test YAML from blocks
qa-use browser generate-test -n "my_test" -o qa-tests/my_test.yaml
# 4. Run generated test
qa-use test run my_test
Plugin Shortcut:
/qa-use:record start my_test
# ... perform interactions ...
/qa-use:record stop
(Wraps the interactive workflow with AI-powered test generation)
CLI Workflow:
# Run test by name
qa-use test run login
# Run with autofix (AI self-healing)
qa-use test run login --autofix
# Validate syntax
qa-use test validate login
# Show test details
qa-use test info login
# List test runs
qa-use test runs --status failed
Plugin Shortcut:
/qa-use:test-run login --autofix
(Convenience shortcut for common test execution)
CLI Workflow:
# Pull tests from cloud
qa-use test sync pull
# Push all local tests to cloud
qa-use test sync push --all
# Push specific test
qa-use test sync push --id <uuid>
# Force push (overwrite conflicts)
qa-use test sync push --force
# Compare local vs cloud
qa-use test diff login.yaml
No Plugin Shortcut - Use CLI commands directly
| Command | Description |
|---|---|
qa-use browser create | Create remote browser session |
qa-use browser create <url> | Create session and navigate to URL |
qa-use browser create --tunnel | Create local browser with API tunnel |
qa-use browser create --no-headless | Show browser window (tunnel mode only) |
qa-use browser create --viewport <size> | Set viewport: desktop, tablet, mobile |
qa-use browser create --ws-url <url> | Connect to existing WebSocket browser |
qa-use browser create --after-test-id <uuid> | Run a test first, then become interactive |
qa-use browser create --var <key=value> | Override app config variables (repeatable) |
qa-use browser list | List active sessions |
qa-use browser status | Show current session details (app_url, recording_url, etc.) |
qa-use browser close | Close active session |
Sessions auto-persist in ~/.qa-use.json. One active session = no -s flag needed.
| Command | Description |
|---|---|
qa-use browser goto <url> | Navigate to URL |
qa-use browser back | Go back |
qa-use browser forward | Go forward |
qa-use browser reload | Reload page |
| Command | Description |
|---|---|
qa-use browser click <ref> | Click element by ref |
qa-use browser click --text "Button" | Click by semantic description |
qa-use browser fill <ref> "value" | Fill input field |
qa-use browser type <ref> "text" | Type with delays (for autocomplete) |
qa-use browser press <key> | Press key (e.g., Enter, Tab) |
qa-use browser check <ref> | Check checkbox |
qa-use browser uncheck <ref> | Uncheck checkbox |
qa-use browser select <ref> "option" | Select dropdown option |
qa-use browser hover <ref> | Hover over element |
qa-use browser scroll down 500 | Scroll by pixels |
qa-use browser scroll-into-view <ref> | Scroll element into view |
qa-use browser drag <ref> --target <ref> | Drag element to target |
qa-use browser mfa-totp [ref] <secret> | Generate TOTP code (optionally fill) |
qa-use browser upload <ref> <file>... | Upload file(s) to input (base64-encoded, works remote & tunnel) |
| Command | Description |
|---|---|
qa-use browser snapshot | Get full ARIA tree with element refs (use only when diff output is insufficient) |
qa-use browser url | Get current URL |
qa-use browser screenshot | Save screenshot.png |
qa-use browser screenshot file.png | Save to custom path |
qa-use browser screenshot --base64 | Output base64 to stdout |
qa-use browser evaluate <expression> | Execute JavaScript in browser context |
The snapshot-diff feature automatically displays DOM changes after each browser action:
+ prefix and green color — these refs are immediately usable~ prefix and yellow color, including attribute changes (+attrs: checked)- prefix and red color — do NOT use these refsDownloads: When an action triggers a file download (e.g., clicking a download link), the response includes download info: filename, size, and a presigned URL. Use qa-use browser downloads to list all downloads or --save <dir> to save them locally.
Use diff output to interact with newly appeared elements directly, without running a full snapshot first.
| Command | Description |
|---|---|
qa-use test run <name> | Run test by name |
qa-use test run --all | Run all tests |
qa-use test run <name> --tunnel | Run with local browser tunnel |
qa-use test run <name> --autofix | Enable AI self-healing |
qa-use test run <name> --update-local | Persist AI fixes to file |
qa-use test run <name> --download | Download assets to /tmp/qa-use/downloads/ |
qa-use test run <name> --var key=value | Override variable |
qa-use test validate <name> | Validate test syntax |
qa-use test list | List available tests |
qa-use test info <name> | Show test details (steps, tags, description) |
qa-use test info --id <uuid> | Show cloud test details by ID |
qa-use test runs [name] | List test run history |
qa-use test runs --id <uuid> | Filter runs by test ID |
qa-use test runs --status failed | Filter runs by status |
qa-use test init | Initialize test directory |
qa-use test sync pull | Pull tests from cloud |
qa-use test sync push --all | Push all local tests to cloud |
qa-use test sync push --id <uuid> | Push specific test |
qa-use test sync push --force | Push tests, overwriting conflicts |
qa-use test diff <file> | Compare local vs cloud test |
qa-use test schema [path] | View test definition schema |
qa-use api dynamically discovers operations from /api/v1/openapi.json and caches metadata locally for offline fallback.
| Command | Description |
|---|---|
qa-use api | Show help and available subcommands |
qa-use api ls | List available /api/v1/* routes from OpenAPI |
qa-use api ls --refresh | Force refresh OpenAPI cache |
qa-use api ls --offline | Use cached OpenAPI metadata only |
qa-use api info /api/v1/<route> | Show route details: parameters, request body, responses |
qa-use api info /api/v1/<route> -X POST | Show info for specific HTTP method |
qa-use api info /api/v1/<route> --json | Route info as JSON |
qa-use api examples | Show usage examples |
qa-use api openapi | Print OpenAPI spec URL |
qa-use api openapi --raw | Dump full OpenAPI spec as JSON |
qa-use api /api/v1/tests | Call endpoint (method inferred when possible) |
qa-use api -X GET /api/v1/test-runs -f limit=5 | GET with query fields |
qa-use api -X POST /api/v1/tests-actions/run --input body.json | POST with JSON body file |
qa-use api -X GET /api/v1/test-runs/<id> | Fetch detail endpoint by ID |
No Plugin Shortcut - Use CLI commands directly.
| Command | Description |
|---|---|
qa-use browser logs console | View console logs from session |
qa-use browser logs console -s <id> | View logs from specific/closed session |
qa-use browser logs network | View network request logs |
qa-use browser logs network -s <id> | View network logs from specific session |
qa-use browser downloads | List downloaded files from session |
qa-use browser downloads --save <dir> | Save downloaded files to local directory |
qa-use browser downloads --json | Output download info as JSON |
| Command | Description |
|---|---|
qa-use browser generate-test | Generate test YAML from recorded session |
qa-use browser generate-test -s <id> | Generate from specific session |
qa-use browser generate-test -n <name> | Specify test name |
qa-use browser generate-test -o <path> | Specify output path |
qa-use browser get-blocks | Get recorded interaction blocks (JSON) |
| Command | Description |
|---|---|
qa-use browser wait <ms> | Fixed wait |
qa-use browser wait-for-selector ".class" | Wait for selector |
qa-use browser wait-for-load | Wait for page load |
Use --var to override app config variables at runtime. Common variables:
| Variable | Description |
|---|---|
base_url | Base URL for the app (e.g., preview deployment URL) |
login_url | Login page URL |
login_username | Username/email for authentication |
login_password | Password for authentication |
Example with ephemeral preview URL:
qa-use browser create --after-test-id <login-test-uuid> \
--var base_url=https://preview-123.example.com \
--var login_url=https://preview-123.example.com/auth/login
CLI Workflow:
# 1. Search for existing test
qa-use test list | grep "login"
# 2. Run test with autofix
qa-use test run login --autofix
# 3. Debug failures
qa-use browser logs console
Plugin Shortcut:
/qa-use:verify "login works with valid credentials"
(Wraps the above CLI workflow with AI-powered test discovery and analysis)
CLI Workflow:
# 1. Create session
qa-use browser create --tunnel --no-headless
# 2. Navigate and interact
qa-use browser goto https://example.com
qa-use browser snapshot
qa-use browser click e1
qa-use browser fill e5 "test"
# 3. Generate test from blocks
qa-use browser get-blocks
qa-use browser generate-test -n "my_test"
# 4. Run test
qa-use test run my_test
Plugin Shortcut:
/qa-use:record start my_test
# ... perform interactions ...
/qa-use:record stop
CLI Workflow:
# Create session that runs login test first
qa-use browser create --after-test-id <login-test-uuid>
# Session now authenticated, explore
qa-use browser goto /dashboard
qa-use browser snapshot
Plugin Shortcut:
/qa-use:explore /dashboard
(Automatically handles auth detection and session creation)
CLI Workflow:
# 1. Open test file in editor
vim qa-tests/login.yaml
# 2. Validate syntax
qa-use test validate login
# 3. Run to verify
qa-use test run login
Plugin Shortcut:
/qa-use:record edit login
(AI-assisted editing with validation)
CLI Workflow:
# Create session and navigate
qa-use browser create --tunnel --no-headless
qa-use browser goto https://evals.desplega.ai/checkboxes
# goto shows diff — initial page load shows all elements:
# Changes: 45 elements added
# + [e18] checkbox "I agree to the terms and conditions"
# + [e19] generic "I agree to the terms and conditions"
# ✅ Use ref from diff directly — no snapshot needed!
qa-use browser click e18
# Diff shows what changed:
# Changes: 5 elements added, 1 element modified
# + [e54] generic "Thanks for agreeing!"
# + [e55] link "Terms and Conditions"
# ~ [e18] checkbox "I agree to the terms and conditions"
# +attrs: active, checked
# ✅ Can click e55 directly from diff output — no snapshot needed!
qa-use browser click e55
# ❌ Need to find an element NOT in the diff? Now run snapshot:
qa-use browser snapshot
Key principle: Use diff output as your primary source of element refs after actions. Only fall back to snapshot when you need to find elements that weren't in the diff.
Benefits:
No Plugin Shortcut - Automatic feature in all browser commands
Environment Variables:
export QA_USE_API_KEY="your-api-key"
export QA_USE_REGION="us" # Optional: "us" or "auto"
Basic Test Execution:
# Run all tests
qa-use test run --all
# Run specific tag
qa-use test run --tag smoke
# Exit codes: 0 = pass, 1 = fail
name: QA Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install qa-use
run: npm install -g @desplega.ai/qa-use
- name: Run tests
run: qa-use test run --all
env:
QA_USE_API_KEY: ${{ secrets.QA_USE_API_KEY }}
Screenshots:
/tmp/qa-use/downloads/ (local) or cloud (remote)Logs:
qa-use browser logs console -s <session-id>qa-use browser logs network -s <session-id>When to use tunnel mode:
Testing localhost (http://localhost:3000)?
├─ YES → Use --tunnel
│ └─ qa-use browser create --tunnel [--no-headless]
│ (Starts local Playwright, creates localtunnel, keeps running)
│
└─ NO (Public URL) → Use remote browser (default)
└─ qa-use browser create
(Uses desplega.ai cloud browser via WebSocket)
The --tunnel flag is a binary choice:
For test execution:
# Local app
qa-use test run my_test --tunnel [--headful]
# Public app
qa-use test run my_test
Plugin shortcuts handle tunnel detection automatically:
/qa-use:explore http://localhost:3000
/qa-use:record start local_test
See references/localhost-testing.md for troubleshooting.
Sessions are stored in ~/.qa-use.json and have:
-s flag neededbrowser closeWhat's captured:
What's NOT captured:
Manual editing: Edit generated YAML to add assertions and refine selectors.
Sharing sessions across processes:
# Process 1: Create session
qa-use browser create --tunnel
# Output: ws://localhost:12345/browser/abc123
# Process 2: Connect to session
qa-use browser goto https://example.com --ws-url ws://localhost:12345/browser/abc123
Access any reference at runtime via the CLI: qa-use docs <topic>
| Topic | CLI Command | Description |
|---|---|---|
| browser-commands.md | qa-use docs browser-commands | Complete browser CLI reference with all flags |
| test-format.md | qa-use docs test-format | Full test YAML specification |
| localhost-testing.md | qa-use docs localhost-testing | Tunnel setup for local development |
| failure-debugging.md | qa-use docs failure-debugging | Failure classification and diagnostics |
| ci.md | qa-use docs ci | CI/CD integration patterns and examples |
Use qa-use docs --list to discover all available topics and templates.
| Template | Description |
|---|---|
| basic-test.yaml | Simple navigation and assertion |
| auth-flow.yaml | Login flow with credentials |
| form-test.yaml | Form submission with validation |
name: Login Test
description: Validates login functionality with valid credentials
tags:
- smoke
- auth
app_config: <app-config-id>
variables:
email: test@example.com
password: secret123
depends_on: setup-test # Optional
steps:
- action: goto
url: /login
- action: fill
target: email input
value: $email
- action: click
target: login button
- action: to_be_visible
target: dashboard
See references/test-format.md for complete specification.
| ❌ Wrong | ✅ Correct |
|---|---|
browser navigate <url> | browser goto <url> |
browser destroy | browser close |
browser close <session-id> | browser close |
| Guessing element refs | Use refs from diff output or snapshot |
Running snapshot after every action | Use diff output; only snapshot when needed |
Testing localhost without --tunnel | Use --tunnel flag |
test sync --pull | test sync pull (subcommand, not flag) |
test sync --push | test sync push (subcommand, not flag) |
When stuck or encountering unexpected errors, use the built-in documentation:
# Check configuration state
qa-use setup
# Browse main documentation
qa-use docs
# List all available topics
qa-use docs --list
# Access specific topic
qa-use docs <topic>
| Situation | Command |
|---|---|
| Auth / API key errors | qa-use setup then qa-use docs |
| Unknown browser command | qa-use docs browser-commands |
| Test failures | qa-use docs failure-debugging |
| Localhost / tunnel issues | qa-use docs localhost-testing |
| Test YAML syntax | qa-use docs test-format |
| CI/CD setup | qa-use docs ci |
Key rules:
qa-use docs before improvising workaroundsqa-use setup shows no config, report it — don't guessAll commands use qa-use assuming global install. For one-off use:
npx @desplega.ai/qa-use browser <command>