Files
2025-11-30 09:03:44 +08:00

19 KiB

Advanced Examples

Complex workflows and advanced usage patterns for chrome-devtools.

Table of Contents


E2E Testing Workflows

Complete User Registration Flow

Test full registration process with validation:

#!/bin/bash
# test_registration.sh

echo "Starting registration flow test..."

# 1. Open registration page
node scripts/new_page.js --url https://example.com/register

# 2. Wait for page load
node scripts/wait_for.js --text "Create Account" --timeout 10000

# 3. Get form structure
node scripts/take_snapshot.js --filePath registration_form.txt

# 4. Fill registration form (update UIDs from snapshot)
node scripts/fill_form.js --elements '[
  {"uid":"input_firstname","value":"John"},
  {"uid":"input_lastname","value":"Doe"},
  {"uid":"input_email","value":"john.doe@example.com"},
  {"uid":"input_password","value":"SecurePass123!"},
  {"uid":"input_password_confirm","value":"SecurePass123!"},
  {"uid":"select_country","value":"United States"}
]'

# 5. Screenshot before submission
node scripts/take_screenshot.js --filePath before_submit.png

# 6. Accept terms checkbox
node scripts/click.js --uid checkbox_terms

# 7. Submit form
node scripts/click.js --uid button_register

# 8. Wait for success message
if node scripts/wait_for.js --text "Registration successful" --timeout 15000; then
  echo "✓ Registration succeeded"

  # 9. Capture success state
  node scripts/take_screenshot.js --filePath registration_success.png
  node scripts/take_snapshot.js --filePath success_page.txt

  # 10. Check for welcome email notification
  node scripts/wait_for.js --text "Verification email sent" --timeout 5000

  echo "✓ Test passed: Registration flow complete"
  exit 0
else
  echo "✗ Registration failed"

  # Capture error state
  node scripts/take_screenshot.js --filePath registration_error.png
  node scripts/list_console_messages.js --types error > console_errors.txt

  echo "✗ Test failed: See error screenshots and logs"
  exit 1
fi

Shopping Cart Checkout Flow

Test complete e-commerce checkout:

#!/bin/bash
# test_checkout.sh

echo "Testing checkout flow..."

# 1. Navigate to product page
node scripts/new_page.js --url https://example.com/products/widget-123

# 2. Wait and verify product loads
node scripts/wait_for.js --text "Add to Cart" --timeout 10000
node scripts/take_snapshot.js > product_page.txt

# 3. Add to cart
node scripts/click.js --uid button_add_to_cart
node scripts/wait_for.js --text "Added to cart" --timeout 5000

# 4. Go to cart
node scripts/click.js --uid link_view_cart
node scripts/wait_for.js --text "Shopping Cart" --timeout 5000

# 5. Verify cart contents
node scripts/take_snapshot.js --filePath cart_contents.txt
node scripts/evaluate_script.js --function "() => document.querySelector('.cart-total').textContent" > cart_total.txt

# 6. Proceed to checkout
node scripts/click.js --uid button_checkout
node scripts/wait_for.js --text "Shipping Information" --timeout 10000

# 7. Fill shipping info
node scripts/fill_form.js --elements '[
  {"uid":"input_address","value":"123 Main Street"},
  {"uid":"input_city","value":"San Francisco"},
  {"uid":"input_state","value":"CA"},
  {"uid":"input_zip","value":"94102"}
]'

# 8. Continue to payment
node scripts/click.js --uid button_continue
node scripts/wait_for.js --text "Payment Method" --timeout 10000

# 9. Select payment method
node scripts/click.js --uid radio_credit_card

# 10. Fill payment info (test mode)
node scripts/fill_form.js --elements '[
  {"uid":"input_card_number","value":"4242424242424242"},
  {"uid":"input_card_expiry","value":"12/25"},
  {"uid":"input_card_cvc","value":"123"}
]'

# 11. Place order
node scripts/click.js --uid button_place_order
node scripts/wait_for.js --text "Order Confirmed" --timeout 20000

# 12. Capture confirmation
node scripts/take_screenshot.js --filePath order_confirmation.png
node scripts/evaluate_script.js --function "() => ({orderNumber: document.querySelector('.order-number').textContent, total: document.querySelector('.order-total').textContent})" > order_details.json

