Expect API
A fluent testing and assertion framework for verifying page state with semantic queries. Perfect for end-to-end tests, validation, and quality assurance.
Overview
The Expect API provides a clean, readable syntax for making assertions about page elements using semantic queries. It's designed for:
- E2E Testing - Verify user flows and critical paths
- Validation - Check that elements exist and are visible
- Quality Assurance - Ensure UI elements meet requirements
- Continuous Integration - Automated testing in CI/CD pipelines
expect()
Creates an assertion builder for fluent testing with semantic queries.
Function Signature
from predicate import expect
expect(browserParameters
- browser (PredicateBrowser) - Browser instance
- selector (str) - Semantic query selector (e.g.,
"role=button text='Submit'")
Assertion Methods
All assertion methods support an optional timeout parameter (default: 5.0 seconds).
.to_exist(timeout=5.0)
Assert that an element matching the selector exists.
from predicate import PredicateBrowser, expect
browser = PredicateBrowser()
browser.start()
browser.page.goto("https://example.com")
# Assert button exists (waits up to 5 seconds)
expect(browser, "role=button text='Submit'").to_be_visible(timeout=5.0)
Assert that an element is visible in the viewport.
# Assert element is visible
expect(browser, "role=heading").to_be_visible()
# Assert with custom timeout
expect(browser, "role=heading").to_be_visible(timeout=3.0).to_have_text(text, timeout=5.0)
Assert that an element contains specific text.
# Assert button has exact text
expect(browser, "role=button").to_have_text("Submit")
# Assert with custom timeout
expect(browser, "role=button").to_have_text("Submit", timeout=10.0).to_have_count(n, timeout=5.0)
Assert that a query returns exactly N elements.
# Assert exactly 10 links exist
expect(browser, "role=link").to_have_count(10)
# Assert with custom timeout
expect(browser, "role=link").to_have_count(10, timeout=8.0)Basic Examples
Verifying Page Elements
from predicate import PredicateBrowser, expect
browser = PredicateBrowser()
browser.start()
browser.page.goto("https://example.com")
# Verify critical elements exist
expect(browser, "role=heading text='Welcome'")Testing Dynamic Content
from predicate import PredicateBrowser, expect, click, find, snapshot
browser = PredicateBrowser()
browser.start()
browser.page.goto("https://example.com")
# Click a button
snap =E2E Test Example
Complete end-to-end test for a login flow:
from predicate import PredicateBrowser, expect, snapshot, find, type_text, click, press
def test_login_flow():
browser = PredicateBrowser()
browser.start()
# Navigate to login pageError Handling
Assertions throw exceptions when they fail:
from predicate import PredicateBrowser, expect
browser = PredicateBrowser()
browser.start()
browser.page.goto("https://example.com")
try:
# This will timeout if button doesn't exist
expect(browser,Integration with Testing Frameworks
pytest (Python)
import pytest
from predicate import PredicateBrowser, expect
@pytest.fixture
def browser():
browser = PredicateBrowser()
browser.start()
yield browserJest (TypeScript)
# Not applicable for Python exampleBest Practices
1. Use Semantic Selectors
Prefer semantic queries over brittle CSS selectors:
# ✅ Good - semantic, resilient to HTML changes
expect(browser, "role=button text~'Submit'").to_exist()
# ❌ Bad - brittle CSS selector
# page.locator('#submit-btn-123').is_visible()2. Set Appropriate Timeouts
Adjust timeouts based on expected page behavior:
# Fast assertion for static content
expect(browser, "role=heading").to_exist(timeout=2.0)
# Longer timeout for dynamic content (AJAX, loading)
expect(browser, "role=article").to_have_count(10, timeout=15.0)3. Combine with Other APIs
Use expect() alongside other Predicate APIs:
# Take snapshot first for complex queries
snap = snapshot(browser)
button = find(snap, "role=button importance>800")
# Then assert element is still visible
expect(browser, f"role=button id={button.id}").to_be_visible()4. Test Critical Paths
Focus on user-critical flows:
def test_checkout_flow():
# 1. Product page
expect(browser, "role=button text~'Add to Cart'").to_exist()
# 2. Cart page
expect(browser, "role=button text~'Checkout'").to_be_visible()
# 3. Payment page
expect(browser, "role=button text~'Place Order'").to_exist()Use Cases
1. Regression Testing
Verify UI elements don't disappear after code changes:
def test_navigation_menu():
browser.page.goto("https://example.com")
# Verify all navigation links exist
expect(browser, "role=link text='Home'").to_exist()
expect(browser, "role=link text='Products'").to_exist()
expect(browser, "role=link text='About'").to_exist()
expect(browser, "role=link text='Contact'").to_exist()2. Accessibility Testing
Check that ARIA roles are properly assigned:
# Verify button roles
expect(browser, "role=button").to_have_count(5)
# Verify heading hierarchy
expect(browser, "role=heading").to_be_visible()3. Form Validation
Test form validation messages:
# Submit empty form
click(browser, submit_button.id)
# Verify error messages appear
expect(browser, "role=alert text~'required'").to_be_visible(timeout=3.0)4. Dynamic Content Verification
Test AJAX-loaded content:
# Click "Load More" button
click(browser, load_more_btn.id)
# Wait for new items to appear
expect(browser, "role=article").to_have_count(20, timeout=10.0)Related APIs
- Wait API - Waiting for elements with
wait_for() - Query API - Finding elements with semantic queries
- Visual Overlay - Visual debugging
Next Steps
- Examples → - More testing examples
- Tracing & Debugging → - Debug test failures
- Best Practices → - Testing best practices