
About
Browser automation powers web testing, scraping, and AI agent
name: browser-automation description: Browser automation powers web testing, scraping, and AI agent interactions. The difference between a flaky script and a reliable system comes down to understanding selectors, waiting strategies, and anti-detection patterns. risk: unknown source: vibeship-spawner-skills (Apache 2.0) date_added: 2026-02-27
Browser Automation
Browser automation powers web testing, scraping, and AI agent interactions. The difference between a flaky script and a reliable system comes down to understanding selectors, waiting strategies, and anti-detection patterns.
This skill covers Playwright (recommended) and Puppeteer, with patterns for testing, scraping, and agentic browser control. Key insight: Playwright won the framework war. Unless you need Puppeteer's stealth ecosystem or are Chrome-only, Playwright is the better choice in 2025.
Critical distinction: Testing automation (predictable apps you control) vs scraping/agent automation (unpredictable sites that fight back). Different problems, different solutions.
Principles
- Use user-facing locators (getByRole, getByText) over CSS/XPath
- Never add manual waits - Playwright's auto-wait handles it
- Each test/task should be fully isolated with fresh context
- Screenshots and traces are your debugging lifeline
- Headless for CI, headed for debugging
- Anti-detection is cat-and-mouse - stay current or get blocked
Capabilities
- browser-automation
- playwright
- puppeteer
- headless-browsers
- web-scraping
- browser-testing
- e2e-testing
- ui-automation
- selenium-alternatives
Scope
- api-testing → backend
- load-testing → performance-thinker
- accessibility-testing → accessibility-specialist
- visual-regression-testing → ui-design
Tooling
Frameworks
- Playwright - When: Default choice - cross-browser, auto-waiting, best DX Note: 96% success rate, 4.5s avg execution, Microsoft-backed
- Puppeteer - When: Chrome-only, need stealth plugins, existing codebase Note: 75% success rate at scale, but best stealth ecosystem
- Selenium - When: Legacy systems, specific language bindings Note: Slower, more verbose, but widest browser support
Stealth_tools
- puppeteer-extra-plugin-stealth - When: Need to bypass bot detection with Puppeteer Note: Gold standard for anti-detection
- playwright-extra - When: Stealth plugins for Playwright Note: Port of puppeteer-extra ecosystem
- undetected-chromedriver - When: Selenium anti-detection Note: Dynamic bypass of detection
Cloud_browsers
- Browserbase - When: Managed headless infrastructure Note: Built-in stealth mode, session management
- BrowserStack - When: Cross-browser testing at scale Note: Real devices, CI integration
Patterns
Test Isolation Pattern
Each test runs in complete isolation with fresh state
When to use: Testing, any automation that needs reproducibility
TEST ISOLATION:
""" Each test gets its own:
- Browser context (cookies, storage)
- Fresh page
- Clean state """
Playwright Test Example
""" import { test, expect } from '@playwright/test';
// Each test runs in isolated browser context test('user can add item to cart', async ({ page }) => { // Fresh context - no cookies, no storage from other tests await page.goto('/products'); await page.getByRole('button', { name: 'Add to Cart' }).click(); await expect(page.getByTestId('cart-count')).toHaveText('1'); });
test('user can remove item from cart', async ({ page }) => { // Completely isolated - cart is empty await page.goto('/cart'); await expect(page.getByText('Your cart is empty')).toBeVisible(); }); """
Shared Authentication Pattern
""" // Save auth state once, reuse across tests // setup.ts import { test as setup } from '@playwright/test';
setup('authenticate', async ({ page }) => { await page.goto('/login'); await page.getByLabel('Email').fill('user@example.com'); await page.getByLabel('Password').fill('password'); await page.getByRole('button', { name: 'Sign in' }).click();
// Wait for auth to complete await page.waitForURL('/dashboard');
// Save authentication state await page.context().storageState({ path: './playwright/.auth/user.json' }); });
// playwright.config.ts export default defineConfig({ projects: [ { name: 'setup', testMatch: /.*.setup.ts/ }, { name: 'tests', dependencies: ['setup'], use: { storageState: './playwright/.auth/user.json', }, }, ], }); """
User-Facing Locator Pattern
Select elements the way users see them
When to use: Always - the default approach for selectors
USER-FACING LOCATORS:
""" Priority order:
- getByRole - Best: matches accessibility tree
- getByText - Good: matches visible content
- getByLabel - Good: matches form labels
- getByTestId - Fallback: explicit test contracts
- CSS/XPath - Last resort: fragile, avoid """
Good Examples (User-Facing)
""" // By role - THE BEST CHOICE await page.getByRole('button', { name: