Skip to content

Playwright Plugin

Deterministic browser automation using Python scripts for precise DOM manipulation and fast assertions.

Quick Start

- name: "Navigate and verify"
  plugin: playwright
  config:
    role: script
    script: |
      from playwright.sync_api import expect

      page.goto("https://example.com")
      expect(page).to_have_url("https://example.com/")
      expect(page.locator("h1")).to_have_text("Example Domain")

      result = {"title": page.title()}

Configuration

Field Description Example
role Must be script script
script Python Playwright code See examples below
env Environment variables for script {"KEY": "value"}

Note: Browser session management and session_id are handled automatically - just specify role: script and your script.

Common Patterns

# Navigate
page.goto("https://example.com")
page.wait_for_load_state("networkidle")

# Click & fill
page.click("button#submit")
page.fill("input[name='email']", "test@example.com")
page.select_option("select#country", "US")

# Wait for elements
page.wait_for_selector("#content")

Assertions

from playwright.sync_api import expect

# Page assertions
expect(page).to_have_url("https://example.com/")
expect(page).to_have_title("Example Domain")

# Element assertions
expect(page.locator("h1")).to_have_text("Welcome")
expect(page.locator("#login")).to_be_visible()
expect(page.locator(".item")).to_have_count(5)

Saving Data

# Save to Rocketship state
result = {
  "title": page.title(),
  "url": page.url,
  "user_id": page.locator("#user-id").inner_text()
}
save:
  - json_path: ".user_id"
    as: "user_id"

Complete Example

- name: "Login flow"
  plugin: playwright
  config:
    env:
      TEST_EMAIL: "{{ .env.TEST_EMAIL }}"
      TEST_PASSWORD: "{{ .env.TEST_PASSWORD }}"
    script: |
      import os
      from playwright.sync_api import expect

      page.goto("https://app.example.com/login")
      page.fill("input[name='email']", os.environ["TEST_EMAIL"])
      page.fill("input[name='password']", os.environ["TEST_PASSWORD"])
      page.click("button[type='submit']")

      expect(page).to_have_url("https://app.example.com/dashboard")

Combining with Other Plugins

# Get auth token from API
- name: "Get token"
  plugin: http
  config:
    method: POST
    url: "{{ .env.API_URL }}/auth/token"
  save:
    - json_path: ".token"
      as: "auth_token"

# Use in browser
- name: "Set token"
  plugin: playwright
  config:
    env:
      AUTH_TOKEN: "{{ auth_token }}"
    script: |
      import os
      page.goto("https://app.example.com")
      page.evaluate(f"localStorage.setItem('token', '{os.environ['AUTH_TOKEN']}')")
      page.reload()

Best Practices

  • Use specific selectors: Prefer IDs and data attributes over classes
  • Wait for elements: Use wait_for_selector for dynamic content
  • Use expect: Playwright's expect provides automatic retries
  • Pass secrets via env: Never hardcode credentials in scripts

Troubleshooting

Issue Solution
Browser won't start Run playwright install chromium
Element not found Add wait_for_selector before interacting
Timeout errors Increase timeout in wait methods
Flaky tests Use expect assertions with built-in retries

See Also