Playwright Python

pip install tracera-playwright

Requires Python ≥ 3.11 and pytest ≥ 8 (see Autotest adapters). tracera-playwright on PyPI.

Do not load tracera-pytest and tracera-playwright in the same pytest run.

The page fixture is from pytest-playwright. Enable screenshot, video, and trace in your Playwright config — artifacts are added to the Tracera result.

Environment variables, run mode, and retries: Autotest adapters.

Retry Env key: PLAYWRIGHT_RETRY.

Bind testCaseId and autotestName

Import stock pytest and Playwright APIs as usual, and tracera and id from tracera_playwright.

At declaration (preferred — bind runs even if the body skips early):

from tracera_playwright import id as tracera_id

@tracera_id(42, "e2e/login")
def test_login(page):
    page.goto("https://example.com/login")

Inside the test (optional if @tracera.id already binds the case):

from tracera_playwright import tracera

def test_login(page):
    tracera.test_case(42, "e2e/login")
    page.goto("https://example.com/login")

Skip

Use stock pytest skip (pytest.skip, @pytest.mark.skip, …). The skip reason is added to the result as comment.

import os
import pytest
from tracera_playwright import id as tracera_id

@tracera_id(42, "e2e/login")
def test_login(page):
    if not os.environ.get("READY"):
        pytest.skip("env not ready")
    page.goto("https://example.com/login")

Steps

Use tracera.step(title, body), @tracera.step("…"), with tracera.step("…"):, or async with tracera.step("…"): (also @tracera.step / await tracera.step(…) on async def). In the @tracera.step("add {item}") decorator, {item} is substituted from the function’s item argument. Steps inside function-scoped fixtures go to the result’s Setup / Teardown; steps inside the test go to the result’s Test section. Suite-level hooks are not reported.

import pytest
from tracera_playwright import tracera

@pytest.fixture(autouse=True)
def open_shop(page):
    with tracera.step("open shop"):
        page.goto("https://example.com/shop")
    yield
    with tracera.step("cleanup"):
        page.goto("https://example.com/cart/clear")

def test_checkout(page):
    tracera.test_case(10, "e2e/checkout")

    @tracera.step("add {item}")
    def add_to_cart(item: str):
        page.get_by_role("button", name="Add").click()

    add_to_cart("sku-1")  # → step "add sku-1"

Comments, errors, and attachments

Comments, errors, and attachments: Autotest adapters. Playwright attaches its screenshots, video, and Playwright trace on its own — in Tracera, images open in a lightbox, video plays inline, and the trace opens in the Trace Viewer.

from tracera_playwright import tracera

def test_login(page):
    tracera.test_case(42, "e2e/login")
    tracera.comment("result-level note")
    tracera.error("result-level error text")

    with tracera.step("open login"):
        page.goto("https://example.com/login")
        tracera.comment("landed on login")
        tracera.attachment(
            file_name="suite-log.txt",
            mime_type="text/plain",
            data=b"finished login flow",
        )

Parameterized tests

The second argument in the @tracera.id decorator is the autotest name. You can put {arg_name} / {param_id} placeholders in it; each {arg_name} must match a test function argument, and every @pytest.mark.parametrize row fills them from that row ({param_id} is the parameter id when pytest provides one). In the example below you get two results for case 42, with autotest names login as ok and login as sso:

import pytest
from tracera_playwright import id as tracera_id

@tracera_id(42, "login as {login}")
@pytest.mark.parametrize("login", ["ok", "sso"])
def test_login(page, login):
    page.goto("https://example.com/login")

Or bind inside the test when the case id also varies:

import pytest
from tracera_playwright import tracera

@pytest.mark.parametrize(
    "case_id,name,path",
    [
        (42, "e2e/login-ok", "/login"),
        (43, "e2e/login-sso", "/login/sso"),
    ],
)
def test_login_row(page, case_id, name, path):
    tracera.test_case(case_id, name)

    with tracera.step("open"):
        page.goto(f"https://example.com{path}")