I can pass native objects (strings, lists, numbers, etc) or JSHandle just fine (thanks to @hardkoded), but have no clue HOW to bass BOTH at the same time
This is my code right now, with the string (deployName) hardcoded inside the body:
async clickClientDeploymentsActionLink(deployName) {
const rowsHandle = await this.getRows();
await rowsHandle.evaluate(node => {
// need to figure HOW to pass both a string and a JSHandle
let deployName = 'Distributed Selene 8.2';
var children = []
for(x = 0; x < node.length; x++) {
if (node[x].childElementCount > 0) {
children.push(node[x]);
}
}
let childNode = null
for(y = 0; y < children.length; y++) {
if (children[y].innerText.includes(deployName)) {
childNode = children[y];
break
}
}
let actionNode = null;
for(z = 0; z < childNode.childNodes.length; z++) {
if (childNode.childNodes[z].innerText == 'Actions') {
actionNode = childNode.childNodes[z];
break;
}
}
actionNode.click()
});
}
This works perfectly, but I need to figure how to pass also the string variable, and can't seem to figure how since handles and variables are passed differently (example of how I pass variables like strings, which totally works):
async rowsChildrenCount(id='dashboardGrid') {
const children = await this.page.evaluate(({id}) => {
const grid = document.getElementById(id)
const rows = grid.getElementsByClassName('ag-row')
var children = []
for(x = 0; x < rows.length; x++) {
if (rows[x].childElementCount > 0) {
children.push(rows[x].childElementCount);
}
}
return children
}, {id});
UPDATE: hardkoded suggested a solution (what I did before, but adding '(node, itemName)' to the evaluate), but it didn't seem to work,
async clickItemActionLink(itemName) {
const rowsHandle = await this.getRows();
await rowsHandle.evaluate((node, itemName) => {
var children = []
for(x = 0; x < node.length; x++) {
if (node[x].childElementCount > 0) {
children.push(node[x]);
}
}
let childNode = null
for(y = 0; y < children.length; y++) {
if (children[y].innerText.includes(itemName)) {
childNode = children[y];
break
}
}
let actionNode = null;
for(z = 0; z < childNode.childNodes.length; z++) {
if (childNode.childNodes[z].innerText == 'Actions') {
actionNode = childNode.childNodes[z];
break;
}
}
actionNode.click()
});
}
That gets "Evaluation failed: TypeError: Cannot read property 'childNodes' of null" on account of itemName being null.
You can build a function where the first argument is always the JSHandle
but the rest of them are values you can pass to the evaluate function.
await page.goto("https://stackoverflow.com/questions/59204241/how-can-one-pass-both-a-jshandle-and-a-native-object-string-to-puppeteer-evalu");
const title = await page.$(".js-products-menu");
await title.evaluate((node, text) => node.innerText = text, "Foo");