Playwright Browser Automation
Microck/ordinary-claude-skills
Playwright によるブラウザ操作の完全自動化。 開発サーバーを自動検出し、/tmp に整理されたテストスクリプトを生成します。ページのテスト、フォームへの入力、スクリーンショットの取得、レスポンシブデザインの確認、UXの検証、ログインフローのテスト、リンクの確認など、あらゆるブラウザ操作を自動化できます。ウェブサイトのテスト、ブラウザ操作の自動化、Web機能の検証、またはブラウザベースのあらゆるテストを実行したい場合に利用してください。
...すべて拡張しますPlaywright Browser Automationについて
Playwright Browser Automation は、ブラウザベースのテストおよび自動化タスクを簡素化・効率化するために設計された汎用性の高いスキルです。Playwrightフレームワークを使用して、プログラム的にウェブサイトとやり取りするための包括的なソリューションを提供します。 ページ移動、フォーム入力、スクリーンショットの撮影、ユーザー体験の検証といったブラウザ操作を自動化することで、このスキルは、Webアプリケーションの機能性と信頼性を確保する際に開発者やテスターが直面する一般的な課題を解決します。効率的で再現性の高いテストプロセスを提供することで、手動テストの必要性を排除し、人的ミスを減らし、開発ワークフローを加速させます。
このスキルは、エンドツーエンドのブラウザ自動化をカバーする幅広い強力な機能を提供します。localhostでのテスト用に開発サーバーを自動検出したり、一時ディレクトリ内に整理されたクリーンなテストスクリプトを生成したり、デフォルトで表示可能なブラウザ内でそれらを実行したりすることができます。 ユーザーは、URLのパラメータ化、複数のビューポートでのテスト、レスポンシブデザインの確認、ログインフローの検証、リンクやその他のWebインタラクションの確認を簡単に行うことができます。 このスキルでは、スクリプトが `/tmp` に書き込まれ、オペレーティングシステムによって自動的に削除されるため、テストファイルがプロジェクトディレクトリを散らかすことはありません。セットアップは簡単で、Playwright と Chromium ブラウザを一度インストールするだけで済みます。
このスキルは、Web機能の検証、反復的なブラウザ操作の自動化、あるいは複雑なテストシナリオの実行を必要とするWeb開発者、QAエンジニア、自動化テスターに最適です。基本的なページテストやスクリーンショットの取得から、Webアプリケーションの包括的なエンドツーエンドテストに至るまで、幅広いタスクに活用できます。 ローカル開発環境や外部ウェブサイトのテスト、あるいはデバイス間でのUXの一貫性を確保する場合でも、Playwright Browser Automation を使用すれば、信頼性が高く、再現性があり、効率的なブラウザ自動化ワークフローを実行できます。
よくある質問
Playwright Browser Automationを初めてセットアップするにはどうすればよいですか?
スキルディレクトリに移動し、`npm run setup` を実行してください。これにより、すべての自動化タスクに必要な Playwright と Chromium ブラウザがインストールされます。このセットアップは一度だけ行えば十分です。
ローカルの開発サーバーと外部ウェブサイトの両方をテストできますか?
はい。このスキルは、localhostでのテスト用に実行中の開発サーバーを自動的に検出します。サーバーが見つからない場合や、外部サイトをテストしたい場合は、URLを手動で指定できます。
このスキルはデフォルトでヘッドレスで実行されますか?
いいえ。デバッグを容易にするため、デフォルトでは画面表示のあるブラウザ(`headless: false`)が起動されますが、必要に応じてヘッドレスモードを有効にすることも可能です。
テストスクリプトはどこに保存され、実行されますか?
テストスクリプトは、スキルやプロジェクトのディレクトリが散らかるのを防ぐため、常に `/tmp` 内の一時ファイル(例:`/tmp/playwright-test-*.js`)に書き込まれます。これらは、Node.js を使用してスキルディレクトリから実行されます。
どのようなブラウザ操作を自動化できますか?
ページ間の移動、フォームへの入力、スクリーンショットの取得、レスポンシブデザインの確認、UXの検証、ログインフローのテスト、リンクやその他のWeb操作の確認など、ブラウザベースのあらゆるタスクを自動化できます。
IMPORTANT - Path Resolution:This skill can be installed in different locations (plugin system, manual installation, global, or project-specific). Before executing any commands, determine the skill directory based on where you loaded this SKILL.md file, and use that path in all commands below. Replace $SKILL_DIR with the actual discovered path.
Common installation paths:
- Plugin system:
~/.claude/plugins/marketplaces/playwright-skill/skills/playwright-skill - Manual global:
~/.claude/skills/playwright-skill - Project-specific:
<project>/.claude/skills/playwright-skill
Playwright Browser Automation
General-purpose browser automation skill. I'll write custom Playwright code for any automation task you request and execute it via the universal executor.
CRITICAL WORKFLOW - Follow these steps in order:
Auto-detect dev servers - For localhost testing, ALWAYS run server detection FIRST:
cd $SKILL_DIR && node -e "require('./lib/helpers').detectDevServers().then(servers => console.log(JSON.stringify(servers)))"
- If 1 server found: Use it automatically, inform user
- If multiple servers found: Ask user which one to test
- If no servers found: Ask for URL or offer to help start dev server
Write scripts to /tmp - NEVER write test files to skill directory; always use
/tmp/playwright-test-*.jsUse visible browser by default - Always use
headless: falseunless user specifically requests headless modeParameterize URLs - Always make URLs configurable via environment variable or constant at top of script
How It Works
- You describe what you want to test/automate
- I auto-detect running dev servers (or ask for URL if testing external site)
- I write custom Playwright code in
/tmp/playwright-test-*.js(won't clutter your project) - I execute it via:
cd $SKILL_DIR && node run.js /tmp/playwright-test-*.js - Results displayed in real-time, browser window visible for debugging
- Test files auto-cleaned from /tmp by your OS
Setup (First Time)
cd $SKILL_DIRnpm run setup
This installs Playwright and Chromium browser. Only needed once.
Execution Pattern
Step 1: Detect dev servers (for localhost testing)
cd $SKILL_DIR && node -e "require('./lib/helpers').detectDevServers().then(s => console.log(JSON.stringify(s)))"
Step 2: Write test script to /tmp with URL parameter
// /tmp/playwright-test-page.jsconst { chromium } = require('playwright');// Parameterized URL (detected or user-provided)const TARGET_URL = 'http://localhost:3001'; // <-- Auto-detected or from user(async () => { const browser = await chromium.launch({ headless: false }); const page = await browser.newPage(); await page.goto(TARGET_URL); console.log('Page loaded:', await page.title()); await page.screenshot({ path: '/tmp/screenshot.png', fullPage: true }); console.log('📸 Screenshot saved to /tmp/screenshot.png'); await browser.close();})();
Step 3: Execute from skill directory
cd $SKILL_DIR && node run.js /tmp/playwright-test-page.js
Common Patterns
Test a Page (Multiple Viewports)
// /tmp/playwright-test-responsive.jsconst { chromium } = require('playwright');const TARGET_URL = 'http://localhost:3001'; // Auto-detected(async () => { const browser = await chromium.launch({ headless: false, slowMo: 100 }); const page = await browser.newPage(); // Desktop test await page.setViewportSize({ width: 1920, height: 1080 }); await page.goto(TARGET_URL); console.log('Desktop - Title:', await page.title()); await page.screenshot({ path: '/tmp/desktop.png', fullPage: true }); // Mobile test await page.setViewportSize({ width: 375, height: 667 }); await page.screenshot({ path: '/tmp/mobile.png', fullPage: true }); await browser.close();})();
Test Login Flow
// /tmp/playwright-test-login.jsconst { chromium } = require('playwright');const TARGET_URL = 'http://localhost:3001'; // Auto-detected(async () => { const browser = await chromium.launch({ headless: false }); const page = await browser.newPage(); await page.goto(`${TARGET_URL}/login`); await page.fill('input[name="email"]', '[email protected]'); await page.fill('input[name="password"]', 'password123'); await page.click('button[type="submit"]'); // Wait for redirect await page.waitForURL('**/dashboard'); console.log('✅ Login successful, redirected to dashboard'); await browser.close();})();
Fill and Submit Form
// /tmp/playwright-test-form.jsconst { chromium } = require('playwright');const TARGET_URL = 'http://localhost:3001'; // Auto-detected(async () => { const browser = await chromium.launch({ headless: false, slowMo: 50 }); const page = await browser.newPage(); await page.goto(`${TARGET_URL}/contact`); await page.fill('input[name="name"]', 'John Doe'); await page.fill('input[name="email"]', '[email protected]'); await page.fill('textarea[name="message"]', 'Test message'); await page.click('button[type="submit"]'); // Verify submission await page.waitForSelector('.success-message'); console.log('✅ Form submitted successfully'); await browser.close();})();
Check for Broken Links
const { chromium } = require('playwright');(async () => { const browser = await chromium.launch({ headless: false }); const page = await browser.newPage(); await page.goto('http://localhost:3000'); const links = await page.locator('a[href^="http"]').all(); const results = { working: 0, broken: [] }; for (const link of links) { const href = await link.getAttribute('href'); try { const response = await page.request.head(href); if (response.ok()) { results.working++; } else { results.broken.push({ url: href, status: response.status() }); } } catch (e) { results.broken.push({ url: href, error: e.message }); } } console.log(`✅ Working links: ${results.working}`); console.log(`❌ Broken links:`, results.broken); await browser.close();})();
Take Screenshot with Error Handling
const { chromium } = require('playwright');(async () => { const browser = await chromium.launch({ headless: false }); const page = await browser.newPage(); try { await page.goto('http://localhost:3000', { waitUntil: 'networkidle', timeout: 10000 }); await page.screenshot({ path: '/tmp/screenshot.png', fullPage: true }); console.log('📸 Screenshot saved to /tmp/screenshot.png'); } catch (error) { console.error('❌ Error:', error.message); } finally { await browser.close(); }})();
Test Responsive Design
// /tmp/playwright-test-responsive-full.jsconst { chromium } = require('playwright');const TARGET_URL = 'http://localhost:3001'; // Auto-detected(async () => { const browser = await chromium.launch({ headless: false }); const page = await browser.newPage(); const viewports = [ { name: 'Desktop', width: 1920, height: 1080 }, { name: 'Tablet', width: 768, height: 1024 }, { name: 'Mobile', width: 375, height: 667 } ]; for (const viewport of viewports) { console.log(`Testing ${viewport.name} (${viewport.width}x${viewport.height})`); await page.setViewportSize({ width: viewport.width, height: viewport.height }); await page.goto(TARGET_URL); await page.waitForTimeout(1000); await page.screenshot({ path: `/tmp/${viewport.name.toLowerCase()}.png`, fullPage: true }); } console.log('✅ All viewports tested'); await browser.close();})();
Inline Execution (Simple Tasks)
For quick one-off tasks, you can execute code inline without creating files:
# Take a quick screenshotcd $SKILL_DIR && node run.js "const browser = await chromium.launch({ headless: false });const page = await browser.newPage();await page.goto('http://localhost:3001');await page.screenshot({ path: '/tmp/quick-screenshot.png', fullPage: true });console.log('Screenshot saved');await browser.close();"
When to use inline vs files:
- Inline: Quick one-off tasks (screenshot, check if element exists, get page title)
- Files: Complex tests, responsive design checks, anything user might want to re-run
Available Helpers
Optional utility functions in lib/helpers.js:
const helpers = require('./lib/helpers');// Detect running dev servers (CRITICAL - use this first!)const servers = await helpers.detectDevServers();console.log('Found servers:', servers);// Safe click with retryawait helpers.safeClick(page, 'button.submit', { retries: 3 });// Safe type with clearawait helpers.safeType(page, '#username', 'testuser');// Take timestamped screenshotawait helpers.takeScreenshot(page, 'test-result');// Handle cookie bannersawait helpers.handleCookieBanner(page);// Extract table dataconst data = await helpers.extractTableData(page, 'table.results');
See lib/helpers.js for full list.
Custom HTTP Headers
Configure custom headers for all HTTP requests via environment variables. Useful for:
- Identifying automated traffic to your backend
- Getting LLM-optimized responses (e.g., plain text errors instead of styled HTML)
- Adding authentication tokens globally
Configuration
Single header (common case):
PW_HEADER_NAME=X-Automated-By PW_HEADER_VALUE=playwright-skill \ cd $SKILL_DIR && node run.js /tmp/my-script.js
Multiple headers (JSON format):
PW_EXTRA_HEADERS='{"X-Automated-By":"playwright-skill","X-Debug":"true"}' \ cd $SKILL_DIR && node run.js /tmp/my-script.js
How It Works
Headers are automatically applied when using helpers.createContext():
const context = await helpers.createContext(browser);const page = await context.newPage();// All requests from this page include your custom headers
For scripts using raw Playwright API, use the injected getContextOptionsWithHeaders():
const context = await browser.newContext( getContextOptionsWithHeaders({ viewport: { width: 1920, height: 1080 } }));
Advanced Usage
For comprehensive Playwright API documentation, see API_REFERENCE.md:
- Selectors & Locators best practices
- Network interception & API mocking
- Authentication & session management
- Visual regression testing
- Mobile device emulation
- Performance testing
- Debugging techniques
- CI/CD integration
Tips
- CRITICAL: Detect servers FIRST - Always run
detectDevServers()before writing test code for localhost testing - Custom headers - Use
PW_HEADER_NAME/PW_HEADER_VALUEenv vars to identify automated traffic to your backend - Use /tmp for test files - Write to
/tmp/playwright-test-*.js, never to skill directory or user's project - Parameterize URLs - Put detected/provided URL in a
TARGET_URLconstant at the top of every script - DEFAULT: Visible browser - Always use
headless: falseunless user explicitly asks for headless mode - Headless mode - Only use
headless: truewhen user specifically requests "headless" or "background" execution - Slow down: Use
slowMo: 100to make actions visible and easier to follow - Wait strategies: Use
waitForURL,waitForSelector,waitForLoadStateinstead of fixed timeouts - Error handling: Always use try-catch for robust automation
- Console output: Use
console.log()to track progress and show what's happening
Troubleshooting
Playwright not installed:
cd $SKILL_DIR && npm run setup
Module not found:Ensure running from skill directory via run.js wrapper
Browser doesn't open:Check headless: false and ensure display available
Element not found:Add wait: await page.waitForSelector('.element', { timeout: 10000 })
Example Usage
User: "Test if the marketing page looks good"Claude: I'll test the marketing page across multiple viewports. Let me first detect running servers...[Runs: detectDevServers()][Output: Found server on port 3001]I found your dev server running on http://localhost:3001[Writes custom automation script to /tmp/playwright-test-marketing.js with URL parameterized][Runs: cd $SKILL_DIR && node run.js /tmp/playwright-test-marketing.js][Shows results with screenshots from /tmp/]User: "Check if login redirects correctly"Claude: I'll test the login flow. First, let me check for running servers...[Runs: detectDevServers()][Output: Found servers on ports 3000 and 3001]I found 2 dev servers. Which one should I test?- http://localhost:3000- http://localhost:3001User: "Use 3001"[Writes login automation to /tmp/playwright-test-login.js][Runs: cd $SKILL_DIR && node run.js /tmp/playwright-test-login.js][Reports: ✅ Login successful, redirected to /dashboard]Notes
- Each automation is custom-written for your specific request
- Not limited to pre-built scripts - any browser task possible
- Auto-detects running dev servers to eliminate hardcoded URLs
- Test scripts written to
/tmpfor automatic cleanup (no clutter) - Code executes reliably with proper module resolution via
run.js - Progressive disclosure - API_REFERENCE.md loaded only when advanced features needed
Playwright Browser Automationをインストール
スキルファイルをダウンロードし、.claude/skills/ ディレクトリに解凍してください。
ZIPをダウンロードリポジトリをクローンし、スキルファイルをプロジェクトにコピーしてください。
git clone https://github.com/Microck/ordinary-claude-skills/blob/main/skills_all/playwright-browser-automation/SKILL.md # Copy SKILL.md to your .claude/skills/ directory
コピー





家
