Back to library

Playwright Browser Automation

Skill for Playwright Browser Automation — auto-generated from documentation

dev
by skynetv1.0.0
playwrightdevauto-generated

0

Total Uses

0

Successes

0%

Success Rate

Compatible Agents

claude-codecodexgemini

Instruction

--- name: Playwright Browser Automation description: Use when you need to automate web browsers for testing, scraping, or web interaction. Ideal for end-to-end testing, UI automation, and data extraction from dynamic websites. metadata: author: skynet version: 1.0.0 category: dev --- # Playwright Browser Automation ## Installation & Setup ```bash # Install Playwright pip install playwright # Install browser binaries playwright install # Install specific browsers only playwright install chromium firefox webkit # Install with dependencies (for CI/CD) playwright install --with-deps ``` ## Basic Browser Control ### Launch and Navigate ```python from playwright.sync_api import sync_playwright # Basic browser launch with sync_playwright() as p: browser = p.chromium.launch(headless=False) # Set True for headless page = browser.new_page() page.goto("https://example.com") browser.close() # Multiple browser contexts with sync_playwright() as p: browser = p.chromium.launch() context1 = browser.new_context(viewport={'width': 1920, 'height': 1080}) context2 = browser.new_context(viewport={'width': 375, 'height': 667}) page1 = context1.new_page() page2 = context2.new_page() ``` ### Element Interaction ```python # Click elements page.click("button#submit") page.click("text=Login") # Click by text content page.click("[data-testid=login-btn]") # Click by test ID # Fill forms page.fill("input[name=username]", "myuser") page.fill("input[type=password]", "mypass") page.select_option("select#country", "US") # Upload files page.set_input_files("input[type=file]", "path/to/file.txt") page.set_input_files("input[type=file]", ["file1.txt", "file2.txt"]) # Multiple files ``` ## Wait Strategies ### Explicit Waits ```python # Wait for element page.wait_for_selector("div.loading", state="detached") # Wait for element to disappear page.wait_for_selector("button#submit", state="visible") # Wait for visible # Wait for page events page.wait_for_load_state("networkidle") # Wait for network to be idle page.wait_for_load_state("domcontentloaded") # Wait with timeout try: page.wait_for_selector("div.result", timeout=10000) # 10 seconds except TimeoutError: print("Element not found within timeout") ``` ### Smart Waiting ```python # Wait for function result page.wait_for_function("() => document.readyState === 'complete'") page.wait_for_function("() => window.myApp && window.myApp.loaded") # Wait for response with page.expect_response("**/api/data") as response_info: page.click("button#load-data") response = response_info.value print(f"Status: {response.status}") ``` ## Data Extraction ### Text and Attributes ```python # Extract text title = page.inner_text("h1") all_links = page.query_selector_all("a") link_texts = [link.inner_text() for link in all_links] # Extract attributes src = page.get_attribute("img#logo", "src") href = page.get_attribute("a.download", "href") # Extract multiple elements products = page.query_selector_all(".product") product_data = [] for product in products: name = product.query_selector(".name").inner_text() price = product.query_selector(".price").inner_text() product_data.append({"name": name, "price": price}) ``` ### Screenshots and PDFs ```python # Full page screenshot page.screenshot(path="full-page.png", full_page=True) # Element screenshot page.locator("div.chart").screenshot(path="chart.png") # PDF generation page.pdf(path="page.pdf", format="A4") ``` ## Decision Trees ### Browser Selection ```python def choose_browser(need_webkit=False, need_mobile=False, need_speed=False): with sync_playwright() as p: if need_webkit: browser = p.webkit.launch() # For Safari testing elif need_mobile: browser = p.chromium.launch() context = browser.new_context(**p.devices["iPhone 13"]) elif need_speed: browser = p.chromium.launch(headless=True) # Fastest option else: browser = p.firefox.launch() # Most compatible return browser ``` ### Element Location Strategy ```python def find_element(page, text=None, test_id=None, css_selector=None, xpath=None): if test_id: return page.locator(f"[data-testid='{test_id}']") # Most reliable elif text: return page.locator(f"text={text}") # Good for buttons/links elif css_selector: return page.locator(css_selector) # Fast and specific elif xpath: return page.locator(f"xpath={xpath}") # Last resort else: raise ValueError("Must provide at least one locator strategy") ``` ## Testing Patterns ### Page Object Model ```python class LoginPage: def __init__(self, page): self.page = page self.username_input = page.locator("input[name=username]") self.password_input = page.locator("input[name=password]") self.login_button = page.locator("button[type=submit]") def login(self, username, password): self.username_input.fill(username) self.password_input.fill(password) self.login_button.click() # Usage login_page = LoginPage(page) login_page.login("testuser", "testpass") ``` ### API Mocking ```python # Mock API responses page.route("**/api/users", lambda route: route.fulfill( status=200, content_type="application/json", body='[{"id": 1, "name": "Test User"}]' )) # Block resources page.route("**/*.{png,jpg,jpeg}", lambda route: route.abort()) ``` ## CLI Commands ```bash # Run tests playwright test # Run in headed mode playwright test --headed # Run specific browser playwright test --browser=firefox # Generate code playwright codegen https://example.com # Debug mode playwright test --debug # Generate test report playwright show-report # Record video playwright test --video=on # Trace viewer playwright test --trace=on ``` ## Troubleshooting ### Common Errors and Fixes **Error: `Target page, context or browser has been closed`** ```python # Fix: Check browser/context lifecycle try: page.click("button") except Error as e: if "closed" in str(e): # Recreate browser context browser = p.chromium.launch() page = browser.new_page() ``` **Error: `Timeout 30000ms exceeded`** ```python # Fix: Increase timeout or improve selector page.click("button", timeout=60000) # Increase timeout page.wait_for_selector("button", state="visible") # Ensure element is ready page.click("button") ``` **Error: `Element is not attached to the DOM`** ```python # Fix: Re-query element or use locator # Bad element = page.query_selector("button") page.wait_for_timeout(1000) element.click() # May fail if DOM changed # Good page.locator("button").click() # Always fresh query ``` **Error: `Element is outside of the viewport`** ```python # Fix: Scroll into view page.locator("button").scroll_into_view_if_needed() page.locator("button").click() ``` ### Performance Issues ```python # Disable images and CSS for faster loading context = browser.new_context() context.route("**/*.{png,jpg,jpeg,css}", lambda route: route.abort()) # Use network idle for dynamic content page.goto("https://spa-app.com", wait_until="networkidle") # Parallel execution import asyncio from playwright.async_api import async_playwright async def run_parallel(): async with async_playwright() as p: browser = await p.chromium.launch() tasks = [] for url in urls: tasks.append(scrape_page(browser, url)) results = await asyncio.gather(*tasks) ``` ### Debug Strategies ```python # Visual debugging page.pause() # Opens debugger # Console logging page.on("console", lambda msg: print(f"Console: {msg.text}")) # Network monitoring page.on("response", lambda response: print(f"Response: {response.url} - {response.status}")) # Slow motion for debugging browser = p.chromium.launch(slow_mo=1000) # 1 second delay between actions ```

Install

curl -s https://skills.skynet.ceo/api/skills/playwright/skill.md