0
0
# Install this skill:
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}`));
// 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:

  1. Navigate to the affected page
  2. Screenshot the initial state
  3. Check console for JavaScript errors
  4. Inspect network for failed API calls (4xx, 5xx)
  5. Interact to reproduce the issue
  6. Screenshot the broken state
  7. Read DOM state of the failing element
  8. 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
  • networkidle can time out on apps with polling β€” use domcontentloaded and 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.