Install
$ agentstack add skill-ryankolean-summit-claude-skills-cli-playwright ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Playwright — Browser Automation & Testing
Repo: https://github.com/microsoft/playwright
Playwright drives Chromium, Firefox, and WebKit from Node.js (or Python/Java/.NET). Use it for end-to-end tests, scraping, screenshots, PDFs, and any workflow that requires a real browser with JavaScript execution.
When to Activate
Manual triggers:
- "How do I use Playwright?"
- "Write a Playwright test"
- "Take a screenshot / generate a PDF with a browser"
- "Intercept network requests in a test"
Auto-detect triggers:
- User wants end-to-end browser tests
- User needs to scrape a JS-heavy site
- User asks about visual regression testing
- User wants to record a browser interaction
Key Commands
Install & Setup
npm init playwright@latest # scaffold new project (installs browsers too)
npx playwright install # install/update all browsers
npx playwright install chromium # install only Chromium
npx playwright install --with-deps # also install OS dependencies (CI)
Run Tests
npx playwright test # run all tests
npx playwright test tests/login.spec.ts # run a specific file
npx playwright test --grep "checkout" # run tests matching pattern
npx playwright test --project=chromium # run in one browser only
npx playwright test --headed # show browser window
npx playwright test --ui # open interactive UI mode
npx playwright test --debug # open Playwright Inspector
npx playwright test --workers=4 # parallel workers
npx playwright test --retries=2 # retry flaky tests
Code Generation
npx playwright codegen https://example.com # record actions → test code
npx playwright codegen --device="iPhone 13" URL # record with mobile emulation
npx playwright codegen --save-storage=auth.json URL # record and save auth state
Reporting
npx playwright show-report # open last HTML report in browser
npx playwright show-report ./my-report # open report from specific path
npx playwright show-trace trace.zip # open a trace archive
Screenshots & PDFs (CLI one-liners)
npx playwright screenshot https://example.com shot.png
npx playwright screenshot --full-page https://example.com full.png
npx playwright pdf https://example.com page.pdf
Core API
Page Navigation & Interaction
import { chromium } from '@playwright/test';
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://example.com'); // navigate
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await page.click('text=Sign in'); // click by text
await page.fill('#email', 'user@example.com'); // fill input
await page.press('#password', 'Enter'); // key press
await page.selectOption('select#country', 'US'); // select dropdown
await page.check('#agree'); // check checkbox
await page.hover('.menu-item'); // hover
await page.waitForSelector('.dashboard'); // wait for element
await page.waitForLoadState('networkidle'); // wait for network quiet
await page.waitForURL('**/dashboard'); // wait for URL change
Locators (preferred over selectors)
// Locators are auto-waiting and retry-able
const btn = page.locator('button[type=submit]');
const byText = page.getByText('Continue');
const byRole = page.getByRole('button', { name: 'Submit' });
const byLabel = page.getByLabel('Email address');
const byPlaceholder = page.getByPlaceholder('Search...');
const byTestId = page.getByTestId('login-btn'); // data-testid attribute
await btn.click();
await byLabel.fill('hello@world.com');
await expect(byRole).toBeEnabled();
Assertions (test mode)
import { expect } from '@playwright/test';
await expect(page).toHaveURL('/dashboard');
await expect(page).toHaveTitle('Dashboard');
await expect(page.locator('h1')).toHaveText('Welcome');
await expect(page.locator('.alert')).toBeVisible();
await expect(page.locator('input')).toBeEnabled();
await expect(page.locator('img')).toHaveAttribute('src', /avatar/);
Screenshots & PDFs (API)
await page.screenshot({ path: 'shot.png' });
await page.screenshot({ path: 'full.png', fullPage: true });
await page.locator('.chart').screenshot({ path: 'chart.png' });
await page.pdf({ path: 'page.pdf', format: 'A4' });
JavaScript Evaluation
const title = await page.evaluate(() => document.title);
const links = await page.evaluate(() =>
Array.from(document.querySelectorAll('a')).map(a => a.href)
);
await page.evaluate((val) => { window.localStorage.setItem('key', val); }, 'hello');
Advanced Patterns
Visual Regression Testing
// First run creates baseline snapshots; subsequent runs diff against them
await expect(page).toHaveScreenshot('home.png');
await expect(page.locator('.hero')).toHaveScreenshot('hero.png', {
maxDiffPixelRatio: 0.01, // allow 1% pixel difference
});
// Update snapshots: npx playwright test --update-snapshots
Parallel Tests
// playwright.config.ts
export default {
workers: process.env.CI ? 2 : undefined, // auto on local, limited on CI
fullyParallel: true, // tests within a file run in parallel
};
Trace Viewer
// playwright.config.ts — record traces on failure
use: {
trace: 'on-first-retry', // 'on', 'off', 'retain-on-failure'
}
// Inspect: npx playwright show-trace trace.zip
Mobile Emulation
import { devices } from '@playwright/test';
// playwright.config.ts
projects: [
{ name: 'Mobile Chrome', use: { ...devices['Pixel 5'] } },
{ name: 'Mobile Safari', use: { ...devices['iPhone 13'] } },
],
Network Interception
// Block images and fonts to speed up tests
await page.route('**/*.{png,jpg,jpeg,gif,svg,woff,woff2}', r => r.abort());
// Mock an API response
await page.route('**/api/users', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify([{ id: 1, name: 'Alice' }]),
});
});
// Intercept and modify a request
await page.route('**/api/search', async route => {
const req = route.request();
await route.continue({ headers: { ...req.headers(), 'X-Custom': 'value' } });
});
Auth Handling (reuse sessions)
// Save auth state after login
const page = await browser.newPage();
await page.goto('/login');
await page.fill('#user', 'admin');
await page.fill('#pass', 'secret');
await page.click('[type=submit]');
await page.context().storageState({ path: 'auth.json' });
// playwright.config.ts — reuse state for all tests
use: { storageState: 'auth.json' }
Request/Response Logging
page.on('request', req => console.log('>>', req.method(), req.url()));
page.on('response', resp => console.log(' console.log('BROWSER:', msg.text()));
Practical Examples
Scrape a Table to JSON
const rows = await page.locator('table tbody tr').evaluateAll(trs =>
trs.map(tr => ({
name: tr.cells[0].textContent?.trim(),
price: tr.cells[1].textContent?.trim(),
}))
);
console.log(JSON.stringify(rows, null, 2));
Download a File
const [download] = await Promise.all([
page.waitForEvent('download'),
page.click('a[href$=".csv"]'),
]);
await download.saveAs('./data.csv');
Handle Dialogs
page.on('dialog', dialog => dialog.accept()); // auto-dismiss all dialogs
Paginate and Collect Data
const results = [];
while (true) {
const items = await page.locator('.item').allTextContents();
results.push(...items);
const next = page.locator('a.next');
if (!(await next.isVisible())) break;
await next.click();
await page.waitForLoadState('networkidle');
}
Chaining with Other Skills
- Apify (cli-apify): Use Playwright inside an Apify Actor for cloud-scale scraping with proxy rotation and scheduling; Playwright handles rendering, Apify handles infrastructure.
- jq: Pipe
page.evaluate()JSON output to jq for filtering —node scrape.js | jq '.[] | select(.price < 50)'. - fzf (cli-fzf): Pipe test names from
npx playwright test --listinto fzf to interactively pick which test to run.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: ryankolean
- Source: ryankolean/summit-claude-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.