seed-skills/browser-use/SKILL.md
CLI tool for persistent browser automation with multi-session support, featuring Chromium/Real/Remote browser modes, cookie management, JavaScript execution, and long-running automation workflows.
npx skillsauth add PramodDutta/qaskills Browser-Use AutomationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are an expert in browser automation using browser-use, a powerful CLI tool designed for persistent, multi-session browser automation. When the user asks you to automate complex browser workflows, manage sessions, or perform long-running automation tasks, follow these detailed instructions.
# Install via npm
npm install -g browser-use
# Or use with npx
npx browser-use --version
# Install with Python
pip install browser-use
# Verify installation
browser-use --help
# Launch Chromium in headless mode
browser-use start --mode chromium --headless
# With custom user data directory
browser-use start --mode chromium --user-data-dir ./browser-data
# With custom viewport
browser-use start --mode chromium --viewport 1920x1080
# Launch visible Chrome browser
browser-use start --mode real --browser chrome
# Launch Firefox
browser-use start --mode real --browser firefox
# Launch with specific profile
browser-use start --mode real --browser chrome --profile "Profile 1"
# Connect to remote Chrome DevTools Protocol
browser-use start --mode remote --cdp-url ws://localhost:9222
# Connect to Selenium Grid
browser-use start --mode remote --selenium-url http://localhost:4444/wd/hub
# Create named session
browser-use session create --name "user-session-1" --persist
# List all sessions
browser-use session list
# Attach to existing session
browser-use session attach --name "user-session-1"
# Delete session
browser-use session delete --name "user-session-1"
# Export session state
browser-use session export --name "user-session-1" --output ./session-state.json
# Import session state
browser-use session import --input ./session-state.json --name "restored-session"
Session List Output:
{
"sessions": [
{
"name": "user-session-1",
"id": "abc123",
"created": "2024-02-12T10:00:00Z",
"lastActive": "2024-02-12T10:30:00Z",
"persistent": true,
"tabs": 3
},
{
"name": "test-session-2",
"id": "def456",
"created": "2024-02-12T11:00:00Z",
"lastActive": "2024-02-12T11:15:00Z",
"persistent": false,
"tabs": 1
}
]
}
# Run multiple sessions in parallel
browser-use parallel --sessions "session-1,session-2,session-3" \
--command "navigate --url https://example.com"
# Run different commands per session
browser-use parallel \
--session session-1 --command "navigate --url https://site1.com" \
--session session-2 --command "navigate --url https://site2.com" \
--session session-3 --command "navigate --url https://site3.com"
# Export cookies from session
browser-use cookies export --session "user-session-1" --output cookies.json
# Export specific domain cookies
browser-use cookies export --session "user-session-1" --domain "example.com" --output example-cookies.json
# Import cookies into session
browser-use cookies import --session "user-session-1" --input cookies.json
# Import cookies for specific domain
browser-use cookies import --session "user-session-1" --input auth-cookies.json --domain "app.example.com"
# Clear all cookies
browser-use cookies clear --session "user-session-1"
# Clear cookies for specific domain
browser-use cookies clear --session "user-session-1" --domain "example.com"
Cookie Export Format:
{
"cookies": [
{
"name": "session_token",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"domain": ".example.com",
"path": "/",
"expires": 1707753600,
"httpOnly": true,
"secure": true,
"sameSite": "Lax"
},
{
"name": "user_preferences",
"value": "theme=dark&lang=en",
"domain": "app.example.com",
"path": "/",
"expires": 1739289600,
"httpOnly": false,
"secure": true,
"sameSite": "Strict"
}
]
}
#!/bin/bash
# auth-persist.sh - Login once, reuse session
SESSION_NAME="authenticated-user"
# Check if session exists
if browser-use session list | grep -q "$SESSION_NAME"; then
echo "Using existing authenticated session"
browser-use session attach --name "$SESSION_NAME"
else
echo "Creating new authenticated session"
browser-use session create --name "$SESSION_NAME" --persist
# Perform login
browser-use navigate --url "https://app.example.com/login"
browser-use type --selector "#email" --text "[email protected]"
browser-use type --selector "#password" --text "$PASSWORD"
browser-use click --selector "button[type='submit']"
browser-use wait --selector ".dashboard" --timeout 10000
# Export cookies for backup
browser-use cookies export --session "$SESSION_NAME" --output auth-cookies.json
echo "Session authenticated and cookies saved"
fi
# Now use authenticated session
browser-use navigate --url "https://app.example.com/dashboard"
# Execute simple JavaScript
browser-use execute --script "return document.title"
# Execute with arguments
browser-use execute --script "return arguments[0] + arguments[1]" --args "[5, 10]"
# Execute and save result
browser-use execute --script "return document.querySelectorAll('.item').length" --output item-count.json
# Execute script from file
browser-use execute --script-file ./custom-script.js
Example Script File (custom-script.js):
// Extract all product data from page
const products = Array.from(document.querySelectorAll('.product-card')).map(card => {
return {
name: card.querySelector('.product-name')?.textContent.trim(),
price: card.querySelector('.product-price')?.textContent.trim(),
image: card.querySelector('.product-image')?.src,
rating: card.querySelector('.rating')?.getAttribute('data-rating'),
available: !card.querySelector('.out-of-stock')
};
});
return { products, total: products.length };
# Execute the script
browser-use execute --script-file ./extract-products.js --output products.json
# Wait for dynamic content with custom condition
browser-use execute --script "
return new Promise(resolve => {
const check = () => {
if (document.querySelectorAll('.loaded-item').length >= 10) {
resolve(true);
} else {
setTimeout(check, 100);
}
};
check();
});
"
# Manipulate page elements
browser-use execute --script "
document.querySelectorAll('.annoying-popup').forEach(el => el.remove());
document.body.style.backgroundColor = '#f0f0f0';
return 'Page modified';
"
# Trigger events
browser-use execute --script "
const event = new Event('custom-event');
document.dispatchEvent(event);
return 'Event triggered';
"
# Navigate with custom headers
browser-use navigate --url "https://api.example.com" \
--headers '{"Authorization": "Bearer token123", "X-Custom": "value"}'
# Navigate with POST data
browser-use navigate --url "https://example.com/search" \
--method POST \
--data '{"query": "automation", "filters": ["category:tools"]}'
# Navigate with referer
browser-use navigate --url "https://example.com/protected" \
--referer "https://example.com/home"
# Navigate and wait for specific event
browser-use navigate --url "https://example.com" \
--wait-for-event "load"
# Scroll to element
browser-use scroll --selector ".footer" --behavior smooth
# Scroll by pixels
browser-use scroll --delta "0,500"
# Scroll to top/bottom
browser-use scroll --position top
browser-use scroll --position bottom
# Hover over element
browser-use hover --selector ".dropdown-trigger"
# Focus element
browser-use focus --selector "input#search"
# Select dropdown option
browser-use select --selector "select#country" --value "US"
# Upload file
browser-use upload --selector "input[type='file']" --file ./document.pdf
# Download file
browser-use download --url "https://example.com/file.pdf" --output ./downloaded.pdf
# Open new tab
browser-use tab new --url "https://example.com"
# List all tabs
browser-use tab list
# Switch to tab by index
browser-use tab switch --index 0
# Switch to tab by URL pattern
browser-use tab switch --url-pattern "example.com"
# Close tab
browser-use tab close --index 1
# Close all tabs except current
browser-use tab close --others
# Duplicate tab
browser-use tab duplicate --index 0
Tab List Output:
{
"tabs": [
{
"index": 0,
"url": "https://example.com",
"title": "Example Domain",
"active": true
},
{
"index": 1,
"url": "https://google.com",
"title": "Google",
"active": false
}
],
"total": 2
}
# Start network monitoring
browser-use network start --filter "*.json"
# Navigate and capture requests
browser-use navigate --url "https://api.example.com"
# Get network log
browser-use network log --output network-requests.json
# Stop monitoring
browser-use network stop
Network Log Format:
{
"requests": [
{
"url": "https://api.example.com/users",
"method": "GET",
"status": 200,
"responseTime": 234,
"size": 1024,
"timestamp": "2024-02-12T10:30:00Z"
}
]
}
# Intercept and modify requests
browser-use intercept --pattern "*/api/*" \
--modify-headers '{"X-Custom-Header": "value"}' \
--modify-response-status 200
# Block specific requests
browser-use intercept --pattern "*.jpg" --block
# Mock API responses
browser-use intercept --pattern "*/api/users" \
--mock-response ./mock-users.json
import { BrowserUse } from 'browser-use';
interface BrowserUseConfig {
mode: 'chromium' | 'real' | 'remote';
headless?: boolean;
viewport?: { width: number; height: number };
userDataDir?: string;
}
class BrowserAutomation {
private browser: BrowserUse;
private sessionName: string;
constructor(sessionName: string, config: BrowserUseConfig = { mode: 'chromium' }) {
this.sessionName = sessionName;
this.browser = new BrowserUse(config);
}
async start(): Promise<void> {
await this.browser.session.create({
name: this.sessionName,
persist: true,
});
}
async navigate(url: string, options?: { waitUntil?: string }): Promise<void> {
await this.browser.navigate({ url, ...options });
}
async executeScript<T>(script: string | Function, args: any[] = []): Promise<T> {
const scriptStr = typeof script === 'function' ? script.toString() : script;
const result = await this.browser.execute({
script: scriptStr,
args,
});
return result.value as T;
}
async saveAuthCookies(filepath: string): Promise<void> {
await this.browser.cookies.export({
session: this.sessionName,
output: filepath,
});
}
async loadAuthCookies(filepath: string): Promise<void> {
await this.browser.cookies.import({
session: this.sessionName,
input: filepath,
});
}
async cleanup(): Promise<void> {
await this.browser.session.delete({ name: this.sessionName });
}
}
// Usage example
async function automateWorkflow() {
const automation = new BrowserAutomation('my-workflow-session');
try {
await automation.start();
// Check if we have saved auth cookies
const cookiesExist = await fs.promises.access('./auth-cookies.json')
.then(() => true)
.catch(() => false);
if (cookiesExist) {
// Restore authenticated session
await automation.loadAuthCookies('./auth-cookies.json');
await automation.navigate('https://app.example.com/dashboard');
} else {
// Perform fresh login
await automation.navigate('https://app.example.com/login');
// ... login steps ...
await automation.saveAuthCookies('./auth-cookies.json');
}
// Execute custom JavaScript
const itemCount = await automation.executeScript<number>(() => {
return document.querySelectorAll('.item').length;
});
console.log(`Found ${itemCount} items on page`);
} finally {
await automation.cleanup();
}
}
import json
from browser_use import BrowserUse
class BrowserAutomation:
def __init__(self, session_name: str, mode: str = "chromium", headless: bool = True):
self.session_name = session_name
self.browser = BrowserUse(mode=mode, headless=headless)
def start(self):
self.browser.session.create(name=self.session_name, persist=True)
def navigate(self, url: str, wait_until: str = "load"):
self.browser.navigate(url=url, wait_until=wait_until)
def execute_script(self, script: str, *args):
return self.browser.execute(script=script, args=list(args))
def save_cookies(self, filepath: str):
self.browser.cookies.export(session=self.session_name, output=filepath)
def load_cookies(self, filepath: str):
self.browser.cookies.import_(session=self.session_name, input=filepath)
def cleanup(self):
self.browser.session.delete(name=self.session_name)
# Usage
def main():
automation = BrowserAutomation("my-session")
try:
automation.start()
# Try to restore session
try:
automation.load_cookies("auth-cookies.json")
automation.navigate("https://app.example.com/dashboard")
print("Restored authenticated session")
except FileNotFoundError:
# Fresh login
automation.navigate("https://app.example.com/login")
# ... perform login ...
automation.save_cookies("auth-cookies.json")
print("New session authenticated")
# Extract data with JavaScript
data = automation.execute_script("""
return Array.from(document.querySelectorAll('.data-item')).map(el => ({
id: el.dataset.id,
text: el.textContent.trim()
}));
""")
print(f"Extracted {len(data)} items")
finally:
automation.cleanup()
if __name__ == "__main__":
main()
#!/bin/bash
# monitor-site.sh - Continuous site monitoring
SESSION="monitor-session"
INTERVAL=300 # 5 minutes
browser-use session create --name "$SESSION" --persist
browser-use navigate --url "https://status.example.com"
while true; do
# Execute monitoring script
STATUS=$(browser-use execute --script "
const statusEl = document.querySelector('.status-indicator');
return {
status: statusEl.textContent,
color: getComputedStyle(statusEl).backgroundColor,
timestamp: new Date().toISOString()
};
")
echo "$(date): $STATUS" >> monitor.log
# Check for failures
if echo "$STATUS" | grep -q "down"; then
browser-use snapshot --output "failure-$(date +%s).png"
# Send alert
curl -X POST https://alerts.example.com/notify -d "$STATUS"
fi
sleep $INTERVAL
browser-use execute --script "location.reload()"
done
async function processMultipleAccounts(accounts: Array<{ email: string; password: string }>) {
const sessions = await Promise.all(
accounts.map(async (account, index) => {
const sessionName = `account-${index}`;
const browser = new BrowserAutomation(sessionName);
await browser.start();
await browser.navigate('https://app.example.com/login');
// Login for each account
await browser.executeScript((email: string, password: string) => {
(document.querySelector('#email') as HTMLInputElement).value = email;
(document.querySelector('#password') as HTMLInputElement).value = password;
(document.querySelector('button[type="submit"]') as HTMLButtonElement).click();
}, account.email, account.password);
// Wait for dashboard
await new Promise(resolve => setTimeout(resolve, 3000));
// Save session
await browser.saveAuthCookies(`./cookies-${index}.json`);
return browser;
})
);
return sessions;
}
# Verbose logging
browser-use --debug navigate --url "https://example.com"
# Save console output
browser-use --console-output ./console.log navigate --url "https://example.com"
# Take screenshot on error
browser-use --screenshot-on-error ./errors/ navigate --url "https://example.com"
# Show DevTools
browser-use start --mode real --devtools
# Check session health
browser-use session health --name "my-session"
# Recover corrupted session
browser-use session recover --name "my-session" --backup ./session-backup.json
# Force delete stuck session
browser-use session delete --name "my-session" --force
# .github/workflows/browser-automation.yml
name: Browser Automation Tests
on: [push, pull_request]
jobs:
automation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install browser-use
run: npm install -g browser-use
- name: Run automation tests
env:
APP_PASSWORD: ${{ secrets.APP_PASSWORD }}
run: |
browser-use session create --name ci-session
bash ./automation-script.sh
browser-use session delete --name ci-session
- name: Upload artifacts
if: failure()
uses: actions/upload-artifact@v4
with:
name: failure-screenshots
path: ./screenshots/
This skill enables powerful, persistent browser automation with session management, making it ideal for long-running workflows, authenticated applications, and complex multi-step automations that AI agents need to orchestrate.
development
Generate test data from the schemas you already have. Read OpenAPI, JSON Schema, SQL DDL, or TypeScript models and produce deterministic factories, boundary and negative cases, relational datasets with valid foreign keys, cleanup scripts, and PII-safe synthetic data. Production records never leave the machine.
development
Diagnose flaky test failures from Playwright reports, traces, and rerun history. Classify each failure as product, test, environment, data, or unknown with cited evidence and a proposed fix. Never auto-modifies code without opt-in.
tools
Test LLM, RAG, MCP, and agentic systems end to end. Build golden datasets, run deterministic checks and LLM judges, score retrieval, probe prompt injection, verify tool use, and gate CI on thresholds. Orchestrates DeepEval, Ragas, promptfoo, and Langfuse.
development
Analyze a git diff, map affected risks, select the tests that matter, detect coverage gaps on changed lines, run configurable quality gates, and produce a go/no-go release report with cited evidence. Recommends only; never merges or deploys.