本文へ移動
cccskills
無料GitHub で公開

playwright

Browser automation, web scraping, E2E testing, and visual regression with Playwright. Covers 30+ patterns: login flows, form testing, responsive design checks, broken link validation, API mocking, data extraction, PDF generation, accessibility audits (axe-core), performance budgets (Lighthouse), visual diffing, multi-browser testing (Chromium/Firefox/WebKit), mobile emulation, infinite scroll, shadow DOM, iframes, file downloads, auth state reuse, cookie consent handling, WebSocket monitoring, console error detection, HAR export, trace viewer, Docker CI, GitHub Actions, and parallel sharding. Use when user asks to test a website, take screenshots, check responsive design, automate a browser task, scrape data, validate forms, check broken links, test login, audit accessibility, or measure page performance. Do NOT use for unit testing, API-only testing, or static analysis. Requires Node.js 18+.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md14.1 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Playwright — Browser Automation Skill

Intelligent browser automation executor. Analyzes the user's request, selects the optimal pattern from 30+ built-in templates, generates production-grade Playwright code, and executes it with real-time reporting.

Setup

Playwright must be available in the environment. If not installed:

npm init -y
npm install playwright @playwright/test
npx playwright install chromium

For all 3 browsers:

npx playwright install

Check what's installed:

npx playwright install --dry-run

Trigger Decision Tree

When user asks for browser automation, classify the task:

User request
├── "screenshot" / "capture" / "take a picture"
│   → screenshot template
├── "responsive" / "mobile" / "different sizes"
│   → responsive check + per-viewport screenshots
├── "login" / "sign in" / "authenticate"
│   → login flow with error detection
├── "form" / "fill" / "submit" / "input"
│   → form testing with validation check
├── "broken links" / "check links" / "link validation"
│   → broken link scanner
├── "scrape" / "extract" / "get data" / "crawl"
│   → data extraction (single page or crawl)
├── "mock" / "intercept" / "stub" / "fake api"
│   → API mocking with route interception
├── "accessibility" / "a11y" / "axe" / "wcag"
│   → accessibility audit (requires axe-core)
├── "performance" / "lighthouse" / "speed" / "load time"
│   → performance audit with budgets
├── "visual" / "visual regression" / "diff"
│   → visual comparison screenshots
├── "download" / "file download"
│   → file download handler
├── "console" / "errors" / "logs"
│   → console error detector
├── "pdf" / "generate pdf"
│   → page-to-PDF converter
└── else → generic browse + report

Workflow

Step 1: Detect the environment

Before writing any code, determine what's available:

  • Dev servers: Check common ports (3000, 3001, 5173, 8080, 8000, 4200, 5000, 9000) for running processes
  • Installed browsers: Run npx playwright install --dry-run to see which browsers are available
  • Framework indicators: Look for package.json dependencies (react, vue, svelte, next, nuxt) to understand the app under test
  • Available credentials: Check if the user mentioned login credentials or has .env files

Step 2: Select template + generate code

Based on task classification and environment info, select the appropriate template and customize it with:

  • Detected URL (dev server or user-supplied)
  • Any user-specific parameters (credentials, selectors, viewports)
  • Best-practice patterns auto-inserted (waitForSelector instead of fixed waits, graceful error handling, cleanup in finally)

Rules for code generation:

  • Use getByRole / getByText / getByLabel over CSS selectors (stable, accessible)
  • Parameterize URL in TARGET_URL constant at top
  • Never use waitForTimeout for conditions — use waitForSelector, waitForURL, waitForResponse
  • Always wrap in try/catch/finally with browser.close() in finally
  • Include console.error logging at each step
  • Comment each logical block
  • Write generated file to OS temp dir as playwright-task-{timestamp}.js

Step 3: Execute

Run the generated script directly with Node:

node <path-to-generated-file>

For inline one-off tasks (quick screenshot, check title):

node -e "
const { chromium } = require('playwright');
(async () => {
  const browser = await chromium.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto('$URL');
  console.log('Title:', await page.title());
  await browser.close();
})();
"

Step 4: Report results

Present results based on task type:

TaskOutput format
ScreenshotDisplay path + preview description
ResponsiveTable: viewport × status × screenshot path
LoginPass/fail + redirect URL + session file
Broken linksSummary: working/broken + detailed table
ScrapeNumber of records + sample rows
A11yViolation count + top 3 issues
PerformanceScore table + largest offenders
Visual diffPass/fail + mismatch pixels

Smart Defaults

These are applied automatically to every generated script:

SettingDefaultWhy
headlessfalseUser sees what's happening
slowMo100Visible transitions for debugging
viewport1280x720Standard desktop
Timeout15000 (15s)Balance patience vs feedback
args--no-sandboxLinux/WSL compatibility
TraceOn first failureDiagnostic data
VideoOn failureVisual debug
ScreenshotOn failureVisual assert
Console listenerActiveCapture browser errors
Page error listenerActiveCatch JS exceptions

