Test Patterns for AI-Driven Browser Automation
Pattern 1: Navigate-Act-Verify (NAV)
The fundamental test pattern. Every browser test follows this structure:
Navigate → Act → Verify
Example: Login Test
# NAVIGATE
vibe-check navigate https://app.example.com/login
# ACT
vibe-check type "input[name=email]" "user@test.com"
vibe-check type "input[name=password]" "secret123"
vibe-check click "button[type=submit]"
# VERIFY
vibe-check wait "h1.dashboard-title"
vibe-check text "h1.dashboard-title"
# → Agent checks: does it say "Dashboard"? PASS
Agent's Role
The agent decides:
- What URL to navigate to
- What selector to use (from hints or discovery)
- What text to type
- How to verify success (text content, URL change, element presence)
Pattern 2: Form Validation Testing
Test that forms reject invalid input correctly.
Example: Registration Form
# Test: empty form submission
vibe-check navigate https://app.example.com/register
vibe-check click "button[type=submit]" # Submit empty form
vibe-check text ".error" # Read all error messages
# → Agent verifies: "Email is required", "Password is required"
# Test: invalid email
vibe-check type "input[name=email]" "not-an-email"
vibe-check click "button[type=submit]"
vibe-check text ".error[data-field=email]"
# → Agent verifies: "Please enter a valid email"
# Test: weak password
vibe-check type "input[name=email]" "valid@test.com"
vibe-check type "input[name=password]" "123"
vibe-check click "button[type=submit]"
vibe-check text ".error[data-field=password]"
# → Agent verifies: "Password must be at least 8 characters"
# Test: valid submission
vibe-check type "input[name=email]" "valid@test.com"
vibe-check type "input[name=password]" "StrongP@ss123"
vibe-check click "button[type=submit]"
vibe-check wait ".success-message"
vibe-check text ".success-message"
# → Agent verifies: "Registration successful"
Agent's Added Value
The agent can generate test cases from the form structure:
- Read all
<input>elements and their validation attributes - Generate boundary-value tests automatically
- Verify error messages match expected UX copy
Pattern 3: Multi-Page Flow
Tests that span multiple page navigations.
Example: E-Commerce Checkout
# Browse products
vibe-check navigate https://shop.example.com
vibe-check click ".product-card:first-child a"
vibe-check text ".product-name"
# → Agent notes: "Blue Widget, $29.99"
# Add to cart
vibe-check click "#add-to-cart"
vibe-check wait ".cart-badge"
vibe-check text ".cart-badge"
# → Agent verifies: badge shows "1"
# Go to cart
vibe-check navigate https://shop.example.com/cart
vibe-check text ".cart-item-name"
# → Agent verifies: "Blue Widget"
vibe-check text ".cart-total"
# → Agent verifies: "$29.99"
# Checkout
vibe-check click "#checkout"
vibe-check type "#card-number" "4111111111111111"
vibe-check type "#expiry" "12/28"
vibe-check type "#cvv" "123"
vibe-check click "#pay-now"
vibe-check wait ".order-confirmation"
vibe-check text ".order-number"
# → Agent captures: "Order #12345"
Key Considerations
- State carries between pages (cart contents, session cookies)
- Use daemon mode for multi-page flows (browser persists)
- Screenshot at each page for debugging trail
Pattern 4: Data Extraction and Verification
Extract structured data from the page and verify against expected values.
Example: Dashboard Metrics
vibe-check navigate https://app.example.com/dashboard
vibe-check eval "JSON.stringify({
revenue: document.querySelector('.metric-revenue').textContent,
users: document.querySelector('.metric-users').textContent,
orders: document.querySelector('.metric-orders').textContent
})"
# → {"revenue": "$45,230", "users": "1,234", "orders": "567"}
Example: Table Data
vibe-check navigate https://app.example.com/users
vibe-check eval "JSON.stringify(
[...document.querySelectorAll('table tbody tr')].map(row => ({
name: row.cells[0].textContent,
email: row.cells[1].textContent,
role: row.cells[2].textContent
}))
)"
# → [{"name": "Alice", "email": "alice@test.com", "role": "Admin"}, ...]
Agent's Added Value
The agent can:
- Parse the JSON output
- Compare against expected values from a database or API
- Identify discrepancies and report them meaningfully
Pattern 5: Wait-and-Verify (Async Operations)
For operations that don't complete immediately (AJAX calls, file uploads, etc.).
Example: File Upload
vibe-check navigate https://app.example.com/upload
# Note: file input interaction may require eval
vibe-check eval "document.querySelector('input[type=file]').value"
# After upload trigger
vibe-check wait ".upload-progress" --state visible
vibe-check wait ".upload-progress" --state hidden --timeout 60000 # Wait for completion
vibe-check text ".upload-status"
# → Agent verifies: "Upload complete"
Example: Search with Debounce
vibe-check navigate https://app.example.com/search
vibe-check type "#search-box" "test query"
# Wait for debounce + API call + render
vibe-check wait ".search-results"
vibe-check text ".result-count"
# → Agent verifies: "15 results found"
Pattern 6: Tab-Based Testing
Tests that require multiple tabs or windows.
Example: Open Link in New Tab
vibe-check navigate https://app.example.com
vibe-check tab-new https://docs.example.com/api # Open API docs in new tab
vibe-check text "h1"
# → "API Reference"
vibe-check tab-switch 0 # Back to app
vibe-check text "h1"
# → "Dashboard"
Example: Compare Two Pages
vibe-check navigate https://staging.example.com
vibe-check text ".version" > /tmp/staging-version.txt
vibe-check tab-new https://production.example.com
vibe-check text ".version" > /tmp/prod-version.txt
# Agent compares the two files
Pattern 7: Negative Testing
Verify that the application correctly rejects invalid operations.
Example: Unauthorized Access
# Try to access admin page without login
vibe-check navigate https://app.example.com/admin
vibe-check url
# → Agent verifies: redirected to /login (not /admin)
vibe-check text "h1"
# → Agent verifies: "Please log in" (not admin content)
Example: Rate Limiting
# Rapid-fire requests
for i in $(seq 1 10); do
vibe-check click "#submit-button"
vibe-check text ".response"
done
# Agent checks if rate limiting kicked in
Pattern 8: Visual Regression (Screenshot Comparison)
Use screenshots to detect visual changes.
# Capture baseline
vibe-check navigate https://app.example.com/dashboard
vibe-check screenshot -o baseline/dashboard.png
# ... after code change ...
# Capture current
vibe-check navigate https://app.example.com/dashboard
vibe-check screenshot -o current/dashboard.png
# Agent compares screenshots (via vision or pixel comparison tool)
Agent's Added Value
With vision capabilities, the agent can:
- Identify specific visual differences
- Classify changes as intentional vs regression
- Describe what changed in natural language
Pattern 9: Error State Testing
Verify the application handles errors gracefully.
Example: Network Error
# Use eval to simulate offline mode
vibe-check eval "window.navigator.__defineGetter__('onLine', () => false)"
vibe-check click "#save-button"
vibe-check text ".error-banner"
# → Agent verifies: appropriate offline message shown
Example: Server Error
vibe-check navigate https://app.example.com/broken-page
vibe-check text "body"
# → Agent checks: is there a user-friendly error page (not a raw 500 stack trace)?
vibe-check screenshot -o error-page.png
Anti-Patterns
Don't: Hard-Code Wait Times
# BAD
vibe-check navigate https://app.example.com
sleep 5 # Arbitrary wait
vibe-check text "h1"
# GOOD
vibe-check navigate https://app.example.com
vibe-check wait "h1" # Wait for specific element
vibe-check text "h1"
Don't: Ignore Return Values
# BAD
vibe-check click "#submit"
vibe-check text ".result" # Might fail if click didn't work
# GOOD
vibe-check click "#submit"
vibe-check wait ".result" # Explicitly wait for expected state
vibe-check text ".result"
Don't: Chain Commands Without Verification
# BAD: Assumes every step succeeds
vibe-check navigate url && vibe-check click A && vibe-check click B && vibe-check click C
# GOOD: Verify each critical step
vibe-check navigate url
vibe-check wait "selector-A"
vibe-check click "selector-A"
vibe-check wait "selector-B"
vibe-check click "selector-B"