Choose CSS selectors that are both specific and stable to avoid selecting the wrong elements. Target IDs, data attributes, or uniquely structured paths whenever possible.
Prefer text selectors for buttons and links to make tests more readable and maintainable, as they mimic user interactions.
Utilize XPath for navigating complex DOM structures or when needing to perform more advanced element searches.
Combine CSS, text, or role-based selectors to fine-tune element targeting – especially helpful on dynamic pages where content or structure can shift frequently.
from playwright.sync_api import sync_playwright # Start Playwright with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page() # Navigate to the target page page.goto('https://sandbox.oxylabs.io/products') # Using CSS selectors product_name = page.locator('css=.product-name').text_content() print('Product Name:', product_name) # Using text selectors add_to_cart_button = page.locator('text=Add to Cart').click() # Using XPath selectors price = page.locator('xpath=//div[@class="price"]').text_content() print('Price:', price) # Combining selectors description = page.locator('.description >> text=More Info').text_content() print('Description:', description) # Close browser browser.close()
Ensure that Playwright locators are updated if the structure of the web page changes, as stale selectors can cause tests to fail.
Always verify that a locator matches only one element unless your test logic expects multiple. Selecting multiple unintended elements can cause test failures or flaky behavior.
Use Playwright's auto-wait feature by default to handle elements that might take time to appear or become interactable, avoiding flaky tests.
The Playwright Inspector is an invaluable tool for troubleshooting. Use it to explore the page structure, validate selectors, and try out locators interactively in the browser.
# Incorrect: Using a non-unique selector that might match multiple elements button = page.locator('button').click() # Correct: Using a unique selector to ensure the correct element is targeted button = page.locator('button#submit').click() # Incorrect: Assuming element is immediately available without waiting product_details = page.locator('div.product-details').text_content() # Correct: Using auto-wait to ensure element is loaded and interactable product_details = page.locator('div.product-details').wait_for(state='visible').text_content() # Incorrect: Using a hardcoded XPath that is brittle and likely to break with UI changes login_button = page.locator('xpath=/html/body/div[2]/div[1]/button').click() # Correct: Using a more robust and readable CSS selector or relative XPath login_button = page.locator('css=button.login').click() # Incorrect: Not checking if the locator matches any element, leading to potential errors price = page.locator('div.price').text_content() # Correct: First check if the locator finds any element before proceeding if page.locator('div.price').count() > 0: price = page.locator('div.price').text_content() else: print("Price element not found")
Web scraper API
Public data delivery from a majority of websites
From
49
Get the latest news from data gathering world
Scale up your business with Oxylabs®
Proxies
Advanced proxy solutions
Data Collection
Datasets
Resources
Innovation hub