Puppeteer Getting List of Elements with Same Selector

Huckleberry Carignan picture Huckleberry Carignan · Sep 7, 2018 · Viewed 35.7k times · Source

Background:

Using NodeJS/CucumberJS/Puppeteer to build end-to-end regression test for an emberJS solution.

Problem:

Selecting (page.click) and getting textContent of one of the elements when there are several dynamic elements with the same selector? (In my case, I have 4 elements with the same selector = [data-test-foo4="true"])

I know, that with:

const text = await page.evaluate( () => document.querySelector('[data-test-foo4="true"]').textContent );

I can get the text of the first element, but how do I select the other elements with the same selector? I've tried:

var text = await page.evaluate( () => document.querySelectorAll('[data-test-foo4="true"]').textContent )[1];
console.log('text = ' + text);

but it gives me 'text = undefined'

Also, the following:

await page.click('[data-test-foo4="true"]');

selects the first elements with that selector, but how can I select the next one with that selector?

Answer

Grant Miller picture Grant Miller · Sep 7, 2018

You can use Array.from() to create an array containing all of the textContent values of each element matching your selector:

const text = await page.evaluate(() => Array.from(document.querySelectorAll('[data-test-foo4="true"]'), element => element.textContent));

console.log(text[0]);
console.log(text[1]);
console.log(text[2]);

If you need to click more than one element containing a given selector, you can create an ElementHandle array using page.$$() and click each one using elementHandle.click():

const example = await page.$$('[data-test-foo4="true"]');

await example[0].click();
await example[1].click();
await example[2].click();