0

Refactoring the following code causes it to fail.

Before:

let ele = await page.waitForSelector(".selector")
let attributeValue = page.evaluate((x) => x.getAttribute("attribute-name"), ele)

After:

function getAttribute(ele, attributeName) {
  return page.evaluate((x) => x.getAttribute(attributeName), ele)
}

let ele = await page.waitForSelector(".selector")
let attributeValue = await getAttribute(ele, "attribute-name")

The error:

Error [ReferenceError]: attributeName is not defined
    at evaluate (evaluate at getAttribute (file:///Users/user/projects/puppeteer-issue/index.js:17:15), <anonymous>:0:23)
    at #evaluate (file:///Users/user/projects/puppeteer-issue/node_modules/puppeteer-core/lib/esm/puppeteer/common/ExecutionContext.js:249:19)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async ExecutionContext.evaluate (file:///Users/user/projects/puppeteer-issue/node_modules/puppeteer-core/lib/esm/puppeteer/common/ExecutionContext.js:146:16)
    at async file:///Users/user/projects/puppeteer-issue/index.js:21:23

I think this is due to the lambda executing in the browser's context.

Minimum code to reproduce the error:

Repo: https://github.com/dQw4w9WgXcQ/stackoverflow-puppeteer-issue enter image description here

dQw4w9WyXcQ
  • 125
  • 1
  • 8
  • sovled the issue: https://stackoverflow.com/questions/46088351/how-can-i-pass-variable-into-an-evaluate-function – dQw4w9WyXcQ Jul 30 '23 at 15:56

1 Answers1

1

You should pass attributeName in function you're trying to evaluate as far as it doesn't see general function scope.

Try this:

function getAttribute(ele, attributeName) {
  return page.evaluate((x, attribute) => x.getAttribute(attribute), ele, attributeName)
}

let ele = await page.waitForSelector(".selector")
let attributeValue = await getAttribute(ele, "attribute-name")
Yaroslavm
  • 1,762
  • 2
  • 7
  • 15