'Puppeteer - How to use page.click() inside page.evaluate()

I am scraping a table and each row has a button to show a modal with information. I need to scraping the information from the modal for each row but I dont know how to open the modal. I have tried with page.click(selector) inside page.evaluate() but It didnt work.

I have tested the next code.

const users = await page.evaluate(() => {
  const usersTable = Array.from(document.querySelectorAll('table#grilla > tbody > tr'))
  const userInfo = usersTable.map(async userTable => {
    await page.click('td > a#modificar-2')
    await page.click('div > button[type=submit].close')
    const username = userTable.children[2].innerText
    const firstName = userTable.children[4].innerText
    const lastName = userTable.children[5].innerText
    const email = userTable.children[6].innerText
    const estado = userTable.children[7].innerText
    const fullName = firstName + lastName
    return { username, fullName, email, estado }
  })
  return userInfo
})

I dont know how to pass page.click() or another option inside page.evaluate()



Solution 1:[1]

If you use page.evaluate() you're switching the context from node puppeteer to browser, so you have to use JS native functions like click: document.querySelector(selector).click().

If you have errors like Error: Evaluation failed: TypeError: Cannot read property 'click' of null probably the element you wanted to click isn't on the page (or it's hidden or something).

Solution 2:[2]

From inside that loop you would do:

userTable.querySelector('td > a#modificar-2').click()

(no await)

Solution 3:[3]

You can return css selectors of elements you want to click from page.evaluate and then perform page.click on them. For getting css selector for the element you can use the code from an answer to this question:

const elemToClick = page.evaluate(() => {
  let elem;

  //...

  return cssPath(elem);

  function cssPath(el) {
    if (!(el instanceof Element)) return;
    var path = [];
    while (el.nodeType === Node.ELEMENT_NODE) {
      var selector = el.nodeName.toLowerCase();
      if (el.id) {
        selector += '#' + el.id;
        path.unshift(selector);
        break;
      } else {
        var sib = el,
          nth = 1;
        while ((sib = sib.previousElementSibling)) {
          if (sib.nodeName.toLowerCase() == selector) nth++;
        }
        if (nth != 1) selector += ':nth-of-type(' + nth + ')';
      }
      path.unshift(selector);
      el = el.parentNode;
    }
    return path.join(' > ');
  }
});

page.click(elemToClick);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Kodziak
Solution 2 pguardiario
Solution 3 ?????? ??????