skills/oimiragieo/agent-studio/browser-automation

browser-automation

Installation
SKILL.md

Browser Automation Skill

Setup

pip install playwright && playwright install chromium
pip install playwright-stealth  # optional, for anti-detection

Skill Comparison

Skill Use Case
browser-automation Scripted automation, data pipelines, form bots
webapp-testing QA assertions, visual regression, test suites
chrome-browser Interactive MCP DevTools control

Iron Law

NEVER USE time.sleep() — use page.wait_for_selector() or wait_for_load_state()

Core Patterns

Navigation and Extraction

with sync_playwright() as p:
    context = p.chromium.launch(headless=True).new_context(
        user_agent="Mozilla/5.0 ...", viewport={"width": 1280, "height": 720})
    page = context.new_page()
    page.goto(url); page.wait_for_load_state("networkidle")
    items = [i.inner_text() for i in page.get_by_role("listitem").all()]

Form Filling

page.get_by_label("Email").fill("user@example.com")
page.get_by_label("Password").fill("secret")
with page.expect_navigation():
    page.get_by_role("button", name="Submit").click()

Screenshot and PDF

page.screenshot(path="full.png", full_page=True)
page.pdf(path="page.pdf", format="A4", print_background=True)

Auth Session Management

# Save session
context.storage_state(path="auth-state.json")
# Reuse session
context = browser.new_context(storage_state="auth-state.json")

Anti-Detection

browser = p.chromium.launch(args=["--disable-blink-features=AutomationControlled"])
context = browser.new_context(user_agent="...", locale="en-US", timezone_id="America/New_York")
page.add_init_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")

Agent Usage

  • Save extracted data to .claude/context/tmp/ as structured JSON
  • Save screenshots/PDFs to .claude/context/artifacts/
  • Never commit auth-state.json — add to .gitignore

Anti-Patterns

Anti-Pattern Correct Approach
time.sleep() for waits page.wait_for_selector() / wait_for_load_state()
CSS selectors for forms get_by_label(), get_by_role()
Re-login each run context.storage_state() persistence
Committing auth state Add auth-state.json to .gitignore

Memory Protocol (MANDATORY)

Before starting: Read .claude/context/memory/learnings.md

After completing:

  • New extraction pattern -> .claude/context/memory/learnings.md
  • Bot detection encountered -> .claude/context/memory/issues.md

ASSUME INTERRUPTION: If it's not in memory, it didn't happen.

Weekly Installs
1
GitHub Stars
25
First Seen
Mar 22, 2026