Back to docs

Examples

Practical examples for common CBrowser use cases.


Basic Automation

Navigate and Screenshot

# CLI
npx cbrowser navigate "https://news.ycombinator.com" --screenshot hn.png
// API
import { CBrowser } from 'cbrowser';

const browser = new CBrowser();
const result = await browser.navigate('https://news.ycombinator.com');
console.log(`Title: ${result.title}`);
console.log(`Load time: ${result.loadTime}ms`);
await browser.close();

Fill a Form

# CLI
npx cbrowser navigate "https://example.com/contact"
npx cbrowser fill "name" "John Doe"
npx cbrowser fill "email" "[email protected]"
npx cbrowser fill "message" "Hello, I have a question..."
npx cbrowser smart-click "Send Message"
// API
const browser = new CBrowser({ persistent: true });
await browser.navigate('https://example.com/contact');
await browser.fill('name', 'John Doe');
await browser.fill('email', '[email protected]');
await browser.fill('message', 'Hello, I have a question...');
await browser.smartClick('Send Message');
await browser.close();

Testing

Simple Test Suite

Create login-tests.txt:

# Test: Successful Login
go to https://myapp.com/login
type "[email protected]" in email field
type "correctpassword" in password field
click "Sign In"
verify url contains "/dashboard"
verify page contains "Welcome back"

# Test: Invalid Password
go to https://myapp.com/login
type "[email protected]" in email field
type "wrongpassword" in password field
click "Sign In"
verify page contains "Invalid credentials"
verify url contains "/login"

# Test: Empty Fields
go to https://myapp.com/login
click "Sign In"
verify page contains "Email is required"

Run:

npx cbrowser test-suite login-tests.txt --html

E-commerce Checkout Test

Create checkout-tests.txt:

# Test: Add to Cart
go to https://shop.example.com/products/widget
click "Add to Cart"
verify page contains "Added to cart"
click "View Cart"
verify page contains "Widget"
verify page contains "$19.99"

# Test: Complete Purchase
go to https://shop.example.com/cart
click "Proceed to Checkout"
type "John Doe" in name field
type "[email protected]" in email field
type "123 Main St" in address field
type "12345" in zip field
select "California" from state dropdown
click "Continue to Payment"
verify url contains "/payment"

# Test: Apply Discount Code
go to https://shop.example.com/cart
type "SAVE10" in discount code field
click "Apply"
verify page contains "10% off"

Persona Testing

Compare User Experience

# Compare how different users experience signup
npx cbrowser compare-personas \
  --start "https://myapp.com" \
  --goal "Complete account registration" \
  --personas power-user,first-timer,elderly-user,mobile-user \
  --html

Create Custom Persona

# Create persona for your specific users
npx cbrowser persona create "busy professional checking on mobile during commute" --name commuter

# Use it
npx cbrowser explore commuter \
  --start "https://myapp.com" \
  --goal "Check latest notifications"

Accessibility Testing

# Test with screen reader user
npx cbrowser explore screen-reader-user \
  --start "https://myapp.com" \
  --goal "Navigate to pricing page"

Cognitive User Simulation (v10.0.0)

Basic Cognitive Journey

# Simulate a first-timer trying to sign up
npx cbrowser cognitive-journey \
  --persona first-timer \
  --start "https://example.com" \
  --goal "create an account"

With Vision Mode

Vision mode sends screenshots to Claude for better visual understanding. Vision is enabled by default β€” use --no-vision to disable it for faster execution when visual context isn't needed:

# Vision is on by default, --vision flag is optional (shown for clarity)
npx cbrowser cognitive-journey \
  --persona elderly-user \
  --start "https://example.com" \
  --goal "find the help page" \
  --verbose

All Options

# Vision is enabled by default; use --no-vision to disable
npx cbrowser cognitive-journey \
  --persona mobile-user \
  --start "https://shop.example.com" \
  --goal "add a product to cart" \
  --max-steps 50 \
  --max-time 180 \
  --headless \
  --verbose

With Location Override (v18.9.0)

Simulate users from specific geographic regions:

# Simulate a user in Tokyo, Japan
npx cbrowser cognitive-journey \
  --persona first-timer \
  --start "https://example.com" \
  --goal "complete checkout" \
  --timezone "Asia/Tokyo" \
  --locale "ja-JP" \
  --geolocation "35.6762,139.6503"
# Simulate a user in New York
npx cbrowser cognitive-journey \
  --persona elderly-user \
  --start "https://bank.example.com" \
  --goal "transfer money" \
  --timezone "America/New_York" \
  --locale "en-US" \
  --geolocation "40.7128,-74.0060"
# Vision is enabled by default
// TypeScript API with location
import { runCognitiveJourney } from 'cbrowser';

const result = await runCognitiveJourney({
  persona: 'first-timer',
  startUrl: 'https://myapp.com',
  goal: 'sign up for a free trial',
  location: {
    timezone: 'Europe/London',
    locale: 'en-GB',
    geolocation: { latitude: 51.5074, longitude: -0.1278 }
  },
  vision: true,
});

Location Priority: Explicit override > Persona default > CBrowser default (America/Denver)

Daemon Mode for Manual Journeys

Keep browser open between commands:

# Start persistent session
npx cbrowser daemon start

# Navigate
npx cbrowser navigate "https://example.com"

# Interact with dropdowns (hover reveals menu)
npx cbrowser hover "Products"
npx cbrowser click "Software"

# Fill forms
npx cbrowser fill "email" "[email protected]"

# Take screenshots
npx cbrowser screenshot step-3.png

# Stop daemon when done
npx cbrowser daemon stop

Cognitive Journey with TypeScript

import { runCognitiveJourney } from 'cbrowser';

const result = await runCognitiveJourney({
  persona: 'first-timer',
  startUrl: 'https://myapp.com',
  goal: 'complete registration',
  vision: true,
  maxSteps: 30,
  maxTime: 120,
});

if (result.goalAchieved) {
  console.log('Goal achieved!');
  console.log(`Steps: ${result.steps.length}`);
  console.log(`Time: ${result.totalTime}s`);
} else {
  console.log(`Abandoned: ${result.abandonmentReason}`);
  console.log('Friction points:');
  result.frictionPoints.forEach(fp => {
    console.log(`  - ${fp.description} (frustration: +${fp.frustrationIncrease})`);
  });
}

Compare Multiple Personas

# See how different users experience your site
npx cbrowser compare-personas \
  --start "https://myapp.com/signup" \
  --goal "complete registration" \
  --personas power-user,first-timer,elderly-user \
  --html
# Vision is enabled by default

Available Personas (21 total)

Cognitive (6):

Persona Key Traits
power-user High comprehension (0.95), low patience (0.4)
first-timer Low comprehension (0.3), medium patience (0.6)
mobile-user Quick taps, exploratory attention
screen-reader-user Sequential attention, keyboard nav
elderly-user High patience (0.9), low comprehension (0.2)
impatient-user Low patience (0.2), impulsive decisions

Accessibility (11): motor-impairment-tremor, low-vision-magnified, cognitive-adhd, dyslexic-user, deaf-user, elderly-low-vision, color-blind-deuteranopia, autism-spectrum, intellectual-disability, aphasia-receptive, dyscalculia

Emotional (4): anxious-user, confident-user, emotional-user, stoic-user

See Persona-Index for full details on each persona.

Decision Fatigue Metrics (v9.9.0)

Track how decision overload affects user behavior:

import { runCognitiveJourney } from 'cbrowser';

const result = await runCognitiveJourney({
  persona: 'first-timer',
  startUrl: 'https://myapp.com/signup',
  goal: 'complete registration',
});

// New v9.9.0 metrics
console.log(`Decisions made: ${result.summary.decisionsMade}`);
console.log(`Decision fatigue: ${(result.summary.finalDecisionFatigue * 100).toFixed(0)}%`);

if (result.summary.wasChoosingDefaults) {
  console.log('⚠️ User started choosing defaults due to fatigue');
}

CLI output now shows decision fatigue:

🎭 COGNITIVE JOURNEY COMPLETE
...
   Decisions made: 12
   Decision fatigue: 67%
   ⚠️  Was choosing defaults (high fatigue)

