Roland Jegorov
Roland Jegorov

Reputation: 819

How to click on elements returned from page.evaluate?

How can I click on elements returned from page.evaluate?

const allCategoryElements = await page.evaluate(() => {
  const allElements = [...document.querySelectorAll(".mySelector")];

  return allElements.filter((element) => {
    const ul = element.querySelector("ul");
    return !ul || !ul.children.length;
  });
});

for (const categoryHandle of allCategoryElements) {
  await categoryHandle.click(); // ERROR: categoryHandle has no click method
}

Basically, what I want is an array of elements that I can then click on (OUTSIDE OF THE EVALUATE). Elements need to be of type ElementHandle, if I'm correct.

Upvotes: 0

Views: 2546

Answers (2)

xdeepakv
xdeepakv

Reputation: 8125

To work with all element, You need to use page.evaluate function and evaluateHandle together

// Get the "viewport" of the page, as reported by the page.
const jsHandle = await page.evaluateHandle(() => {
const allElements = [...document.querySelectorAll(".mySelector")];
  return allElements.filter((element) => {
    const ul = element.querySelector("ul");
    return !ul || !ul.children.length;
  });
 });
 await page.evaluate(all => {
  for (const elm of all) {
       elm.click();
     }
  } , jsHandle);

Upvotes: 0

mbit
mbit

Reputation: 3013

elements can't be returned using page.evaluate as they're not serializable. Use page.evaluateHandle instead.

From the docs

The only difference between page.evaluate and page.evaluateHandle is that page.evaluateHandle returns in-page object (JSHandle)

example:

Here the element is not returned.

const element = await page.evaluate(() => document.querySelector('a'));

while here the element will be an instance of JSHandle:

const element = await page.evaluateHandle(() => document.querySelector('a'));

You can use jsHandle.asElement() to get the ElementHandle.

Upvotes: 2

Related Questions