echo "✓ Checkout flow completed successfully"

Web Scraping Patterns

Multi-Page Data Extraction

Scrape data across paginated results:

#!/bin/bash
# scrape_listings.sh

BASE_URL="https://example.com/listings"
OUTPUT_FILE="all_listings.json"
MAX_PAGES=10

echo "[" > $OUTPUT_FILE

for page in $(seq 1 $MAX_PAGES); do
  echo "Scraping page $page..."

  # Navigate to page
  if [ $page -eq 1 ]; then
    node scripts/new_page.js --url "$BASE_URL"
  else
    node scripts/navigate_page.js --url "$BASE_URL?page=$page"
  fi

  # Wait for listings to load
  node scripts/wait_for.js --text "listings found" --timeout 10000

  # Extract listings data
  LISTINGS=$(node scripts/evaluate_script.js --function "() => Array.from(document.querySelectorAll('.listing')).map(item => ({
    title: item.querySelector('.title').textContent.trim(),
    price: item.querySelector('.price').textContent.trim(),
    location: item.querySelector('.location').textContent.trim(),
    url: item.querySelector('a').href
  }))")

  # Append to output (remove outer brackets)
  echo "$LISTINGS" | jq '.[]' >> $OUTPUT_FILE

  # Check if there's a next page
  HAS_NEXT=$(node scripts/evaluate_script.js --function "() => document.querySelector('.pagination .next') !== null")

  if [ "$HAS_NEXT" != "true" ]; then
    echo "Reached last page at page $page"
    break
  fi

  # Add comma separator
  if [ $page -lt $MAX_PAGES ]; then
    echo "," >> $OUTPUT_FILE
  fi

  # Be polite: wait between requests
  sleep 2
done

echo "]" >> $OUTPUT_FILE

echo "✓ Scraped listings saved to $OUTPUT_FILE"

# Summary statistics
TOTAL=$(cat $OUTPUT_FILE | jq 'length')
echo "Total listings extracted: $TOTAL"

Dynamic Content Scraping with Infinite Scroll

Extract data from infinite scroll pages:

#!/bin/bash
# scrape_infinite_scroll.sh

echo "Scraping infinite scroll content..."

# Open page
node scripts/new_page.js --url https://example.com/feed

# Wait for initial content
node scripts/wait_for.js --text "Post" --timeout 10000

# Initialize
PREVIOUS_COUNT=0
SCROLL_ATTEMPTS=0
MAX_SCROLLS=20
OUTPUT_FILE="feed_items.json"

while [ $SCROLL_ATTEMPTS -lt $MAX_SCROLLS ]; do
  # Count current items
  CURRENT_COUNT=$(node scripts/evaluate_script.js --function "() => document.querySelectorAll('.feed-item').length")

  echo "Scroll $SCROLL_ATTEMPTS: Found $CURRENT_COUNT items"

  # Check if we got new items
  if [ "$CURRENT_COUNT" -eq "$PREVIOUS_COUNT" ]; then
    echo "No new items loaded, reached end"
    break
  fi

  PREVIOUS_COUNT=$CURRENT_COUNT

  # Scroll to bottom
  node scripts/evaluate_script.js --function "() => window.scrollTo(0, document.body.scrollHeight)"

  # Wait for new content to load
  sleep 2

  SCROLL_ATTEMPTS=$((SCROLL_ATTEMPTS + 1))
done

# Extract all items
echo "Extracting all $CURRENT_COUNT items..."

node scripts/evaluate_script.js --function "() => Array.from(document.querySelectorAll('.feed-item')).map(item => ({
  author: item.querySelector('.author').textContent.trim(),
  content: item.querySelector('.content').textContent.trim(),
  timestamp: item.querySelector('.timestamp').textContent.trim(),
  likes: item.querySelector('.likes').textContent.trim()
}))" > $OUTPUT_FILE

echo "✓ Extracted $CURRENT_COUNT items to $OUTPUT_FILE"

Performance Optimization

Automated Performance Regression Testing

Compare performance across builds:

#!/bin/bash
# performance_regression_test.sh

BASELINE_URL="https://staging.example.com"
CURRENT_URL="https://production.example.com"