Important Rules

  • No hardcoded URLs: Always parameterize as TARGET_URL
  • No fixed waits: Use waitForSelector, waitForURL, waitForResponse, waitForLoadState
  • Auth state reuse: Save to .auth/ directory for multi-step flows
  • Temp files only: Write scripts to OS temp dir, never to project or skill dir
  • Failure screenshots: Always capture on error for debugging
  • Close browser: Always browser.close() in finally block

Error Recovery

ErrorDiagnosisResponse
ECONNREFUSEDServer not runningSuggest dev server or check URL
Timeout 30sElement/page not loadingRetry with waitForSelector, suggest specific selector
NoSuchElementWrong selectorAuto-capture page HTML snippet, suggest better selector
Auth failureLogin credentials wrongCapture error message, suggest alternative flow
404/500Bad URL or server errorLog status + body, offer to check URL

Common Fast Patterns

Quick screenshot

const { chromium } = require('playwright');
(async () => {
  const browser = await chromium.launch({ headless: false });
  const page = await browser.newPage();
  await page.setViewportSize({ width: 1920, height: 1080 });
  await page.goto(TARGET_URL, { waitUntil: 'networkidle' });
  await page.screenshot({ path: `${require('os').tmpdir()}/screenshot.png`, fullPage: true });
  console.log('Screenshot saved to temp/screenshot.png');
  await browser.close();
})();

Quick page info

const { chromium } = require('playwright');
(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto(TARGET_URL);
  console.log('Title:', await page.title());
  console.log('URL:', page.url());
  const meta = await page.$('meta[name="description"]');
  console.log('Meta description:', meta ? await meta.getAttribute('content') : 'N/A');
  await browser.close();
})();

Quick form test

const { chromium } = require('playwright');
(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto(TARGET_URL);
  const inputs = await page.locator('input, textarea, select').count();
  const buttons = await page.locator('button, input[type="submit"]').count();
  console.log(`Form has ${inputs} inputs and ${buttons} buttons`);
  await browser.close();
})();

Advanced Patterns

Login flow with auth state reuse

const { chromium } = require('playwright');
const path = require('path');
const AUTH_FILE = path.join(__dirname, '.auth', 'state.json');

(async () => {
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext();

  // Try to reuse saved auth state
  try {
    const state = require(AUTH_FILE);
    await context.addCookies(state.cookies);
  } catch {}

  const page = await context.newPage();
  await page.goto(TARGET_URL);

  // Check if logged in
  const isLoggedIn = await page.$('[data-logged-in]');
  if (!isLoggedIn) {
    await page.fill('[name="username"]', USERNAME);
    await page.fill('[name="password"]', PASSWORD);
    await page.click('button[type="submit"]');
    await page.waitForURL('**/dashboard');
    // Save auth state
    const cookies = await context.cookies();
    require('fs').writeFileSync(AUTH_FILE, JSON.stringify({ cookies }, null, 2));
  }

  // Continue with authenticated actions...
  await browser.close();
})();

API mocking with route interception

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext();
  const page = await context.newPage();

  // Mock API responses
  await page.route('**/api/users', route => {
    route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify([{ id: 1, name: 'Test User' }])
    });
  });

  // Block analytics/tracking requests
  await page.route(/google-analytics|facebook|gtag/, route => route.abort());

  await page.goto(TARGET_URL);
  // Test with mocked data...
  await browser.close();
})();

Accessibility audit (requires axe-core)

npm install @axe-core/playwright
const { chromium } = require('playwright');
const { injectAxe, checkA11y } = require('@axe-core/playwright');

(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto(TARGET_URL);
  await injectAxe(page);
  const results = await checkA11y(page, null, {
    detailedReport: true,
    detailedReportOptions: { html: true }
  });
  console.log(`Violations: ${results.violations.length}`);
  results.violations.forEach(v => console.log(`- ${v.help}: ${v.nodes.length} instances`));
  await browser.close();
})();

Anti-Patterns

Anti-PatternWhy It's BadDo This Instead
page.waitForTimeout(5000)Flaky, slows tests, false passespage.waitForSelector('.loaded')
page.$eval('.css-selector', ...)Brittle, breaks on DOM changespage.getByRole('button', { name: 'Submit' })
Hardcoded localhost:3000Fails when port changesParameterize as TARGET_URL env var
No browser.close()Hangs, leaks resourcesAlways in finally block
page.click() without waitRace condition, element not readypage.click() already waits for actionability
Sequential tests in one scriptOne failure kills everythingSeparate scripts or use test runner
networkidle on SPAsNever resolves on polling appsUse load + explicit element wait
Capturing fullPage on infinite scrollHuge images, timeoutsClip viewport only
Reusing selectors between environmentsDev vs prod DOM differsUse data-testid or role-based locators

