Initial commit
This commit is contained in:
737
skills/mcp-chrome-devtools/reference/advanced-examples.md
Normal file
737
skills/mcp-chrome-devtools/reference/advanced-examples.md
Normal file
@@ -0,0 +1,737 @@
|
||||
# Advanced Examples
|
||||
|
||||
Complex workflows and advanced usage patterns for chrome-devtools.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [E2E Testing Workflows](#e2e-testing-workflows)
|
||||
- [Web Scraping Patterns](#web-scraping-patterns)
|
||||
- [Performance Optimization](#performance-optimization)
|
||||
- [CI/CD Integration](#cicd-integration)
|
||||
- [Cross-Browser Testing Simulation](#cross-browser-testing-simulation)
|
||||
- [Advanced JavaScript Extraction](#advanced-javascript-extraction)
|
||||
|
||||
---
|
||||
|
||||
## E2E Testing Workflows
|
||||
|
||||
### Complete User Registration Flow
|
||||
|
||||
Test full registration process with validation:
|
||||
|
||||
```bash
|
||||
#!/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:
|
||||
|
||||
```bash
|
||||
#!/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:
|
||||
|
||||
```bash
|
||||
#!/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:
|
||||
|
||||
```bash
|
||||
#!/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:
|
||||
|
||||
```bash
|
||||
#!/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:
|
||||
|
||||
```bash
|
||||
#!/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
|
||||
|
||||
```yaml
|
||||
# .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
|
||||
|
||||
```groovy
|
||||
// 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
|
||||
|
||||
```bash
|
||||
#!/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
|
||||
|
||||
```bash
|
||||
#!/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
|
||||
|
||||
```bash
|
||||
#!/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
|
||||
|
||||
```bash
|
||||
#!/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.
|
||||
772
skills/mcp-chrome-devtools/reference/all-tools.md
Normal file
772
skills/mcp-chrome-devtools/reference/all-tools.md
Normal file
@@ -0,0 +1,772 @@
|
||||
# Complete Tool Reference
|
||||
|
||||
Alphabetical listing of all 26 chrome-devtools tools with full parameters and examples.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [click](#click)
|
||||
- [close_page](#close_page)
|
||||
- [drag](#drag)
|
||||
- [emulate](#emulate)
|
||||
- [evaluate_script](#evaluate_script)
|
||||
- [fill](#fill)
|
||||
- [fill_form](#fill_form)
|
||||
- [get_console_message](#get_console_message)
|
||||
- [get_network_request](#get_network_request)
|
||||
- [handle_dialog](#handle_dialog)
|
||||
- [hover](#hover)
|
||||
- [list_console_messages](#list_console_messages)
|
||||
- [list_network_requests](#list_network_requests)
|
||||
- [list_pages](#list_pages)
|
||||
- [navigate_page](#navigate_page)
|
||||
- [new_page](#new_page)
|
||||
- [performance_analyze_insight](#performance_analyze_insight)
|
||||
- [performance_start_trace](#performance_start_trace)
|
||||
- [performance_stop_trace](#performance_stop_trace)
|
||||
- [press_key](#press_key)
|
||||
- [resize_page](#resize_page)
|
||||
- [select_page](#select_page)
|
||||
- [take_screenshot](#take_screenshot)
|
||||
- [take_snapshot](#take_snapshot)
|
||||
- [upload_file](#upload_file)
|
||||
- [wait_for](#wait_for)
|
||||
|
||||
---
|
||||
|
||||
## click
|
||||
|
||||
Clicks on an element identified by its UID.
|
||||
|
||||
**Group:** Element Interaction
|
||||
|
||||
**Required Parameters:**
|
||||
- `--uid UID` - Element unique identifier from snapshot
|
||||
|
||||
**Optional Parameters:**
|
||||
- `--dblClick BOOLEAN` - Double click instead of single click (default: false)
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Single click
|
||||
node scripts/click.js --uid button_submit_abc123
|
||||
|
||||
# Double click
|
||||
node scripts/click.js --uid file_icon_xyz789 --dblClick true
|
||||
```
|
||||
|
||||
**Related Tools:** hover, fill, take_snapshot
|
||||
|
||||
---
|
||||
|
||||
## close_page
|
||||
|
||||
Closes a page by its index. Cannot close the last remaining page.
|
||||
|
||||
**Group:** Page Management
|
||||
|
||||
**Required Parameters:**
|
||||
- `--pageIdx NUMBER` - Index of page to close (from list_pages)
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
node scripts/close_page.js --pageIdx 2
|
||||
```
|
||||
|
||||
**Notes:** Always keep at least one page open. Close pages from highest to lowest index to avoid index shifting.
|
||||
|
||||
**Related Tools:** list_pages, new_page, select_page
|
||||
|
||||
---
|
||||
|
||||
## drag
|
||||
|
||||
Drags one element onto another element.
|
||||
|
||||
**Group:** Element Interaction
|
||||
|
||||
**Required Parameters:**
|
||||
- `--from-uid UID` - UID of element to drag
|
||||
- `--to-uid UID` - UID of target drop zone
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
node scripts/drag.js --from-uid task_item_abc --to-uid dropzone_xyz
|
||||
```
|
||||
|
||||
**Related Tools:** hover, click, take_snapshot
|
||||
|
||||
---
|
||||
|
||||
## emulate
|
||||
|
||||
Emulates network conditions and CPU throttling.
|
||||
|
||||
**Group:** Performance Analysis
|
||||
|
||||
**Optional Parameters:**
|
||||
- `--networkConditions JSON` - Network throttling config
|
||||
- `--cpuThrottlingRate NUMBER` - CPU throttling multiplier (1 = normal)
|
||||
|
||||
**Network Conditions Format:**
|
||||
```json
|
||||
{
|
||||
"downloadThroughput": 50000,
|
||||
"uploadThroughput": 50000,
|
||||
"latency": 2000
|
||||
}
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Slow 3G
|
||||
node scripts/emulate.js --networkConditions '{"downloadThroughput":50000,"uploadThroughput":50000,"latency":2000}'
|
||||
|
||||
# 4x CPU slowdown
|
||||
node scripts/emulate.js --cpuThrottlingRate 4
|
||||
|
||||
# Combined
|
||||
node scripts/emulate.js --networkConditions '{"downloadThroughput":100000,"uploadThroughput":50000,"latency":100}' --cpuThrottlingRate 2
|
||||
|
||||
# Reset to normal
|
||||
node scripts/emulate.js --cpuThrottlingRate 1
|
||||
```
|
||||
|
||||
**Common Presets:**
|
||||
- Slow 3G: 50KB/s down, 50KB/s up, 2000ms latency
|
||||
- Fast 3G: 180KB/s down, 84KB/s up, 562ms latency
|
||||
- 4G: 1.6MB/s down, 750KB/s up, 150ms latency
|
||||
|
||||
**Related Tools:** performance_start_trace, performance_stop_trace
|
||||
|
||||
---
|
||||
|
||||
## evaluate_script
|
||||
|
||||
Executes JavaScript in the page context and returns JSON-serializable results.
|
||||
|
||||
**Group:** Performance Analysis
|
||||
|
||||
**Required Parameters:**
|
||||
- `--function STRING` - JavaScript function as string
|
||||
|
||||
**Optional Parameters:**
|
||||
- `--args JSON_ARRAY` - Function arguments as JSON array
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Simple extraction
|
||||
node scripts/evaluate_script.js --function "() => document.title"
|
||||
|
||||
# With parameters
|
||||
node scripts/evaluate_script.js --function "(x, y) => x + y" --args '[5, 3]'
|
||||
|
||||
# Extract array of data
|
||||
node scripts/evaluate_script.js --function "() => Array.from(document.querySelectorAll('h2')).map(h => h.textContent)"
|
||||
|
||||
# Complex object extraction
|
||||
node scripts/evaluate_script.js --function "() => ({title: document.title, links: document.querySelectorAll('a').length})"
|
||||
```
|
||||
|
||||
**Important:** Return values must be JSON-serializable (no DOM nodes, functions, or circular references).
|
||||
|
||||
**Related Tools:** take_snapshot, wait_for
|
||||
|
||||
---
|
||||
|
||||
## fill
|
||||
|
||||
Types text into inputs/textareas or selects dropdown options.
|
||||
|
||||
**Group:** Element Interaction
|
||||
|
||||
**Required Parameters:**
|
||||
- `--uid UID` - Element unique identifier
|
||||
- `--value STRING` - Text to type or option to select
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Text input
|
||||
node scripts/fill.js --uid input_username_abc --value "john.doe"
|
||||
|
||||
# Textarea
|
||||
node scripts/fill.js --uid textarea_comment_def --value "This is a long comment"
|
||||
|
||||
# Dropdown select
|
||||
node scripts/fill.js --uid select_country_ghi --value "United States"
|
||||
```
|
||||
|
||||
**Related Tools:** fill_form, click, take_snapshot
|
||||
|
||||
---
|
||||
|
||||
## fill_form
|
||||
|
||||
Fills multiple form fields at once.
|
||||
|
||||
**Group:** Element Interaction
|
||||
|
||||
**Required Parameters:**
|
||||
- `--elements JSON_ARRAY` - Array of {uid, value} objects
|
||||
|
||||
**Format:**
|
||||
```json
|
||||
[
|
||||
{"uid": "input_email", "value": "test@example.com"},
|
||||
{"uid": "input_password", "value": "secret123"}
|
||||
]
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
node scripts/fill_form.js --elements '[{"uid":"input_email","value":"test@example.com"},{"uid":"input_password","value":"secret123"}]'
|
||||
|
||||
# Multi-line for readability (bash)
|
||||
node scripts/fill_form.js --elements '[
|
||||
{"uid":"input_name","value":"John Doe"},
|
||||
{"uid":"input_email","value":"john@example.com"},
|
||||
{"uid":"select_country","value":"USA"}
|
||||
]'
|
||||
```
|
||||
|
||||
**Related Tools:** fill, click, take_snapshot
|
||||
|
||||
---
|
||||
|
||||
## get_console_message
|
||||
|
||||
Retrieves a specific console message by ID.
|
||||
|
||||
**Group:** Inspection & Debugging
|
||||
|
||||
**Required Parameters:**
|
||||
- `--msgid STRING` - Message ID from list_console_messages
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
node scripts/get_console_message.js --msgid msg_abc123
|
||||
```
|
||||
|
||||
**Related Tools:** list_console_messages
|
||||
|
||||
---
|
||||
|
||||
## get_network_request
|
||||
|
||||
Gets details of a specific network request.
|
||||
|
||||
**Group:** Inspection & Debugging
|
||||
|
||||
**Optional Parameters:**
|
||||
- `--reqid STRING` - Request ID from list_network_requests (if omitted, returns currently selected request in DevTools)
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Specific request
|
||||
node scripts/get_network_request.js --reqid req_abc123
|
||||
|
||||
# Currently selected in DevTools
|
||||
node scripts/get_network_request.js
|
||||
```
|
||||
|
||||
**Output includes:** URL, method, status code, headers, request/response body, timing.
|
||||
|
||||
**Related Tools:** list_network_requests
|
||||
|
||||
---
|
||||
|
||||
## handle_dialog
|
||||
|
||||
Handles browser dialogs (alert, confirm, prompt).
|
||||
|
||||
**Group:** Performance Analysis
|
||||
|
||||
**Required Parameters:**
|
||||
- `--action STRING` - Either "accept" or "dismiss"
|
||||
|
||||
**Optional Parameters:**
|
||||
- `--promptText STRING` - Text to enter in prompt dialog (only for prompts)
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Accept alert
|
||||
node scripts/handle_dialog.js --action accept
|
||||
|
||||
# Dismiss confirm
|
||||
node scripts/handle_dialog.js --action dismiss
|
||||
|
||||
# Accept prompt with input
|
||||
node scripts/handle_dialog.js --action accept --promptText "My Answer"
|
||||
```
|
||||
|
||||
**Notes:** Dialog must already be open when calling this tool.
|
||||
|
||||
**Related Tools:** click, wait_for
|
||||
|
||||
---
|
||||
|
||||
## hover
|
||||
|
||||
Hovers the mouse over an element.
|
||||
|
||||
**Group:** Element Interaction
|
||||
|
||||
**Required Parameters:**
|
||||
- `--uid UID` - Element unique identifier
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
node scripts/hover.js --uid tooltip_trigger_abc
|
||||
|
||||
# Common pattern: hover then click
|
||||
node scripts/hover.js --uid menu_trigger_xyz
|
||||
node scripts/click.js --uid menu_item_settings
|
||||
```
|
||||
|
||||
**Use Cases:** Triggering tooltips, dropdown menus, hover effects.
|
||||
|
||||
**Related Tools:** click, take_snapshot
|
||||
|
||||
---
|
||||
|
||||
## list_console_messages
|
||||
|
||||
Lists console messages (logs, warnings, errors) from the current page.
|
||||
|
||||
**Group:** Inspection & Debugging
|
||||
|
||||
**Optional Parameters:**
|
||||
- `--pageSize NUMBER` - Number of messages per page
|
||||
- `--pageIdx NUMBER` - Page index for pagination (0-based)
|
||||
- `--types STRING` - Comma-separated types: log,warn,error,info
|
||||
- `--includePreservedMessages BOOLEAN` - Include messages from before current navigation
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# All messages
|
||||
node scripts/list_console_messages.js
|
||||
|
||||
# Only errors
|
||||
node scripts/list_console_messages.js --types error
|
||||
|
||||
# Errors and warnings
|
||||
node scripts/list_console_messages.js --types error,warn
|
||||
|
||||
# Paginated
|
||||
node scripts/list_console_messages.js --pageSize 10 --pageIdx 0
|
||||
```
|
||||
|
||||
**Related Tools:** get_console_message
|
||||
|
||||
---
|
||||
|
||||
## list_network_requests
|
||||
|
||||
Lists network requests made by the current page.
|
||||
|
||||
**Group:** Inspection & Debugging
|
||||
|
||||
**Optional Parameters:**
|
||||
- `--pageSize NUMBER` - Number of requests per page
|
||||
- `--pageIdx NUMBER` - Page index for pagination (0-based)
|
||||
- `--resourceTypes STRING` - Comma-separated types: fetch,xhr,document,script,stylesheet,image
|
||||
- `--includePreservedRequests BOOLEAN` - Include requests from before current navigation
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# All requests
|
||||
node scripts/list_network_requests.js
|
||||
|
||||
# Only API calls
|
||||
node scripts/list_network_requests.js --resourceTypes fetch,xhr
|
||||
|
||||
# Only scripts and stylesheets
|
||||
node scripts/list_network_requests.js --resourceTypes script,stylesheet
|
||||
|
||||
# Paginated
|
||||
node scripts/list_network_requests.js --pageSize 20 --pageIdx 0
|
||||
```
|
||||
|
||||
**Related Tools:** get_network_request
|
||||
|
||||
---
|
||||
|
||||
## list_pages
|
||||
|
||||
Lists all open browser pages with their indices and URLs.
|
||||
|
||||
**Group:** Page Management
|
||||
|
||||
**No Parameters**
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
node scripts/list_pages.js
|
||||
```
|
||||
|
||||
**Output Example:**
|
||||
```
|
||||
Page 0: https://example.com (selected)
|
||||
Page 1: https://google.com
|
||||
Page 2: https://github.com
|
||||
```
|
||||
|
||||
**Related Tools:** new_page, select_page, close_page
|
||||
|
||||
---
|
||||
|
||||
## navigate_page
|
||||
|
||||
Navigates the currently selected page.
|
||||
|
||||
**Group:** Page Management
|
||||
|
||||
**Optional Parameters:**
|
||||
- `--url STRING` - URL to navigate to
|
||||
- `--type STRING` - Navigation type: navigate, reload, back, forward
|
||||
- `--ignoreCache BOOLEAN` - Bypass cache on reload
|
||||
- `--timeout NUMBER` - Navigation timeout in milliseconds
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Navigate to URL
|
||||
node scripts/navigate_page.js --url https://example.com/page2
|
||||
|
||||
# Reload page
|
||||
node scripts/navigate_page.js --type reload
|
||||
|
||||
# Reload ignoring cache
|
||||
node scripts/navigate_page.js --type reload --ignoreCache true
|
||||
|
||||
# Go back
|
||||
node scripts/navigate_page.js --type back
|
||||
|
||||
# Go forward
|
||||
node scripts/navigate_page.js --type forward
|
||||
```
|
||||
|
||||
**Related Tools:** new_page, wait_for
|
||||
|
||||
---
|
||||
|
||||
## new_page
|
||||
|
||||
Creates a new browser page (tab).
|
||||
|
||||
**Group:** Page Management
|
||||
|
||||
**Required Parameters:**
|
||||
- `--url STRING` - URL to open
|
||||
|
||||
**Optional Parameters:**
|
||||
- `--timeout NUMBER` - Page load timeout in milliseconds (default: 30000)
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
node scripts/new_page.js --url https://example.com
|
||||
|
||||
# With longer timeout
|
||||
node scripts/new_page.js --url https://slow-site.com --timeout 60000
|
||||
```
|
||||
|
||||
**Notes:** New page becomes the selected page automatically.
|
||||
|
||||
**Related Tools:** list_pages, select_page, close_page
|
||||
|
||||
---
|
||||
|
||||
## performance_analyze_insight
|
||||
|
||||
Gets detailed information about a specific performance insight.
|
||||
|
||||
**Group:** Performance Analysis
|
||||
|
||||
**Required Parameters:**
|
||||
- `--insightSetId STRING` - Insight set ID from performance trace
|
||||
- `--insightName STRING` - Name of specific insight to analyze
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
node scripts/performance_analyze_insight.js --insightSetId set_abc123 --insightName LargestContentfulPaint
|
||||
|
||||
node scripts/performance_analyze_insight.js --insightSetId set_abc123 --insightName CumulativeLayoutShift
|
||||
```
|
||||
|
||||
**Common Insight Names:**
|
||||
- LargestContentfulPaint
|
||||
- FirstContentfulPaint
|
||||
- CumulativeLayoutShift
|
||||
- TotalBlockingTime
|
||||
- TimeToInteractive
|
||||
|
||||
**Related Tools:** performance_start_trace, performance_stop_trace
|
||||
|
||||
---
|
||||
|
||||
## performance_start_trace
|
||||
|
||||
Starts performance trace recording.
|
||||
|
||||
**Group:** Performance Analysis
|
||||
|
||||
**Required Parameters:**
|
||||
- `--reload BOOLEAN` - Reload page before tracing
|
||||
- `--autoStop BOOLEAN` - Automatically stop when page loads
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Start with page reload
|
||||
node scripts/performance_start_trace.js --reload true --autoStop false
|
||||
|
||||
# Start without reload
|
||||
node scripts/performance_start_trace.js --reload false --autoStop true
|
||||
```
|
||||
|
||||
**Notes:** Only one trace can be active at a time. Call performance_stop_trace to get results.
|
||||
|
||||
**Related Tools:** performance_stop_trace, performance_analyze_insight
|
||||
|
||||
---
|
||||
|
||||
## performance_stop_trace
|
||||
|
||||
Stops the active performance trace and returns results.
|
||||
|
||||
**Group:** Performance Analysis
|
||||
|
||||
**No Parameters**
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
node scripts/performance_stop_trace.js
|
||||
```
|
||||
|
||||
**Output includes:**
|
||||
- Core Web Vitals scores (LCP, FID, CLS)
|
||||
- Performance insights
|
||||
- Insight set IDs for detailed analysis
|
||||
- Timing metrics
|
||||
|
||||
**Related Tools:** performance_start_trace, performance_analyze_insight
|
||||
|
||||
---
|
||||
|
||||
## press_key
|
||||
|
||||
Presses a key or key combination.
|
||||
|
||||
**Group:** Element Interaction
|
||||
|
||||
**Required Parameters:**
|
||||
- `--key STRING` - Key or key combination to press
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Single key
|
||||
node scripts/press_key.js --key Enter
|
||||
node scripts/press_key.js --key Tab
|
||||
node scripts/press_key.js --key Escape
|
||||
|
||||
# Arrow keys
|
||||
node scripts/press_key.js --key ArrowDown
|
||||
node scripts/press_key.js --key ArrowUp
|
||||
|
||||
# Key combinations (use + separator)
|
||||
node scripts/press_key.js --key "Control+S"
|
||||
node scripts/press_key.js --key "Control+Shift+P"
|
||||
node scripts/press_key.js --key "Alt+F4"
|
||||
```
|
||||
|
||||
**Common Keys:** Enter, Tab, Escape, Space, Backspace, Delete, ArrowUp, ArrowDown, ArrowLeft, ArrowRight
|
||||
|
||||
**Modifiers:** Control, Shift, Alt, Meta (Command on Mac)
|
||||
|
||||
**Related Tools:** fill, click
|
||||
|
||||
---
|
||||
|
||||
## resize_page
|
||||
|
||||
Resizes the browser window to specific dimensions.
|
||||
|
||||
**Group:** Page Management
|
||||
|
||||
**Required Parameters:**
|
||||
- `--width NUMBER` - Width in pixels
|
||||
- `--height NUMBER` - Height in pixels
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Desktop
|
||||
node scripts/resize_page.js --width 1920 --height 1080
|
||||
|
||||
# Laptop
|
||||
node scripts/resize_page.js --width 1366 --height 768
|
||||
|
||||
# Tablet
|
||||
node scripts/resize_page.js --width 768 --height 1024
|
||||
|
||||
# Mobile
|
||||
node scripts/resize_page.js --width 375 --height 667
|
||||
```
|
||||
|
||||
**Common Dimensions:**
|
||||
- Desktop: 1920x1080, 1440x900, 1366x768
|
||||
- Tablet: 768x1024 (iPad), 600x960
|
||||
- Mobile: 375x667 (iPhone), 360x640 (Android)
|
||||
|
||||
**Related Tools:** take_screenshot, emulate
|
||||
|
||||
---
|
||||
|
||||
## select_page
|
||||
|
||||
Switches the active context to a specific page.
|
||||
|
||||
**Group:** Page Management
|
||||
|
||||
**Required Parameters:**
|
||||
- `--pageIdx NUMBER` - Page index from list_pages
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
node scripts/select_page.js --pageIdx 0
|
||||
node scripts/select_page.js --pageIdx 2
|
||||
```
|
||||
|
||||
**Notes:** All subsequent commands operate on the selected page.
|
||||
|
||||
**Related Tools:** list_pages, new_page
|
||||
|
||||
---
|
||||
|
||||
## take_screenshot
|
||||
|
||||
Captures a visual screenshot of the page or element.
|
||||
|
||||
**Group:** Inspection & Debugging
|
||||
|
||||
**Optional Parameters:**
|
||||
- `--format STRING` - Image format: png or jpeg (default: png)
|
||||
- `--quality NUMBER` - JPEG quality 0-100 (default: 90)
|
||||
- `--uid STRING` - Element UID to screenshot (if omitted, screenshots viewport)
|
||||
- `--fullPage BOOLEAN` - Capture full scrollable page (default: false)
|
||||
- `--filePath STRING` - Path to save image file
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Full page PNG
|
||||
node scripts/take_screenshot.js --fullPage true --filePath page.png
|
||||
|
||||
# Viewport only
|
||||
node scripts/take_screenshot.js --filePath viewport.png
|
||||
|
||||
# Specific element
|
||||
node scripts/take_screenshot.js --uid element_abc123 --filePath element.png
|
||||
|
||||
# Compressed JPEG
|
||||
node scripts/take_screenshot.js --format jpeg --quality 80 --filePath page.jpg
|
||||
```
|
||||
|
||||
**Related Tools:** take_snapshot
|
||||
|
||||
---
|
||||
|
||||
## take_snapshot
|
||||
|
||||
Captures text-based page structure with element UIDs.
|
||||
|
||||
**Group:** Inspection & Debugging
|
||||
|
||||
**Optional Parameters:**
|
||||
- `--verbose BOOLEAN` - Include more details (default: false)
|
||||
- `--filePath STRING` - Path to save snapshot file
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Console output
|
||||
node scripts/take_snapshot.js
|
||||
|
||||
# Verbose mode
|
||||
node scripts/take_snapshot.js --verbose true
|
||||
|
||||
# Save to file
|
||||
node scripts/take_snapshot.js --filePath snapshot.txt
|
||||
|
||||
# Both
|
||||
node scripts/take_snapshot.js --verbose true --filePath detailed_snapshot.txt
|
||||
```
|
||||
|
||||
**Output Format:**
|
||||
```
|
||||
Page: https://example.com
|
||||
Title: Example Domain
|
||||
|
||||
button "Submit" [uid: button_submit_abc123]
|
||||
input "Email" [uid: input_email_def456]
|
||||
link "About" [uid: link_about_ghi789]
|
||||
```
|
||||
|
||||
**Important:** Always use UIDs from the most recent snapshot. UIDs regenerate on each snapshot.
|
||||
|
||||
**Related Tools:** click, fill, hover, drag, take_screenshot
|
||||
|
||||
---
|
||||
|
||||
## upload_file
|
||||
|
||||
Uploads a file through a file input element.
|
||||
|
||||
**Group:** Element Interaction
|
||||
|
||||
**Required Parameters:**
|
||||
- `--uid UID` - File input element UID
|
||||
- `--filePath STRING` - Absolute path to file to upload
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Upload document
|
||||
node scripts/upload_file.js --uid input_file_abc --filePath /Users/username/documents/resume.pdf
|
||||
|
||||
# Upload image
|
||||
node scripts/upload_file.js --uid input_avatar_xyz --filePath /Users/username/pictures/profile.jpg
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
- Use absolute paths (not relative)
|
||||
- Use forward slashes in paths
|
||||
- Verify file exists before upload
|
||||
|
||||
**Related Tools:** click, fill, wait_for
|
||||
|
||||
---
|
||||
|
||||
## wait_for
|
||||
|
||||
Waits for specific text to appear on the page.
|
||||
|
||||
**Group:** Performance Analysis
|
||||
|
||||
**Required Parameters:**
|
||||
- `--text STRING` - Text to wait for (exact match)
|
||||
|
||||
**Optional Parameters:**
|
||||
- `--timeout NUMBER` - Maximum wait time in milliseconds (default: 30000)
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Wait up to 30 seconds (default)
|
||||
node scripts/wait_for.js --text "Loading complete"
|
||||
|
||||
# Wait up to 10 seconds
|
||||
node scripts/wait_for.js --text "Welcome" --timeout 10000
|
||||
|
||||
# Wait for error message
|
||||
node scripts/wait_for.js --text "Error occurred" --timeout 5000
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
- Text match is exact (case-sensitive)
|
||||
- Times out if text doesn't appear within timeout period
|
||||
- Use after navigation, clicks, or any action that triggers loading
|
||||
|
||||
**Related Tools:** click, navigate_page, take_snapshot
|
||||
743
skills/mcp-chrome-devtools/reference/troubleshooting.md
Normal file
743
skills/mcp-chrome-devtools/reference/troubleshooting.md
Normal file
@@ -0,0 +1,743 @@
|
||||
# Troubleshooting Guide
|
||||
|
||||
Common issues and solutions for chrome-devtools skill.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Connection Issues](#connection-issues)
|
||||
- [Page Management Problems](#page-management-problems)
|
||||
- [Element Interaction Issues](#element-interaction-issues)
|
||||
- [Snapshot and Screenshot Problems](#snapshot-and-screenshot-problems)
|
||||
- [Console and Network Debugging](#console-and-network-debugging)
|
||||
- [Performance Analysis Issues](#performance-analysis-issues)
|
||||
- [General Best Practices](#general-best-practices)
|
||||
|
||||
---
|
||||
|
||||
## Connection Issues
|
||||
|
||||
### Problem: "Cannot connect to mcp2rest"
|
||||
|
||||
**Symptoms:**
|
||||
- Scripts fail with connection error
|
||||
- "ECONNREFUSED" error on port 28888
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Check if mcp2rest is running:**
|
||||
```bash
|
||||
curl http://localhost:28888/health
|
||||
```
|
||||
|
||||
Expected: `{"status": "healthy"}`
|
||||
|
||||
2. **Start mcp2rest if not running:**
|
||||
```bash
|
||||
mcp2rest start
|
||||
```
|
||||
|
||||
3. **Verify chrome-devtools server is loaded:**
|
||||
```bash
|
||||
curl http://localhost:28888/servers
|
||||
```
|
||||
|
||||
Should list chrome-devtools with "connected" status.
|
||||
|
||||
4. **Reload server if disconnected:**
|
||||
```bash
|
||||
mcp2rest reload chrome-devtools
|
||||
```
|
||||
|
||||
### Problem: "Server not found"
|
||||
|
||||
**Symptoms:**
|
||||
- Server not listed in mcp2rest
|
||||
- Tools return "server not configured" error
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Check installed servers:**
|
||||
```bash
|
||||
mcp2rest list
|
||||
```
|
||||
|
||||
2. **Add chrome-devtools server:**
|
||||
```bash
|
||||
mcp2rest add chrome-devtools
|
||||
```
|
||||
|
||||
3. **Restart mcp2rest:**
|
||||
```bash
|
||||
mcp2rest restart
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Page Management Problems
|
||||
|
||||
### Problem: "Cannot close last page"
|
||||
|
||||
**Symptoms:**
|
||||
- close_page fails with error about last page
|
||||
|
||||
**Solution:**
|
||||
|
||||
Always keep at least one page open. Open a new page before closing the last one:
|
||||
|
||||
```bash
|
||||
# Check current pages
|
||||
node scripts/list_pages.js
|
||||
|
||||
# Open new page first
|
||||
node scripts/new_page.js --url https://example.com
|
||||
|
||||
# Now close the old page
|
||||
node scripts/close_page.js --pageIdx 1
|
||||
```
|
||||
|
||||
### Problem: "Page index out of range"
|
||||
|
||||
**Symptoms:**
|
||||
- select_page or close_page fails
|
||||
- "Invalid page index" error
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Always list pages first:**
|
||||
```bash
|
||||
node scripts/list_pages.js
|
||||
```
|
||||
|
||||
2. **Use indices from the current list:**
|
||||
Page indices shift when pages are closed. Always get fresh indices.
|
||||
|
||||
3. **Close pages in reverse order:**
|
||||
```bash
|
||||
# If closing multiple pages, start from highest index
|
||||
node scripts/close_page.js --pageIdx 3
|
||||
node scripts/close_page.js --pageIdx 2
|
||||
node scripts/close_page.js --pageIdx 1
|
||||
```
|
||||
|
||||
### Problem: "Navigation timeout"
|
||||
|
||||
**Symptoms:**
|
||||
- new_page or navigate_page times out
|
||||
- Page doesn't load within timeout period
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Increase timeout:**
|
||||
```bash
|
||||
node scripts/new_page.js --url https://slow-site.com --timeout 60000
|
||||
```
|
||||
|
||||
2. **Check network connectivity:**
|
||||
Verify the URL loads in a regular browser.
|
||||
|
||||
3. **Use emulation to debug slow loading:**
|
||||
```bash
|
||||
# Test without throttling first
|
||||
node scripts/emulate.js --cpuThrottlingRate 1
|
||||
node scripts/new_page.js --url https://example.com
|
||||
```
|
||||
|
||||
### Problem: "Wrong page context"
|
||||
|
||||
**Symptoms:**
|
||||
- Commands execute on wrong page
|
||||
- Unexpected elements in snapshot
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Check selected page:**
|
||||
```bash
|
||||
node scripts/list_pages.js
|
||||
# Look for "(selected)" indicator
|
||||
```
|
||||
|
||||
2. **Explicitly select target page:**
|
||||
```bash
|
||||
node scripts/select_page.js --pageIdx 0
|
||||
```
|
||||
|
||||
3. **Pattern: Always select before interaction:**
|
||||
```bash
|
||||
node scripts/list_pages.js
|
||||
node scripts/select_page.js --pageIdx 1
|
||||
node scripts/take_snapshot.js
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Element Interaction Issues
|
||||
|
||||
### Problem: "Element UID not found"
|
||||
|
||||
**Symptoms:**
|
||||
- click, fill, or hover fails
|
||||
- "UID does not exist" error
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Take fresh snapshot:**
|
||||
UIDs regenerate on each snapshot. Never reuse old UIDs.
|
||||
|
||||
```bash
|
||||
# Always take new snapshot before interaction
|
||||
node scripts/take_snapshot.js
|
||||
# Use UIDs from this output
|
||||
node scripts/click.js --uid <fresh-uid>
|
||||
```
|
||||
|
||||
2. **Verify element exists:**
|
||||
Check the snapshot output to confirm the element is present.
|
||||
|
||||
3. **Wait for page to load:**
|
||||
```bash
|
||||
node scripts/wait_for.js --text "Page loaded" --timeout 10000
|
||||
node scripts/take_snapshot.js
|
||||
```
|
||||
|
||||
### Problem: "Click doesn't trigger action"
|
||||
|
||||
**Symptoms:**
|
||||
- Element is clicked but nothing happens
|
||||
- No error, but expected behavior doesn't occur
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Wait for page to fully load:**
|
||||
```bash
|
||||
node scripts/wait_for.js --text "Ready" --timeout 5000
|
||||
node scripts/click.js --uid button_abc
|
||||
```
|
||||
|
||||
2. **Try hover first:**
|
||||
Some elements require hover to become clickable.
|
||||
|
||||
```bash
|
||||
node scripts/hover.js --uid element_abc
|
||||
node scripts/click.js --uid element_abc
|
||||
```
|
||||
|
||||
3. **Check if element is visible:**
|
||||
Hidden or off-screen elements may not be clickable. Use take_snapshot with verbose to check visibility.
|
||||
|
||||
4. **Use double-click if needed:**
|
||||
```bash
|
||||
node scripts/click.js --uid element_abc --dblClick true
|
||||
```
|
||||
|
||||
### Problem: "Fill doesn't work on input"
|
||||
|
||||
**Symptoms:**
|
||||
- Text not entered into field
|
||||
- Select dropdown not changing
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Verify element type:**
|
||||
Use take_snapshot to confirm it's an input/textarea/select.
|
||||
|
||||
2. **Click to focus first:**
|
||||
```bash
|
||||
node scripts/click.js --uid input_abc
|
||||
node scripts/fill.js --uid input_abc --value "text"
|
||||
```
|
||||
|
||||
3. **For custom components, use press_key:**
|
||||
```bash
|
||||
node scripts/click.js --uid custom_input
|
||||
node scripts/press_key.js --key "H"
|
||||
node scripts/press_key.js --key "i"
|
||||
```
|
||||
|
||||
4. **For dropdowns, use exact option value:**
|
||||
Check the HTML to find the correct option value.
|
||||
|
||||
### Problem: "Drag and drop doesn't work"
|
||||
|
||||
**Symptoms:**
|
||||
- Drag operation completes but element doesn't move
|
||||
- "Invalid UID" error
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Verify both UIDs are current:**
|
||||
```bash
|
||||
node scripts/take_snapshot.js
|
||||
# Use UIDs from this output
|
||||
node scripts/drag.js --from-uid <fresh-from> --to-uid <fresh-to>
|
||||
```
|
||||
|
||||
2. **Add wait between operations:**
|
||||
```bash
|
||||
node scripts/drag.js --from-uid item1 --to-uid zone1
|
||||
node scripts/wait_for.js --text "Moved" --timeout 3000
|
||||
```
|
||||
|
||||
3. **Check if dropzone accepts the element:**
|
||||
Some drag-and-drop UIs have restrictions on what can be dropped where.
|
||||
|
||||
### Problem: "File upload fails"
|
||||
|
||||
**Symptoms:**
|
||||
- upload_file fails
|
||||
- File path error
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Use absolute paths:**
|
||||
```bash
|
||||
# Good
|
||||
node scripts/upload_file.js --uid input_file --filePath /Users/username/file.pdf
|
||||
|
||||
# Bad
|
||||
# node scripts/upload_file.js --uid input_file --filePath ./file.pdf
|
||||
```
|
||||
|
||||
2. **Use forward slashes:**
|
||||
```bash
|
||||
# Good
|
||||
/Users/username/documents/file.pdf
|
||||
|
||||
# Bad (Windows-style)
|
||||
# C:\Users\username\documents\file.pdf
|
||||
```
|
||||
|
||||
3. **Verify file exists:**
|
||||
```bash
|
||||
ls -la /Users/username/documents/file.pdf
|
||||
```
|
||||
|
||||
4. **Check file input UID:**
|
||||
Take fresh snapshot and verify the element is a file input.
|
||||
|
||||
---
|
||||
|
||||
## Snapshot and Screenshot Problems
|
||||
|
||||
### Problem: "Snapshot shows different UIDs each time"
|
||||
|
||||
**Symptoms:**
|
||||
- UIDs change on each snapshot
|
||||
- Previously working UIDs stop working
|
||||
|
||||
**Solution:**
|
||||
|
||||
**This is expected behavior.** UIDs are dynamically generated on each snapshot. Always use the most recent snapshot:
|
||||
|
||||
```bash
|
||||
# Pattern: Always snapshot before interaction
|
||||
node scripts/take_snapshot.js
|
||||
# Immediately use UIDs from output
|
||||
node scripts/click.js --uid <current-uid>
|
||||
```
|
||||
|
||||
### Problem: "Screenshot is blank or black"
|
||||
|
||||
**Symptoms:**
|
||||
- Screenshot file is created but shows blank/black image
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Wait for page to render:**
|
||||
```bash
|
||||
node scripts/wait_for.js --text "Content" --timeout 10000
|
||||
node scripts/take_screenshot.js --filePath page.png
|
||||
```
|
||||
|
||||
2. **Try full page screenshot:**
|
||||
```bash
|
||||
node scripts/take_screenshot.js --fullPage true --filePath page.png
|
||||
```
|
||||
|
||||
3. **Verify element is visible:**
|
||||
For element screenshots, ensure the element isn't hidden or off-screen.
|
||||
|
||||
4. **Check page actually loaded:**
|
||||
```bash
|
||||
node scripts/take_snapshot.js
|
||||
# Verify page content appears in snapshot
|
||||
```
|
||||
|
||||
### Problem: "Screenshot file not saving"
|
||||
|
||||
**Symptoms:**
|
||||
- No error but file not created
|
||||
- "File not found" when opening
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Use absolute path:**
|
||||
```bash
|
||||
node scripts/take_screenshot.js --filePath /Users/username/screenshots/page.png
|
||||
```
|
||||
|
||||
2. **Ensure directory exists:**
|
||||
```bash
|
||||
mkdir -p /Users/username/screenshots
|
||||
node scripts/take_screenshot.js --filePath /Users/username/screenshots/page.png
|
||||
```
|
||||
|
||||
3. **Check file permissions:**
|
||||
Ensure you have write access to the target directory.
|
||||
|
||||
---
|
||||
|
||||
## Console and Network Debugging
|
||||
|
||||
### Problem: "Console messages not showing up"
|
||||
|
||||
**Symptoms:**
|
||||
- list_console_messages returns empty or incomplete results
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Messages accumulate since navigation:**
|
||||
Console messages are captured from the current page navigation onwards.
|
||||
|
||||
2. **Reload if needed:**
|
||||
```bash
|
||||
node scripts/navigate_page.js --type reload
|
||||
# Wait for page load
|
||||
node scripts/wait_for.js --text "Ready" --timeout 10000
|
||||
# Now check console
|
||||
node scripts/list_console_messages.js
|
||||
```
|
||||
|
||||
3. **Include preserved messages:**
|
||||
```bash
|
||||
node scripts/list_console_messages.js --includePreservedMessages true
|
||||
```
|
||||
|
||||
4. **Ensure page has errors to show:**
|
||||
Use take_snapshot or evaluate_script to verify page loaded correctly.
|
||||
|
||||
### Problem: "Network requests list is empty"
|
||||
|
||||
**Symptoms:**
|
||||
- list_network_requests returns no results
|
||||
- Expected API calls not showing
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Requests are captured from navigation onwards:**
|
||||
```bash
|
||||
# Navigate first to capture requests
|
||||
node scripts/navigate_page.js --url https://example.com
|
||||
# Wait for page to load
|
||||
node scripts/wait_for.js --text "Loaded" --timeout 10000
|
||||
# Now check requests
|
||||
node scripts/list_network_requests.js
|
||||
```
|
||||
|
||||
2. **Filter by resource type:**
|
||||
```bash
|
||||
# Maybe filtering too strictly
|
||||
node scripts/list_network_requests.js --resourceTypes fetch,xhr,document
|
||||
```
|
||||
|
||||
3. **Include preserved requests:**
|
||||
```bash
|
||||
node scripts/list_network_requests.js --includePreservedRequests true
|
||||
```
|
||||
|
||||
### Problem: "Cannot find console message or network request ID"
|
||||
|
||||
**Symptoms:**
|
||||
- get_console_message or get_network_request fails
|
||||
- "Invalid ID" error
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **List first to get IDs:**
|
||||
```bash
|
||||
# For console
|
||||
node scripts/list_console_messages.js
|
||||
# Copy message ID from output
|
||||
node scripts/get_console_message.js --msgid <id-from-list>
|
||||
|
||||
# For network
|
||||
node scripts/list_network_requests.js
|
||||
# Copy request ID from output
|
||||
node scripts/get_network_request.js --reqid <id-from-list>
|
||||
```
|
||||
|
||||
2. **IDs are session-specific:**
|
||||
IDs don't persist across page navigations. Get fresh IDs after navigation.
|
||||
|
||||
---
|
||||
|
||||
## Performance Analysis Issues
|
||||
|
||||
### Problem: "evaluate_script returns null or error"
|
||||
|
||||
**Symptoms:**
|
||||
- Script execution fails
|
||||
- Returns null unexpectedly
|
||||
- "Evaluation failed" error
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Return JSON-serializable values only:**
|
||||
```bash
|
||||
# Good: primitives, arrays, plain objects
|
||||
node scripts/evaluate_script.js --function "() => document.title"
|
||||
node scripts/evaluate_script.js --function "() => [1, 2, 3]"
|
||||
node scripts/evaluate_script.js --function "() => ({key: 'value'})"
|
||||
|
||||
# Bad: DOM nodes, functions, circular references
|
||||
# node scripts/evaluate_script.js --function "() => document.querySelector('div')"
|
||||
```
|
||||
|
||||
2. **Extract values from DOM elements:**
|
||||
```bash
|
||||
# Instead of returning DOM nodes, extract their properties
|
||||
node scripts/evaluate_script.js --function "() => Array.from(document.querySelectorAll('a')).map(a => a.href)"
|
||||
```
|
||||
|
||||
3. **Check for JavaScript errors:**
|
||||
```bash
|
||||
node scripts/list_console_messages.js --types error
|
||||
```
|
||||
|
||||
4. **Verify function syntax:**
|
||||
```bash
|
||||
# Arrow function
|
||||
node scripts/evaluate_script.js --function "() => document.title"
|
||||
|
||||
# Function with parameters
|
||||
node scripts/evaluate_script.js --function "(x, y) => x + y" --args '[5, 3]'
|
||||
```
|
||||
|
||||
### Problem: "wait_for times out"
|
||||
|
||||
**Symptoms:**
|
||||
- wait_for exceeds timeout
|
||||
- Text never appears
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Increase timeout:**
|
||||
```bash
|
||||
node scripts/wait_for.js --text "Loaded" --timeout 30000
|
||||
```
|
||||
|
||||
2. **Verify text actually appears:**
|
||||
```bash
|
||||
# Check with snapshot
|
||||
node scripts/take_snapshot.js
|
||||
# Look for the expected text
|
||||
```
|
||||
|
||||
3. **Text match is exact:**
|
||||
Check spelling, capitalization, and spacing.
|
||||
|
||||
```bash
|
||||
# Case-sensitive match
|
||||
# "Welcome" ≠ "welcome" ≠ "Welcome!"
|
||||
```
|
||||
|
||||
4. **Wait for network first:**
|
||||
```bash
|
||||
# If text appears after API call, wait longer
|
||||
node scripts/wait_for.js --text "Data loaded" --timeout 20000
|
||||
```
|
||||
|
||||
### Problem: "Dialog not handled"
|
||||
|
||||
**Symptoms:**
|
||||
- handle_dialog fails
|
||||
- "No dialog present" error
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Dialog must be open first:**
|
||||
```bash
|
||||
# Trigger dialog
|
||||
node scripts/click.js --uid button_delete
|
||||
|
||||
# Immediately handle it
|
||||
node scripts/handle_dialog.js --action accept
|
||||
```
|
||||
|
||||
2. **Some "dialogs" are custom HTML:**
|
||||
If it's not a real browser dialog (alert/confirm/prompt), use click instead:
|
||||
|
||||
```bash
|
||||
# For custom modal dialogs
|
||||
node scripts/take_snapshot.js
|
||||
node scripts/click.js --uid button_modal_ok
|
||||
```
|
||||
|
||||
3. **Timing matters:**
|
||||
Handle dialog immediately after triggering action.
|
||||
|
||||
### Problem: "Performance trace shows unexpected results"
|
||||
|
||||
**Symptoms:**
|
||||
- CWV scores don't match expectations
|
||||
- Missing performance data
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Ensure page fully loads:**
|
||||
```bash
|
||||
node scripts/performance_start_trace.js --reload true --autoStop false
|
||||
node scripts/wait_for.js --text "Loaded" --timeout 20000
|
||||
node scripts/performance_stop_trace.js
|
||||
```
|
||||
|
||||
2. **Use reload for consistent measurement:**
|
||||
```bash
|
||||
# For initial page load measurement
|
||||
node scripts/performance_start_trace.js --reload true --autoStop false
|
||||
```
|
||||
|
||||
3. **Clear browser state:**
|
||||
Navigation with cache clear:
|
||||
```bash
|
||||
node scripts/navigate_page.js --url https://example.com --ignoreCache true
|
||||
```
|
||||
|
||||
4. **Disable emulation if active:**
|
||||
```bash
|
||||
node scripts/emulate.js --cpuThrottlingRate 1
|
||||
```
|
||||
|
||||
### Problem: "Emulation not working"
|
||||
|
||||
**Symptoms:**
|
||||
- Page loads at normal speed despite emulation
|
||||
- No visible effect from throttling
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Emulation persists for session:**
|
||||
Reset to normal first, then apply:
|
||||
|
||||
```bash
|
||||
# Reset
|
||||
node scripts/emulate.js --cpuThrottlingRate 1
|
||||
|
||||
# Then apply desired emulation
|
||||
node scripts/emulate.js --cpuThrottlingRate 4
|
||||
```
|
||||
|
||||
2. **Network conditions must be valid JSON:**
|
||||
```bash
|
||||
# All three properties required
|
||||
node scripts/emulate.js --networkConditions '{"downloadThroughput":50000,"uploadThroughput":50000,"latency":2000}'
|
||||
```
|
||||
|
||||
3. **Verify effect with performance trace:**
|
||||
```bash
|
||||
node scripts/emulate.js --cpuThrottlingRate 4
|
||||
node scripts/performance_start_trace.js --reload true --autoStop false
|
||||
node scripts/wait_for.js --text "Loaded" --timeout 60000
|
||||
node scripts/performance_stop_trace.js
|
||||
# Check timing metrics in output
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## General Best Practices
|
||||
|
||||
### Always Snapshot Before Interaction
|
||||
|
||||
UIDs are dynamic. Take a fresh snapshot before every interaction:
|
||||
|
||||
```bash
|
||||
# Good pattern
|
||||
node scripts/take_snapshot.js
|
||||
node scripts/click.js --uid <current-uid>
|
||||
|
||||
# Bad pattern (will fail)
|
||||
# node scripts/take_snapshot.js
|
||||
# ... do other things ...
|
||||
# node scripts/click.js --uid <old-uid> # UID expired!
|
||||
```
|
||||
|
||||
### Wait After Actions
|
||||
|
||||
Allow time for UI updates:
|
||||
|
||||
```bash
|
||||
node scripts/click.js --uid button_submit
|
||||
node scripts/wait_for.js --text "Success" --timeout 5000
|
||||
node scripts/take_snapshot.js
|
||||
```
|
||||
|
||||
### Use Absolute Paths
|
||||
|
||||
Always use absolute paths for files:
|
||||
|
||||
```bash
|
||||
# Good
|
||||
/Users/username/documents/file.pdf
|
||||
/home/user/screenshots/page.png
|
||||
|
||||
# Bad
|
||||
./file.pdf
|
||||
../screenshots/page.png
|
||||
```
|
||||
|
||||
### Check Connection First
|
||||
|
||||
Before running workflows, verify mcp2rest is healthy:
|
||||
|
||||
```bash
|
||||
curl http://localhost:28888/health
|
||||
```
|
||||
|
||||
### List Before Selecting
|
||||
|
||||
Always list pages before selecting or closing:
|
||||
|
||||
```bash
|
||||
node scripts/list_pages.js
|
||||
node scripts/select_page.js --pageIdx 1
|
||||
```
|
||||
|
||||
### Handle Errors Gracefully
|
||||
|
||||
Check console and network for debugging:
|
||||
|
||||
```bash
|
||||
# After error occurs
|
||||
node scripts/list_console_messages.js --types error
|
||||
node scripts/list_network_requests.js
|
||||
node scripts/take_screenshot.js --filePath error_state.png
|
||||
```
|
||||
|
||||
### Use Verbose for Debugging
|
||||
|
||||
Get more details when troubleshooting:
|
||||
|
||||
```bash
|
||||
node scripts/take_snapshot.js --verbose true
|
||||
```
|
||||
|
||||
### Save Outputs for Analysis
|
||||
|
||||
Redirect output to files for later review:
|
||||
|
||||
```bash
|
||||
node scripts/list_console_messages.js > console_log.txt
|
||||
node scripts/list_network_requests.js > network_log.txt
|
||||
node scripts/take_snapshot.js --filePath snapshot.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
If you encounter issues not covered here:
|
||||
|
||||
1. **Check tool documentation:** @reference/all-tools.md
|
||||
2. **Review workflows:** @workflows/[tool-group].md
|
||||
3. **Test with minimal example:** Isolate the problem with simplest reproduction
|
||||
4. **Check mcp2rest status:** Ensure server is connected and healthy
|
||||
5. **Restart mcp2rest:** Sometimes a fresh start helps: `mcp2rest restart`
|
||||
Reference in New Issue
Block a user