Fitts' Law Motor Timing (v9.9.0)

Mouse movement timing based on target distance and size:

# Elderly users show 2x slower mouse movements
npx cbrowser cognitive-journey \
  --persona elderly-user \
  --start "https://example.com" \
  --goal "click the small help icon" \
  --verbose

Output shows realistic motor delays:

━━━ Step 3 ━━━
Moving mouse to small target (48x48 pixels, 450px away)
Fitts' Law: MT = 100 + 150 Γ— logβ‚‚(450/48 + 1) = 612ms
Age modifier: 1.8x β†’ 1102ms actual delay

Dual-Process Theory (v10.0.0)

Simulate Kahneman's System 1 (automatic) and System 2 (deliberate) thinking:

import { runCognitiveJourney } from 'cbrowser';

const result = await runCognitiveJourney({
  persona: 'power-user',  // Starts in System 1
  startUrl: 'https://complex-app.com',
  goal: 'configure advanced settings',
  verbose: true,
});

// Experts start fast (System 1), switch to slow (System 2) when confused
console.log(`Time in System 1: ${result.cognitiveMode.timeInSystem1}ms`);
console.log(`Time in System 2: ${result.cognitiveMode.timeInSystem2}ms`);

Verbose output shows cognitive switching:

━━━ Step 5 ━━━
🧠 Switching to System 2 (deliberate thinking)
   Trigger: confusion level 0.72 exceeded threshold 0.6

━━━ Step 8 ━━━
🧠 Returning to System 1 (automatic mode)
   Trigger: confusion dropped to 0.15, last action succeeded

GOMS/KLM Realistic Timing (v10.0.0)

Fill actions now use empirically-derived keystroke timing:

// Typing "[email protected]" as a novice vs expert
// Novice: 500ms/keystroke + 1350ms mental prep = ~9.3s
// Expert: 120ms/keystroke + 600ms mental prep = ~2.5s

const result = await runCognitiveJourney({
  persona: 'elderly-user',  // expertise: 0.3
  startUrl: 'https://myapp.com/signup',
  goal: 'enter email address',
});

// Result includes typing time metrics
console.log(`Typing time: ${result.steps[2].typingTimeMs}ms`);

Flaky Test Management

Find Flaky Tests

# Run tests 10 times to find unreliable ones
npx cbrowser flaky-check tests.txt --runs 10 --output flaky-report.json

Fix Flaky Tests

# Analyze and auto-fix
npx cbrowser repair-tests tests.txt --auto-apply --verify --output fixed-tests.txt

CI/CD Integration

# GitHub Actions
name: Test Suite

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: |
          npm install cbrowser
          npx playwright install chromium

      - name: Run tests
        run: npx cbrowser test-suite tests.txt --output results.json

      - name: Check for flaky tests
        run: |
          npx cbrowser flaky-check tests.txt --runs 5 --output flaky.json
          FLAKY=$(cat flaky.json | jq '.summary.flakyTests')
          if [ "$FLAKY" -gt "0" ]; then
            echo "⚠️ Found $FLAKY flaky tests"
            cat flaky.json | jq '.testAnalyses[] | select(.isFlaky) | .testName'
          fi

      - name: Upload results
        uses: actions/upload-artifact@v4
        with:
          name: test-results
          path: |
            results.json
            flaky.json

Session Management

Save Authenticated Session

import { CBrowser } from 'cbrowser';

const browser = new CBrowser({ persistent: true });

// Log in manually or automate it
await browser.navigate('https://myapp.com/login');
await browser.fill('email', '[email protected]');
await browser.fill('password', 'mypassword');
await browser.smartClick('Sign In');

// Wait for dashboard
await browser.assert("url contains '/dashboard'");

// Save the session for later
await browser.saveSession('myapp-logged-in');
await browser.close();

Reuse Session

const browser = new CBrowser({ persistent: true });

// Load saved session
await browser.loadSession('myapp-logged-in');

// Now you're already logged in
await browser.navigate('https://myapp.com/settings');
// No login required!

await browser.close();

Data Extraction

