How to handle strict mode in Playwright (Typescript/Javascript)

Overview

Strict mode in Playwright means locators are strict. Any locator which resolves to more than one element will become invalid and it makes Playwright throw this ugly exception:

=> This Exception means we have violated strict mode as our locator resolved to 10 elements instead of 1. Strict mode is useful in almost situations but in some other cases, know how to handle it flexibly is also helpful too.

Locator resolves to one element

  • Method 1: Using CSS or Xpath syntax

When catching element in DOM HTML, we mainly use CSS or Xpath selector. In CSS you can use:

+ first-child

+ last-child

+ nth-child

…and some other CSS selector adapted to your requirement to make your locator only resolve to one element.

Example:

(//ul[@class='sac-results']//li[@class='sac-results__item'])[1]
(//ul[@class='sac-results']//li[@class='sac-results__item'])[2]

In Xpath, you can group all elements in one array and access its element like this. Note that index of this array starts from one instead of zero.

(//ul[@class='sac-results']//li[@class='sac-results__item'])[1]
(//ul[@class='sac-results']//li[@class='sac-results__item'])[2]
  • Method 2: Using Locator API

Do not want to make your locator resolved to only one element by CSS or Xpath selector, just use Playwright Locator API.

Playwright supports quite of built-in methods for this like first(), last(), nth()

await page.locator('ul.sac-results li.sac-results__item').first()

=> return locator of the first matching element

await page.locator('ul.sac-results li.sac-results__item').last()

=> return locator of the last matching element

await page.locator('ul.sac-results li.sac-results__item').nth(1)

=> return locator to the n-th matching element. Just passing index of element to nth() method. Index equal to zero will resolve to the first element, relevant to first() method

Another way to write above statement is passing “nth=index” to locator() method like below. It just has the same effect though.

await page.locator('ul.sac-results li.sac-results__item').locator('nth=0')

You can also use $() method to resolve to one element although Playwright recommend using locator() method instead.

const element = await page.$('ul.sac-results li.sac-results__item');
console.log(await element?.innerText())

Locator resolves to multiple elements

But in some cases, you still want to keep your locator resolved to multiple elements on purpose. Consider a real-life example, in this domain I want to verify a suggestion drop down list which contains 10 elements is displayed after entering keyword to header search textbox.

1. Get all elements:

You can use all() method to get an array of locators which point to respective elements and use for loop to iterate through all elements.

const elements = await page.locator('ul.sac-results li.sac-results__item').all();
for(const element of elements) {
   console.log(await element.innerText());
}

Another way is using $$() method which has the same functionality as all() method although Playwright recommends using locator() method instead.

const elements = await page.$$('ul.sac-results li.sac-results__item');
for(const element of elements) {
   console.log(await element.innerText());
}

2. Disable strict mode by waitForSelector():

waitForSelector() is used to wait for a locator satisfies state of an element. Although our locator resolved to multiple element, using “strict: false” will bypass the restrictions.

const element = await page.waitForSelector('ul.sac-results li.sac-results__item', {state: 'visible', strict: false});
console.log(await element.innerText())

Strict mode in Selenium

Selenium is more “sloppy” than Playwright. Selenium (Java) has two methods called findElement() and findElements(). Both of those does not concern about strictness of locator. If our locator resolves to more than one element, findElement() only returns the first matching element while findElements() returns a List collection of matching elements.

Selenium (Java)Playwright (Typescript)
Strict modeNone of restrictionsLocators should be resolve to only one element. Otherwise exception will be throwed
MethodsfindElement(): resolve to only the first matching element. Throw exception if no element found
findElements(): resolve to a List of elements. Return an empty List if no element found
Locator(): resolve to only one element. Exception will be throwed if violating strict mode
$(): resolve to the first matching element. Exception will not be throwed if violating strict mode (not recommend to use)
$$(): resolve to an array of matching elements. Exception will not be throwed if violating strict mode (not recommend to use)
Selenium Vs Playwright in strict mode (tomatoqa.com)

Conclusion

Strict mode is a restriction of Playwright which makes us aware of using more exact locator. Our locator should resolve to only one element. Otherwise Exception will be throwed. Know how to handle in many situations will make this automation tool more flexible. Thanks for reading!

Ask me anything