Playwright E2E¶
How to add browser-based E2E tests with Playwright.
Prerequisites¶
Auth fixtures¶
Playwright fixtures are app-specific because auth storage varies (localStorage, cookies, etc.). Add these to your e2e/conftest.py after the bluefox_e2e_setup() call:
e2e/conftest.py
import pytest
from pathlib import Path
from bluefox_test.e2e import bluefox_e2e_setup
globals().update(bluefox_e2e_setup(
login_endpoint="/auth/login",
login_payload={"email": "e2e@test.com", "password": "testpassword123"},
))
PLAYWRIGHT_STATE = Path("e2e/.auth/playwright_state.json")
@pytest.fixture(scope="session")
def browser_auth_state(server, auth_token):
"""Save auth state so Playwright tests start logged in."""
from playwright.sync_api import sync_playwright
PLAYWRIGHT_STATE.parent.mkdir(exist_ok=True)
with sync_playwright() as p:
browser = p.chromium.launch()
context = browser.new_context()
page = context.new_page()
page.goto(f"{server}/login")
# Adjust to match your app's auth storage:
page.evaluate(f"""() => {{
localStorage.setItem('access_token', '{auth_token}');
}}""")
context.storage_state(path=str(PLAYWRIGHT_STATE))
browser.close()
return str(PLAYWRIGHT_STATE)
@pytest.fixture
def page(server, browser_auth_state):
"""Authenticated Playwright page."""
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
context = browser.new_context(storage_state=browser_auth_state)
pg = context.new_page()
pg.goto(server)
yield pg
browser.close()
Writing browser tests¶
e2e/test_dashboard.py
import pytest
pytestmark = pytest.mark.e2e
def test_dashboard__shows_username(page):
page.goto("/dashboard")
assert page.locator("[data-testid='username']").text_content() == "E2E User"
def test_create_todo__via_ui(page):
page.goto("/todos")
page.fill("[data-testid='todo-title']", "Buy groceries")
page.click("[data-testid='submit-todo']")
assert page.locator("[data-testid='todo-item']").first.text_content() == "Buy groceries"
CI setup¶
Add Playwright to your CI workflow:
.github/workflows/test.yml
- run: |
uv sync --group test
uv run playwright install chromium
- run: make e2e
Tip
Add e2e/.auth/ to your .gitignore to avoid committing cached auth state.