8. Handling Form Submissions and Dynamic Waits
While Playwright’s auto-waiting handles most clicks and actions, complex scenarios often require explicit waiting. A classic example is submitting a form that triggers an AJAX call to load new content.
8.1. Waiting for New Elements
The most common and robust way to confirm a form submission was successful is to wait for an element that only appears on the success page or after the new data loads.
We use page.wait_for_selector() or, more commonly, simply using a locator action on the element you expect.
Python
# Assuming you are on a login page
# 1. Locate the input fields and the submit button
username_field = page.get_by_label("Username")
password_field = page.get_by_label("Password")
submit_button = page.get_by_role("button", name="Log In")
# 2. Fill the form
await username_field.fill("test_user")
await password_field.fill("secure_pass")
# 3. Click the submit button
await submit_button.click()
# 4. Explicit Wait: Wait for a post-login element to appear
# For example, a welcome message or a dashboard link
# If this locator is successful, we know the submission worked.
dashboard_header = page.get_by_text("Welcome to your Dashboard")
try:
# Use the locator method to wait for the element (default timeout is 30s)
await dashboard_header.wait_for()
print("Login successful! Dashboard loaded.")
except TimeoutError:
print("Login failed or dashboard element did not appear.")
9. Monitoring Network Requests (page.expect_response())
Sometimes, the success of an action is defined by a specific API call succeeding. Playwright allows you to listen for and inspect network requests and responses, which is incredibly useful for testing back-end interactions.
We use page.expect_response() to wrap the action that triggers the network request.
Python
import re # We'll use regex for more flexible URL matching
async def wait_for_api_data(page):
# 1. Define the expected API response pattern
# Use re.compile for a flexible regex match on the API URL
api_url_pattern = re.compile(r".*/api/v1/user/data.*")
# 2. Use a context manager to listen for the response
async with page.expect_response(api_url_pattern) as response_info:
# 3. Perform the action that triggers the API call (e.g., clicking 'Refresh')
await page.get_by_role("button", name="Refresh Data").click()
# 4. Wait for the response object to be resolved
response = await response_info.value
# 5. Assert or check the status code
if response.status == 200:
print(f"API call successful! Status: {response.status}")
# 6. Get the JSON payload (if applicable)
data = await response.json()
print(f"Received data keys: {data.keys()}")
else:
print(f"API call failed! Status: {response.status}")
# You can also wait for a request to be initiated with page.expect_request()
10. Taking Full Page Screenshots
In Part 1, we took a basic screenshot. Playwright also makes it trivial to capture the entire scrolling page, which is essential for comprehensive visual testing.
When calling page.screenshot(), simply set the full_page option to True.
Python
async def take_full_page_screenshot(page):
await page.goto("https://playwright.dev/python")
print("Taking a full-page screenshot...")
# 1. The key option: full_page=True
await page.screenshot(
path="full_page_documentation.png",
full_page=True,
# Optional: Hide the scrollbar in the screenshot
mask=[page.locator("nav.navbar")] # Example: hide the navigation bar
)
print("Full page screenshot saved as full_page_documentation.png")
# ... (You would integrate this into your main run function)
Final Thoughts and Next Steps
Congratulations! You now have a solid foundation in Playwright with Python. You’ve covered:
- Setup and Basic Navigation
- Best Practices for Locators
- Accelerating Development with Codegen
- Handling Advanced Waits (Form Submission & Network Monitoring)
- Capturing Full Page Visuals
From here, you can explore integrating Playwright into a testing framework like Pytest for a structured testing suite, or use it for complex web scraping projects.
Thank you for following this Playwright Python Tutorial!