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
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:
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 retry
await
helpers
.
safeClick
(
page
,
'button.submit'
,
{
retries
:
3
}
)
;
// Safe type with clear
await
helpers
.
safeType
(
page
,
'#username'
,
'testuser'
)
;
// Take timestamped screenshot
await
helpers
.
takeScreenshot
(
page
,
'test-result'
)
;
// Handle cookie banners
await
helpers
.
handleCookieBanner
(
page
)
;
// Extract table data
const
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_VALUE
env 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_URL
constant at the top of every script
DEFAULT: Visible browser
- Always use
headless: false
unless user explicitly asks for headless mode
Headless mode
- Only use
headless: true
when user specifically requests "headless" or "background" execution
Slow down:
Use
slowMo: 100
to make actions visible and easier to follow
Wait strategies:
Use
waitForURL
,
waitForSelector
,
waitForLoadState
instead 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:3001
User: "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
/tmp
for 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
When to Use
This skill is applicable to execute the workflow or actions described in the overview.