Oscar Salazar, Senior Software Engineer
Oscar is a Software Engineer passionate about frontend development and creative coding, he has worked in several projects involving from video games to rich interactive experiences in different web applications. He loves studying and playing with the newest CSS features to create fantastic art.
How to select elements in a Playwright test
When automating web browsers with the Playwright library, it's important to understand the difference between the
page.locator method and the
page.$ method for locating elements on a web page.
page.$ method is a shorthand for
page.mainFrame().$ and is used to query the DOM of the current frame for an element matching a given CSS selector. This method is useful for simple queries, such as finding an element with a specific class or ID. However, it has some limitations. For example, it can only search within the current frame and it cannot perform more advanced queries, such as searching for elements with a specific attribute or text content.
Here is an example of element handles in action:
// Element Handle const buttonHandle = await page.$("button"); await buttonHandle.click(); // Element Handles const linkHandles = await page.$$("a");
page.locator method, on the other hand, allows you to perform more advanced queries, such as searching for elements within a specific context or using different query strategies like
textContent. This method returns a handle to the element that can be used to perform actions such as clicking, filling, etc. Additionally,
page.locator is more readable and less prone to errors.
Here is an example of the previous element handles implemented with locators:
const buttonLocator = page.locator("button"); await buttonLocator.click();
page.locator prefered over ElementHandle
One of the main advantages of using
page.$ is that it provides a more powerful and flexible way to locate elements on a web page. The
page.locator method can search for elements within a specific context, such as a specific frame or shadow DOM, and it can use different query strategies, such as
textContent. This makes it easier to write tests that are more robust and less prone to breaking when the structure of the web page changes.
Let's see how to use
textContent to locate elements
const element = await page.locator.xpath( '//div[@class="some-class"]/span[text()="Hello World"]' ); const element = await page.locator.textContent("Hello World");
Another advantage of using
page.locator is that it makes the code more readable and maintainable. By using
page.locator, you can write more descriptive and meaningful queries, which makes it easier to understand the intent of the code. This is especially important when working on a large test suite with multiple contributors.
It's important to note that
page.locator method is not just limited to DOM-related queries, it can be used to interact with the browser context as well. You can create new context, select existing context, etc.
In conclusion, while
page.$ is useful for simple queries it is marked as deprecated and its usage is discouraged, so it could be removed in future releases, it's recommended to use the
page.locator method for more advanced queries and to make your code more powerful, flexible and maintainable.
Automatically remove ElementHandle selectors
Codiga provides IDE plugins and integrations with GitHub, GitLab, or Bitbucket to detect ElementHandle selectors. The Codiga static code analysis detects this issue directly in your IDE or code reviews.
In particular, this analysis rule produces a warning each time there is an ElementHandle selector in a Playwright test.
To use this rule consistently, all you need to do is to install the integration in your IDE (for VS Code or JetBrains) or code management system and add a codiga.yml file at the root of your profile with the following content:
rulesets: - playwright
You can also navigate to your project directory in your terminal and run the following command to get started.
npx @codiga/cli ruleset-add playwright