echo "Running performance regression tests..."

# Test baseline (staging)
echo "Testing baseline: $BASELINE_URL"

node scripts/new_page.js --url "$BASELINE_URL"
node scripts/performance_start_trace.js --reload true --autoStop false
node scripts/wait_for.js --text "Ready" --timeout 30000
node scripts/performance_stop_trace.js > baseline_trace.json

BASELINE_LCP=$(cat baseline_trace.json | jq -r '.metrics.LCP.value')
BASELINE_FID=$(cat baseline_trace.json | jq -r '.metrics.FID.value')
BASELINE_CLS=$(cat baseline_trace.json | jq -r '.metrics.CLS.value')

echo "Baseline: LCP=$BASELINE_LCP, FID=$BASELINE_FID, CLS=$BASELINE_CLS"

# Test current (production)
echo "Testing current: $CURRENT_URL"

node scripts/navigate_page.js --url "$CURRENT_URL"
node scripts/performance_start_trace.js --reload true --autoStop false
node scripts/wait_for.js --text "Ready" --timeout 30000
node scripts/performance_stop_trace.js > current_trace.json

CURRENT_LCP=$(cat current_trace.json | jq -r '.metrics.LCP.value')
CURRENT_FID=$(cat current_trace.json | jq -r '.metrics.FID.value')
CURRENT_CLS=$(cat current_trace.json | jq -r '.metrics.CLS.value')

echo "Current: LCP=$CURRENT_LCP, FID=$CURRENT_FID, CLS=$CURRENT_CLS"

# Compare (allow 10% regression threshold)
THRESHOLD=1.1
FAILED=false

LCP_RATIO=$(echo "scale=2; $CURRENT_LCP / $BASELINE_LCP" | bc)
if (( $(echo "$LCP_RATIO > $THRESHOLD" | bc -l) )); then
  echo "✗ LCP regression detected: ${CURRENT_LCP}ms vs ${BASELINE_LCP}ms"
  FAILED=true
else
  echo "✓ LCP within threshold"
fi

FID_RATIO=$(echo "scale=2; $CURRENT_FID / $BASELINE_FID" | bc)
if (( $(echo "$FID_RATIO > $THRESHOLD" | bc -l) )); then
  echo "✗ FID regression detected: ${CURRENT_FID}ms vs ${BASELINE_FID}ms"
  FAILED=true
else
  echo "✓ FID within threshold"
fi

CLS_RATIO=$(echo "scale=2; $CURRENT_CLS / $BASELINE_CLS" | bc)
if (( $(echo "$CLS_RATIO > $THRESHOLD" | bc -l) )); then
  echo "✗ CLS regression detected: ${CURRENT_CLS} vs ${BASELINE_CLS}"
  FAILED=true
else
  echo "✓ CLS within threshold"
fi

if [ "$FAILED" = true ]; then
  echo "Performance regression test FAILED"
  exit 1
else
  echo "Performance regression test PASSED"
  exit 0
fi

Network Performance Testing Matrix

Test performance across network conditions:

#!/bin/bash
# network_performance_matrix.sh

URL="https://example.com"
OUTPUT_DIR="performance_results"

mkdir -p $OUTPUT_DIR

# Define network profiles
declare -A NETWORKS
NETWORKS["fast"]='{"downloadThroughput":10000000,"uploadThroughput":10000000,"latency":10}'
NETWORKS["4g"]='{"downloadThroughput":1600000,"uploadThroughput":750000,"latency":150}'
NETWORKS["3g"]='{"downloadThroughput":180000,"uploadThroughput":84000,"latency":562}'
NETWORKS["slow-3g"]='{"downloadThroughput":50000,"uploadThroughput":50000,"latency":2000}'

echo "Testing performance across network conditions..."

# Open page once
node scripts/new_page.js --url "$URL"