Scrape Product Data

npx cbrowser extract "all product names and prices" \
  --url "https://shop.example.com/category/electronics" \
  --format json

Extract Article Content

const browser = new CBrowser();
await browser.navigate('https://blog.example.com/post/123');

const result = await browser.extract('the main article text');
console.log(result.data);

await browser.close();

Page Analysis

Analyze Before Testing

# Understand page structure first
npx cbrowser analyze "https://myapp.com/login"

Output:

πŸ“Š Page Analysis:
   Title: Login - MyApp
   Forms: 1
     - form#login-form (3 fields)
       - email (input[type=email])
       - password (input[type=password])
       - remember (checkbox)
       πŸ” Login form detected
   Buttons: 2
     - "Sign In" (primary)
     - "Forgot Password" (link)
   Links: 5
   Has Social Login: βœ… (Google, GitHub)
   Has CAPTCHA: ❌

Generate Tests from Analysis

npx cbrowser generate-tests "https://myapp.com/login" --output login-tests.txt

Performance Testing

Check Core Web Vitals

npx cbrowser perf "https://myapp.com" --budget-lcp 2500 --budget-cls 0.1

Output:

πŸ“Š Performance Report: https://myapp.com

Core Web Vitals:
  LCP: 1,823ms βœ… (budget: 2,500ms)
  FID: 12ms βœ…
  CLS: 0.05 βœ… (budget: 0.1)

Additional Metrics:
  TTFB: 245ms
  FCP: 892ms
  TTI: 2,134ms
  Total Blocking Time: 89ms

Resources:
  Total Size: 1.2MB
  Scripts: 450KB (8 files)
  Styles: 120KB (3 files)
  Images: 580KB (12 files)

Complete Workflow Example

import {
  CBrowser,
  parseNLTestSuite,
  runNLTestSuite,
  detectFlakyTests,
  repairTestSuite,
  comparePersonas,
} from 'cbrowser';

async function fullTestWorkflow() {
  // 1. Create test suite
  const suite = parseNLTestSuite(`
    # Test: Homepage loads
    go to https://myapp.com
    verify title contains "MyApp"
    verify page contains "Get Started"

    # Test: Navigation works
    go to https://myapp.com
    click "Features"
    verify url contains "/features"
    verify page contains "Our Features"

    # Test: Contact form
    go to https://myapp.com/contact
    type "Test User" in name field
    type "[email protected]" in email field
    type "This is a test message" in message field
    click "Send"
    verify page contains "Thank you"
  `, "MyApp E2E Tests");

  // 2. Run tests
  console.log('Running tests...');
  const testResult = await runNLTestSuite(suite, {
    continueOnFailure: true,
    screenshotOnFailure: true,
  });
  console.log(`Pass rate: ${testResult.summary.passRate}%`);

  // 3. Check for flaky tests
  console.log('Checking for flaky tests...');
  const flakyResult = await detectFlakyTests(suite, { runs: 5 });
  if (flakyResult.summary.flakyTests > 0) {
    console.log(`Found ${flakyResult.summary.flakyTests} flaky tests`);
  }

  // 4. Repair any failures
  if (testResult.summary.failed > 0) {
    console.log('Attempting repairs...');
    const repairResult = await repairTestSuite(suite, {
      autoApply: true,
      verifyRepairs: true,
    });
    console.log(`Repaired: ${repairResult.summary.repaired} tests`);
  }

  // 5. Compare user experiences
  console.log('Running persona comparison...');
  const comparison = await comparePersonas({
    startUrl: 'https://myapp.com',
    goal: 'Navigate to pricing and understand costs',
    personas: ['power-user', 'first-timer', 'elderly-user'],
  });

  for (const result of comparison.results) {
    console.log(`${result.persona}: ${result.success ? 'SUCCESS' : 'FAILED'}`);
    console.log(`  Time: ${result.totalTime}ms`);
    console.log(`  Friction: ${result.frictionPoints.length} points`);
  }
}

fullTestWorkflow().catch(console.error);

Related


Copyright: (c) 2026 Alexa Eden.

License: MIT License

Contact: [email protected]

From the Blog