Use when adding new error messages to React, or seeing "unknown error code" warnings.
npx skills add Anshin-Health-Solutions/superpai --skill "browser"
Install specific skill from multi-skill repository
# Description
Debug-first browser automation with Playwright. Screenshots, console logs, network requests captured by default.
# SKILL.md
name: browser
description: "Debug-first browser automation with Playwright. Screenshots, console logs, network requests captured by default."
triggers:
- browser
- screenshot
- debug web
- verify UI
- troubleshoot frontend
- Playwright
Browser Skill
Browser automation for verification, debugging, and testing.
Capabilities
- Screenshot β Capture page state for visual verification
- Console Logs β Capture browser console output
- Network β Monitor network requests and responses
- Interact β Click, type, navigate, scroll
- Assert β Verify page content, layout, behavior
Debug-First
Console logs, network requests, and errors are captured by default. You don't need to set them up.
Requirements
- Playwright installed (
npx playwright install) - Not available on Claude Desktop
Common Operations
// Screenshot
await page.screenshot({ path: 'screenshot.png', fullPage: true });
// Check element exists
await expect(page.locator('.header')).toBeVisible();
// Capture console
page.on('console', msg => console.log(msg.text()));
Full Playwright Patterns
Setup and Configuration
import { chromium, Browser, Page } from 'playwright';
// Standard debug-first setup
const browser = await chromium.launch({ headless: false, slowMo: 50 });
const context = await browser.newContext({
viewport: { width: 1280, height: 720 },
recordVideo: { dir: 'videos/' },
});
const page = await context.newPage();
// Capture all console output
page.on('console', msg => {
console.log(`[${msg.type().toUpperCase()}] ${msg.text()}`);
});
// Capture all network requests
page.on('request', req => {
if (req.resourceType() === 'fetch' || req.resourceType() === 'xhr') {
console.log(`>> ${req.method()} ${req.url()}`);
}
});
// Capture all network responses
page.on('response', res => {
if (res.url().includes('/api/')) {
console.log(`<< ${res.status()} ${res.url()}`);
}
});
// Capture page errors
page.on('pageerror', err => console.error(`PAGE ERROR: ${err.message}`));
Navigation and Wait Strategies
// Navigate and wait for network idle
await page.goto('https://app.example.com', { waitUntil: 'networkidle' });
// Wait for specific element
await page.waitForSelector('.dashboard-loaded', { timeout: 10000 });
// Wait for API response
const [response] = await Promise.all([
page.waitForResponse(resp => resp.url().includes('/api/data')),
page.click('#load-data-button'),
]);
const data = await response.json();
// Wait for navigation after action
await Promise.all([
page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
page.click('#submit-button'),
]);
// Wait for text to appear
await page.waitForFunction(
text => document.body.innerText.includes(text),
'Dashboard loaded'
);
Interaction Patterns
// Type into field with clear first
await page.fill('#username', '[email protected]');
await page.fill('#password', 'password123');
// Click with force if element is obscured
await page.click('#submit', { force: true });
// Select from dropdown
await page.selectOption('#country', 'US');
// Check a checkbox
await page.check('#terms-checkbox');
// Upload a file
await page.setInputFiles('#file-upload', '/path/to/file.pdf');
// Hover over element (triggers tooltips, menus)
await page.hover('.menu-item');
// Keyboard shortcuts
await page.keyboard.press('Control+A');
await page.keyboard.type('replacement text');
// Scroll to element
await page.locator('#footer').scrollIntoViewIfNeeded();
Screenshot Comparison Workflow
// Capture baseline
await page.screenshot({ path: 'baseline.png', fullPage: true });
// After changes, capture comparison
await page.screenshot({ path: 'after-change.png', fullPage: true });
// Element-specific screenshot (avoid noise from other parts)
await page.locator('.component-under-test').screenshot({ path: 'component.png' });
// Screenshot with clip region
await page.screenshot({
path: 'cropped.png',
clip: { x: 0, y: 0, width: 800, height: 400 }
});
Debug Workflow for Frontend Issues
When the user reports a UI problem, follow this sequence:
- Navigate to the affected page
- Screenshot the initial state
- Check console for JavaScript errors
- Inspect network for failed API calls (4xx, 5xx)
- Interact to reproduce the issue
- Screenshot the broken state
- Read DOM state of the failing element
- Report findings with screenshots and logs
// Full debug capture pattern
async function debugPage(url: string) {
const errors: string[] = [];
const failedRequests: string[] = [];
page.on('pageerror', err => errors.push(err.message));
page.on('response', res => {
if (res.status() >= 400) failedRequests.push(`${res.status()} ${res.url()}`);
});
await page.goto(url, { waitUntil: 'networkidle' });
await page.screenshot({ path: 'debug-state.png', fullPage: true });
return {
title: await page.title(),
url: page.url(),
errors,
failedRequests,
screenshot: 'debug-state.png',
};
}
Assertion Patterns
// Element visibility
await expect(page.locator('.success-message')).toBeVisible();
await expect(page.locator('.error-banner')).toBeHidden();
// Text content
await expect(page.locator('h1')).toHaveText('Welcome Back');
await expect(page.locator('.count')).toContainText('42');
// URL assertion
await expect(page).toHaveURL('/dashboard');
// Page title
await expect(page).toHaveTitle(/Dashboard/);
// Element count
await expect(page.locator('.list-item')).toHaveCount(10);
// Attribute check
await expect(page.locator('#submit')).toBeEnabled();
await expect(page.locator('#submit')).toHaveAttribute('type', 'submit');
Red Flags / Warnings
- Never use
page.waitForTimeout()for synchronization β it causes flaky tests; use event-based waits networkidlecan time out on apps with polling β usedomcontentloadedand add specific element waits- Headless mode renders differently from headed β always validate in headed mode when debugging visual issues
- Screenshots in CI may differ from local due to font rendering and OS differences
- Avoid hardcoded delays; if an element does not appear within 10 seconds, the bug is real
Output: Visual confirmation with screenshots, console logs, and network trace of the page state.
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.