for profile in "${!NETWORKS[@]}"; do
  echo "Testing network profile: $profile"

  # Apply network emulation
  node scripts/emulate.js --networkConditions "${NETWORKS[$profile]}"

  # Run performance trace
  node scripts/performance_start_trace.js --reload true --autoStop false
  node scripts/wait_for.js --text "Ready" --timeout 60000
  node scripts/performance_stop_trace.js > "$OUTPUT_DIR/${profile}_trace.json"

  # Extract key metrics
  LCP=$(cat "$OUTPUT_DIR/${profile}_trace.json" | jq -r '.metrics.LCP.value')
  FID=$(cat "$OUTPUT_DIR/${profile}_trace.json" | jq -r '.metrics.FID.value')
  CLS=$(cat "$OUTPUT_DIR/${profile}_trace.json" | jq -r '.metrics.CLS.value')

  echo "$profile: LCP=${LCP}ms, FID=${FID}ms, CLS=$CLS"

  # Capture screenshot
  node scripts/take_screenshot.js --filePath "$OUTPUT_DIR/${profile}_loaded.png"
done

# Reset to normal
node scripts/emulate.js --cpuThrottlingRate 1

echo "✓ Performance testing complete. Results in $OUTPUT_DIR/"

CI/CD Integration

GitHub Actions Workflow

# .github/workflows/e2e-tests.yml
name: E2E Tests

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  e2e-tests:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3

    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'

    - name: Install mcp2skill-tools
      run: |
        npm install -g mcp2skill-tools

    - name: Start mcp2rest
      run: |
        mcp2rest start
        mcp2rest add chrome-devtools

    - name: Install skill dependencies
      run: |
        cd ~/.claude/skills/mcp-chrome-devtools/scripts
        npm install

    - name: Run E2E tests
      run: |
        cd tests
        bash test_registration.sh
        bash test_checkout.sh
        bash test_search.sh

    - name: Upload test artifacts
      if: always()
      uses: actions/upload-artifact@v3
      with:
        name: test-results
        path: |
          **/*.png
          **/*.txt
          **/*.json

    - name: Stop mcp2rest
      if: always()
      run: mcp2rest stop

Jenkins Pipeline

// Jenkinsfile
pipeline {
    agent any

    environment {
        NODE_VERSION = '18'
    }

    stages {
        stage('Setup') {
            steps {
                sh 'npm install -g mcp2skill-tools'
                sh 'mcp2rest start'
                sh 'mcp2rest add chrome-devtools'
            }
        }

        stage('Install Dependencies') {
            steps {
                dir('~/.claude/skills/mcp-chrome-devtools/scripts') {
                    sh 'npm install'
                }
            }
        }

        stage('E2E Tests') {
            parallel {
                stage('Registration Flow') {
                    steps {
                        sh 'bash tests/test_registration.sh'
                    }
                }
                stage('Checkout Flow') {
                    steps {
                        sh 'bash tests/test_checkout.sh'
                    }
                }
                stage('Search Flow') {
                    steps {
                        sh 'bash tests/test_search.sh'
                    }
                }
            }
        }

        stage('Performance Tests') {
            steps {
                sh 'bash tests/performance_regression_test.sh'
            }
        }
    }

    post {
        always {
            archiveArtifacts artifacts: '**/*.png,**/*.txt,**/*.json', allowEmptyArchive: true
            sh 'mcp2rest stop'
        }
        failure {
            emailext (
                subject: "E2E Tests Failed: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
                body: "Check console output at ${env.BUILD_URL}",
                to: "team@example.com"
            )
        }
    }
}

Cross-Browser Testing Simulation

Device Emulation Matrix

#!/bin/bash
# device_matrix_test.sh

URL="https://example.com"
OUTPUT_DIR="device_screenshots"

mkdir -p $OUTPUT_DIR

# Define device viewports
declare -A DEVICES
DEVICES["desktop_1080"]="1920 1080"
DEVICES["desktop_720"]="1280 720"
DEVICES["laptop"]="1366 768"
DEVICES["ipad_portrait"]="768 1024"
DEVICES["ipad_landscape"]="1024 768"
DEVICES["iphone_portrait"]="375 667"
DEVICES["iphone_landscape"]="667 375"
DEVICES["android_portrait"]="360 640"
DEVICES["android_landscape"]="640 360"

echo "Testing across device viewports..."

# Open page
node scripts/new_page.js --url "$URL"

