A high-level API to automate web browsers across Chromium, Firefox and WebKit with both synchronous and asynchronous execution models.
—
Comprehensive assertion framework with built-in waiting and retry logic for reliable test automation. Supports page, element, and API response assertions.
Main entry point for assertions with configurable timeouts and retry logic.
def expect(
actual: Union[Page, Locator, APIResponse],
message: Optional[str] = None
) -> Union[PageAssertions, LocatorAssertions, APIResponseAssertions]:
"""
Create assertion object for target.
Args:
actual: Object to assert against (Page, Locator, or APIResponse)
message: Custom assertion message
Returns:
Union[PageAssertions, LocatorAssertions, APIResponseAssertions]: Assertion object
"""
class Expect:
def set_options(self, timeout: Optional[float] = None) -> None:
"""
Set global assertion options.
Args:
timeout: Default timeout for assertions in milliseconds
"""Assertions for page-level properties like title and URL.
class PageAssertions:
def to_have_title(
self,
title: Union[str, Pattern],
timeout: Optional[float] = None
) -> None:
"""
Assert page title matches expected value.
Args:
title: Expected title text or pattern
timeout: Assertion timeout in milliseconds
"""
def to_have_url(
self,
url: Union[str, Pattern],
timeout: Optional[float] = None
) -> None:
"""
Assert page URL matches expected value.
Args:
url: Expected URL text or pattern
timeout: Assertion timeout in milliseconds
"""
def not_to_have_title(
self,
title: Union[str, Pattern],
timeout: Optional[float] = None
) -> None:
"""Assert page title does not match value."""
def not_to_have_url(
self,
url: Union[str, Pattern],
timeout: Optional[float] = None
) -> None:
"""Assert page URL does not match value."""Comprehensive element-level assertions with automatic waiting.
class LocatorAssertions:
def to_be_attached(self, timeout: Optional[float] = None) -> None:
"""Assert element is attached to DOM."""
def to_be_checked(self, timeout: Optional[float] = None) -> None:
"""Assert checkbox/radio is checked."""
def to_be_disabled(self, timeout: Optional[float] = None) -> None:
"""Assert element is disabled."""
def to_be_editable(self, timeout: Optional[float] = None) -> None:
"""Assert element is editable."""
def to_be_empty(self, timeout: Optional[float] = None) -> None:
"""Assert element is empty."""
def to_be_enabled(self, timeout: Optional[float] = None) -> None:
"""Assert element is enabled."""
def to_be_focused(self, timeout: Optional[float] = None) -> None:
"""Assert element is focused."""
def to_be_hidden(self, timeout: Optional[float] = None) -> None:
"""Assert element is hidden."""
def to_be_visible(self, timeout: Optional[float] = None) -> None:
"""Assert element is visible."""
def to_contain_text(
self,
expected: Union[str, Pattern, List[Union[str, Pattern]]],
timeout: Optional[float] = None,
use_inner_text: Optional[bool] = None
) -> None:
"""
Assert element contains text.
Args:
expected: Text or patterns to find
timeout: Assertion timeout
use_inner_text: Use innerText instead of textContent
"""
def to_have_attribute(
self,
name: str,
value: Union[str, Pattern],
timeout: Optional[float] = None
) -> None:
"""
Assert element has attribute with value.
Args:
name: Attribute name
value: Expected attribute value
timeout: Assertion timeout
"""
def to_have_class(
self,
expected: Union[str, Pattern, List[Union[str, Pattern]]],
timeout: Optional[float] = None
) -> None:
"""Assert element has CSS class(es)."""
def to_have_count(
self,
count: int,
timeout: Optional[float] = None
) -> None:
"""
Assert locator matches exact number of elements.
Args:
count: Expected element count
timeout: Assertion timeout
"""
def to_have_css(
self,
name: str,
value: Union[str, Pattern],
timeout: Optional[float] = None
) -> None:
"""
Assert element has CSS property value.
Args:
name: CSS property name
value: Expected property value
timeout: Assertion timeout
"""
def to_have_id(
self,
id: Union[str, Pattern],
timeout: Optional[float] = None
) -> None:
"""Assert element has ID."""
def to_have_js_property(
self,
name: str,
value: Any,
timeout: Optional[float] = None
) -> None:
"""Assert element has JavaScript property value."""
def to_have_screenshot(
self,
name: Union[str, bytes],
timeout: Optional[float] = None,
animations: Optional[str] = None,
caret: Optional[str] = None,
clip: Optional[FloatRect] = None,
mask: Optional[List[Locator]] = None,
omit_background: Optional[bool] = None,
scale: Optional[str] = None,
style: Optional[str] = None,
threshold: Optional[float] = None,
max_diff_pixels: Optional[int] = None
) -> None:
"""Assert element screenshot matches baseline."""
def to_have_text(
self,
expected: Union[str, Pattern, List[Union[str, Pattern]]],
timeout: Optional[float] = None,
use_inner_text: Optional[bool] = None
) -> None:
"""Assert element has exact text content."""
def to_have_value(
self,
value: Union[str, Pattern],
timeout: Optional[float] = None
) -> None:
"""Assert input element has value."""
def to_have_values(
self,
values: List[Union[str, Pattern]],
timeout: Optional[float] = None
) -> None:
"""Assert select element has selected values."""Assertions for HTTP responses from API testing.
class APIResponseAssertions:
def to_be_ok(self, timeout: Optional[float] = None) -> None:
"""Assert response has successful status (200-299)."""
def not_to_be_ok(self, timeout: Optional[float] = None) -> None:
"""Assert response has unsuccessful status."""from playwright.sync_api import sync_playwright, expect
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://example.com")
# Assert page properties
expect(page).to_have_title("Example Domain")
expect(page).to_have_url("https://example.com/")
browser.close()with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://example.com/form")
# Element state assertions
submit_btn = page.get_by_role("button", name="Submit")
expect(submit_btn).to_be_visible()
expect(submit_btn).to_be_disabled()
# Fill form to enable button
email_input = page.get_by_label("Email")
email_input.fill("test@example.com")
expect(submit_btn).to_be_enabled()
expect(email_input).to_have_value("test@example.com")
browser.close()with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://example.com/products")
# Text content assertions
heading = page.get_by_role("heading", name="Products")
expect(heading).to_be_visible()
expect(heading).to_have_text("Our Products")
# Count assertions
product_cards = page.locator(".product-card")
expect(product_cards).to_have_count(12)
# Multiple element text
product_names = page.locator(".product-name")
expect(product_names).to_contain_text(["Laptop", "Phone", "Tablet"])
browser.close()Install with Tessl CLI
npx tessl i tessl/pypi-playwright