Find Element and Elements in Playwright Python
In every automation tool, finding and performing operations on the elements present on the website is essential. Roughly 70% of the automation code involves finding and performing operations on the elements.
If you take other automation tools, they perform the following steps:
- Find the element
- Perform the operation
But in the playwright, the finding does not happen until you perform some operation.
- Form the locator
- Perform Operation (Just before performing playwright finds the element)
I understand, that most probably wouldn’t believe the above statement, but that is how the playwright works. Because of this, you might see less of the stale element reference exception in the playwright.
Playwright Normal Way
These two methods are the commonly used methods to find elements in the Playwright Python. Other automation tools have two different methods to find a single element and multiple elements, but with Playwright, we can find single or multiple elements using the same function.
This also contributes headache to you, in the future if more than one is present in place of one element. When we write, we write operations thinking that only 1 is present, but if more than one is present, then the test will fail saying more than one element is present.
Unlike other tools, Playwright does not take the first element if more than one element is present.
We will be using https://demo.testercoder.com/waits.html, the practice page for this example. On this page, you can find the below section. We will be trying to find the button and click it.
Finding Single Element:
Open the Browser and Navigate to the practice page
page = browser.new_page()
page.goto("https://demo.testercoder.com/waits.html")
Form the locator, this step will not find the element, it just forms the locator.
locator = page.locator("#start-button")
print(locator)
If you run the above line, you will get output like the one below, where you can see the type of the element is Locator, also the locator value, and where the locator is present.
When we try to perform any operation on this locator, then only the playwright finds the element and performs the operation.
locator = page.locator("#start-button")
locator.click()
#or
page.locator("#start-button").click()
Now run the complete code
from playwright.sync_api import sync_playwright
playwright = sync_playwright().start()
browser = playwright.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://demo.testercoder.com/waits.html")
locator = page.locator("#start-button")
locator.click()
print("Execution Over")
Instead of clicking the button, Let’s click the first checkbox.
from playwright.sync_api import sync_playwright
playwright = sync_playwright().start()
browser = playwright.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://demo.testercoder.com/waits.html")
page.locator("#checkbox-container [type='checkbox']").click()
If you run the above code, you will error because there is more than one matching element.
playwright._impl._api_types.Error: Error: strict mode violation: locator("#checkbox-container [type='checkbox']") resolved to 2 elements:
1) <input type="checkbox" id="checkbox-1"/> aka locator("#checkbox-1")
2) <input type="checkbox" id="checkbox-2"/> aka locator("#checkbox-2")
=========================== logs ===========================
waiting for locator("#checkbox-container [type='checkbox']")
The Playwright cannot work if more than one element is matching, it will create an ambiguous situation where it doesn’t not which one to click in such cases, we have to specify exactly which element we want.
In such cases, you have to change the locator that matches only one element or change the code to click the nth element. When more than one element is present, the index starts from 0. So you can use a function called nth()
from playwright.sync_api import sync_playwright
playwright = sync_playwright().start()
browser = playwright.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://demo.testercoder.com/waits.html")
page.locator("#checkbox-container #checkbox-1").click()
# or
page.locator("#checkbox-container [type='checkbox']").nth(0).click()
Find Multiple Elements in Playwright Python
We do not have to do anything to find multiple elements, just use the same method that found the single element. If the page has more than one element then the playwright automatically finds all the elements.
From your part, you have to make sure the locator value (xpath or CSS) matches all the expected elements.
from playwright.sync_api import sync_playwright
playwright = sync_playwright().start()
browser = playwright.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://demo.testercoder.com/waits.html")
locator = page.locator("#checkbox-container [type='checkbox']")
matching_checkboxes = locator.count()
print(matching_checkboxes)
Using Element handle
We can find the elements using element handles. This has more raw functions than refined playwright functions.
from playwright.sync_api import sync_playwright
playwright = sync_playwright().start()
browser = playwright.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://demo.testercoder.com/waits.html")
element_handle = page.locator("#checkbox-container #checkbox-1").element_handle().click()
element_handles = page.locator("#checkbox-container [type='checkbox']").element_handles()
Find an element using query selector and query selector all
We can find the element using query_selector()
function, and to find multiple elements we can use query_selector_all()
.
These are javascript native methods but the playwright adapted them into playwright methods.
from playwright.sync_api import sync_playwright
playwright = sync_playwright().start()
browser = playwright.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://demo.testercoder.com/waits.html")
single_element = page.query_selector("#start-button").text_content()
print(single_element)
multiple_element = page.query_selector_all("#checkbox-container [type='checkbox']")
for ele in multiple_element:
ele.click()
Finding elements in Javascript way:
We can use JavaScript to find single or multiple elements. These methods must be used using page.evaluate()
, we can perform operations with JavaScript itself. Returning the element from the javascript is quite difficult. So we have to perform the operation using the javascript itself.
But if you want to retrieve a value like get text from the element, type, or any other attribute then it automatically returns the value.
- getElementById(): find a single element using the id attribute
- getElementsByClassName(): find multiple elements using the class name.
- getElementsByName(): find multiple elements by name
- getElementsByTagName(): find multiple elements using the tag name
- querySelector(): find a single element using the CSS selector
- querySelectorAll(): find multiple elements using CSS selector
page.goto("https://demo.testercoder.com/waits.html")
element_id = page.evaluate("document.getElementById('checkbox-1').id") # retuns the output
print(element_id)
selector_all = """
all_ele = document.querySelectorAll("#checkbox-container [type='checkbox']")
for(const ele of all_ele){
ele.click()
}
"""
element = page.evaluate(selector_all)
The output is
Eval on the Selector/Element:
eval_on_selector()
and eval_on_selector_all()
will find the element based on the selector and perform the operation. but it is hard to get the element out and perform operations using Python.
element_type = page.eval_on_selector("#checkbox-container #checkbox-1", "element => element.type")
Other ways to find elements in Playwright:
<input type="text" title="username" placeholder="enter username" role="username">
<img src="sample.png" alt="image of cats"></img>
- page.get_attribute(): find the element using the attribute
- page.get_by_role(): find the element using role attribute
- page.get_by_text(): find the element using the text present in the element this will be useful for label, span, p, and header, tags
- page.get_by_label(): get element by label attribute
- page.get_by_title(): get element using title attribute
- page.get_by_alt_text(): get element using alt text, this helps find images. (mostly alt attribute is associated with images)
- page.get_by_placeholder(): get element based on the place holder attribute, useful for input area and input bar.
- page.get_by_test_id(): get element using test_id attribute.
Posts You Might Like
- Why playwright is better than selenium webdriver, is it?
- Handle dropdowns in Playwright Python
- Open the browser and Close in Playwright Python
- Handle checkbox in Playwright Python
- Element Operations in Playwright Python
- Handle IFrames in Playwright Python
- Page level commands in Playwright Python
- Element State with Playwright Python