0

Using playwright C# I've been trying to work with multiple elements that use the same locator.

Is there any functionality in playwright which is equivalent to the FindElements method from selenium? This method allows us to store multiple elements of the same locator in a collection which can then be used to access individual elements. I actually need to perform actions of each of the elements so having them in a collection where I can access them by index works well for me.

It seems that due to playwrights locator strictness that there is nothing suitable to achieve the same result as Selenium Findelements. I temporarily tried using ElementHandles but this is not recommended and still proves problematic when trying to access elements.

Playwright have First, Last and Nth() locator options which allow us to pick a specific element but I prefer having access to all of the elements in list, accessible by index which I find to be more useful when working with multiple elect's in the same or similar areas.

I ended up writing my own code to store the elements in a list but I wondered what others are using as a substitute for FindElements?

IList<ILocator> elements = new List<ILocator>();

int listSize = await Page.Locator("div #internalSearch span.e-list-text").CountAsync();
for (int j = 0; j < listSize; j++)
{ ILocator locator = Page.Locator("div #internalSearch span.e-list-text").Nth(j);
elements.Add(locator);
}

Assert.True(elements.Count == listSize);
bobe_b
  • 187
  • 1
  • 2
  • 21

2 Answers2

1

Using a selector that finds a list of locators in Playwright is exactly the same as calling .FindElements() in selenium, except that Playwright does not have a specifically named method like .FindLocators().

Playwright - a selector that matches multiple elements returns a list of locators, which you then iterate over:

var rows = page.GetByRole(AriaRole.Listitem);
var count = await rows.CountAsync();
for (int i = 0; i < count; ++i)
  Console.WriteLine(await rows.Nth(i).TextContentAsync());

Selenium - FindElements returns a list of elements that you have to iterate over.

IList < IWebElement > elements = driver.FindElements(By.TagName("p"));
foreach(IWebElement e in elements) {
  System.Console.WriteLine(e.Text);
}
AJG
  • 476
  • 2
  • 5
0

You can also use locator.evaluateAll:

This method finds all elements matching the specified locator and passes an array of matched elements as a first argument to the passed pageFunction(callback). Returns the result of pageFunction invocation.

If pageFunction returns a Promise, then locator.evaluateAll(pageFunction[, arg]) would wait for the promise to resolve and return its value.

Code Example(in JavaScript):

const elements = page.locator('div');
const divCounts = await elements.evaluateAll((divs, min) => divs.length >= min, 10);
Vishal Aggarwal
  • 1,929
  • 1
  • 13
  • 23