for device in "${!DEVICES[@]}"; do
  echo "Testing device: $device"

  # Parse dimensions
  read -r width height <<< "${DEVICES[$device]}"

  # Resize window
  node scripts/resize_page.js --width $width --height $height

  # Wait for reflow
  sleep 2

  # Capture screenshot
  node scripts/take_screenshot.js --fullPage true --filePath "$OUTPUT_DIR/${device}.png"

  # Capture snapshot for debugging
  node scripts/take_snapshot.js --filePath "$OUTPUT_DIR/${device}_snapshot.txt"
done

echo "✓ Device matrix testing complete. Screenshots in $OUTPUT_DIR/"

Advanced JavaScript Extraction

Extract Structured Data from SPA

#!/bin/bash
# extract_spa_data.sh

echo "Extracting data from Single Page Application..."

# Open SPA
node scripts/new_page.js --url https://example.com/dashboard

# Wait for app to initialize
node scripts/wait_for.js --text "Dashboard" --timeout 15000

# Wait for data to load (check for spinner to disappear)
node scripts/evaluate_script.js --function "() => new Promise(resolve => {
  const checkSpinner = setInterval(() => {
    if (!document.querySelector('.loading-spinner')) {
      clearInterval(checkSpinner);
      resolve(true);
    }
  }, 100);
})"

# Extract React/Vue component state
APP_STATE=$(node scripts/evaluate_script.js --function "() => {
  // Try to access React DevTools state
  const root = document.querySelector('#root');
  const reactInternals = root._reactRootContainer || root._reactInternalFiber;

  // Or access Vue instance
  const vueInstance = root.__vue__;

  // Extract data from global state (Redux, Vuex, etc.)
  return {
    redux: window.__REDUX_DEVTOOLS_EXTENSION__ ? window.store.getState() : null,
    vuex: window.__VUEX_DEVTOOLS_GLOBAL_HOOK__ ? window.$store.state : null,
    // Or extract directly from DOM
    domData: Array.from(document.querySelectorAll('.data-item')).map(item => ({
      id: item.dataset.id,
      title: item.querySelector('.title').textContent,
      value: item.querySelector('.value').textContent
    }))
  };
}")

echo "$APP_STATE" | jq '.' > app_state.json

echo "✓ Extracted application state to app_state.json"

Monitor Real-Time Updates

#!/bin/bash
# monitor_realtime_updates.sh

echo "Monitoring real-time updates..."

# Open page with real-time data
node scripts/new_page.js --url https://example.com/live-feed

# Set up monitoring script
node scripts/evaluate_script.js --function "() => {
  window.updates = [];
  window.observer = new MutationObserver(mutations => {
    mutations.forEach(mutation => {
      if (mutation.type === 'childList') {
        mutation.addedNodes.forEach(node => {
          if (node.classList && node.classList.contains('update-item')) {
            window.updates.push({
              timestamp: new Date().toISOString(),
              content: node.textContent,
              type: node.dataset.type
            });
          }
        });
      }
    });
  });

  const container = document.querySelector('.updates-container');
  window.observer.observe(container, { childList: true, subtree: true });

  return 'Monitoring started';
}"

# Wait for updates to accumulate
echo "Collecting updates for 60 seconds..."
sleep 60

# Retrieve collected updates
UPDATES=$(node scripts/evaluate_script.js --function "() => window.updates")

echo "$UPDATES" | jq '.' > realtime_updates.json

# Clean up
node scripts/evaluate_script.js --function "() => { window.observer.disconnect(); return 'Monitoring stopped'; }"

echo "✓ Collected updates saved to realtime_updates.json"

Complex Workflow Orchestration

Multi-User Simulation

#!/bin/bash
# simulate_multi_user.sh

echo "Simulating multi-user interactions..."

# User 1: Admin workflow
(
  echo "User 1: Admin actions"
  node scripts/new_page.js --url https://example.com/admin
  node scripts/wait_for.js --text "Admin Panel" --timeout 10000
  # ... admin actions ...
) &

# User 2: Customer workflow
(
  echo "User 2: Customer actions"
  node scripts/new_page.js --url https://example.com/shop
  node scripts/wait_for.js --text "Products" --timeout 10000
  # ... customer actions ...
) &

# Wait for both users to complete
wait

echo "✓ Multi-user simulation complete"

This advanced examples reference provides production-ready patterns for complex automation, testing, and data extraction workflows.