Reputation: 819
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
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
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