Error Handling

Playwright-specific errors and remedies

ErrorLikely CauseResolution
browserType.launch: Executable doesn't existChromium not installedRun npx playwright install chromium
page.goto: net::ERR_CONNECTION_REFUSEDDev server not runningStart dev server or verify URL
page.click: Target closedNavigation happened during clickUse page.waitForNavigation() before click or Promise.all([page.waitForNavigation(), page.click()])
locator.click: Timeout 30000ms exceededElement never becomes actionableCheck selector; maybe element is hidden/disabled/covered
page.fill: Element is not an <input>Wrong element type targetedUse getByRole('textbox') for proper targeting
route.fulfill: Request already servedMultiple routes matched same requestOrder routes most-specific first; use route.fallback() for pass-through
browser.newContext: Cookie domain mismatchAuth state reuse on wrong domainEnsure cookies match the target URL's domain
page.pdf: Protocol errorHeadless mode disabledPDF generation requires headless: true
page.waitForSelector: Target closedNavigation destroyed the pageWrap navigation + post-navigation actions in a single await chain
require('playwright'): Cannot find moduleInstall incompletenpm install playwright then verify node_modules/playwright exists

Checklist

  • Locator uses getByRole, getByText, or getByTestId — never XPath or CSS selectors with fragile class names
  • Auto-waiting relied on (no manual waitForTimeout or sleep)
  • Test isolates state (clean DB or API mock per test)
  • Cross-browser tested (Chromium + Firefox + WebKit) for critical flows
  • Trace viewer enabled on failure for debugging CI flakes

Sources

  • Playwright official documentation (playwright.dev) — locator strategies, auto-waiting, fixtures
  • Testing Trophy methodology — 80% integration / 20% unit testing ratio
  • @axe-core/playwright for accessibility audits
  • Lighthouse CI for performance budgets
  • Production E2E patterns from 30+ project codebases

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Apply professional, premium UI/UX design standards when building or styling web interfaces. Use this skill when the user asks to create a website, landing page, web app, dashboard, UI component, or any visual interface — or when they ask to make something look better, more professional, or more beautiful. Covers visual hierarchy, typography, color systems, layout, spacing, motion, dark mode, responsive design, and conversion patterns. Activate even when the user doesn't say "design" — if they're building a web frontend, these standards apply.

日本語の概要は準備中です。原文の説明を表示しています。

EliasOulkadi/shokunin1142026年10月5日 更新

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.

日本語の概要は準備中です。原文の説明を表示しています。

EliasOulkadi/shokunin1142026年10月5日 更新

Run 150+ AI apps via inference.sh CLI - image generation, video creation, LLMs, search, 3D, Twitter automation. Models: FLUX, Veo, Gemini, Grok, Claude, Seedance, OmniHuman, Tavily, Exa, OpenRouter, and many more. Use when running AI apps, generating images/videos, calling LLMs, web search, or automating Twitter. Triggers: inference.sh, infsh, ai model, run ai, serverless ai, ai api, flux, veo, claude api, image generation, video generation, openrouter, tavily, exa search, twitter api, grok

日本語の概要は準備中です。原文の説明を表示しています。

EliasOulkadi/shokunin1142026年10月5日 更新

api-forge

無料

Design REST/GraphQL APIs with OpenAPI 3.1, error handling, pagination, rate limiting, webhooks, and idempotency. Use when user asks to design an API, create endpoints, define REST/GraphQL schema, or generate OpenAPI spec. Do NOT use for database schema design, frontend API integration, or non-HTTP protocols (gRPC, WebSocket, MQTT).

日本語の概要は準備中です。原文の説明を表示しています。

EliasOulkadi/shokunin1142026年10月5日 更新

Implement authentication and authorization with OWASP Top 10 standards, OAuth 2.0 + OIDC, WebAuthn/Passkeys, session management, and RBAC/ABAC. Use when user asks to implement login, signup, authentication, authorization, JWT, OAuth, SSO, passkeys, MFA, or role-based access. Do NOT use for API key management (use api-forge), encryption at rest, or network-level security (firewalls, WAF).

日本語の概要は準備中です。原文の説明を表示しています。

EliasOulkadi/shokunin1142026年10月5日 更新

Generate brand guidelines, design systems with design tokens (W3C format), creative direction (SCAMPER, Design Thinking, TRIZ), and design briefs with scope and success criteria.

日本語の概要は準備中です。原文の説明を表示しています。

EliasOulkadi/shokunin1142026年10月5日 更新

EliasOulkadi のスキルをすべて見る

このスキルの問題を報告する