Codiga has joined Datadog!

Read the Blog·

Interested in our Static Analysis?

Sign up
← All posts
Oscar Salazar Tuesday, January 17, 2023

Playwright best practices avoid ElementHandle use Locator instead

Share

AUTHOR

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.

See all articles

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.

The 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");

The 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 xpath or 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();

Why is page.locator prefered over ElementHandle

One of the main advantages of using page.locator over 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 xpath or 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 xpath and 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.

Avoid ElementHandle selectors

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

More resources

Are you interested in Datadog Static Analysis?

Sign up