automated-testspuppeteer

Puppeteer - Wait For Element After Selector


I have an HTML table with data like

Username is admin Actions
New User Make Admin
Old User Make Admin

After clicking "Make Admin", how do I wait for the check mark to show up?

I figured out how to look for the checkmark:

const checkmarkText = await page.$eval(`text/${new_user}`, e=>{
    return e.nextSibling.innerHTML;
});

But I'm not sure how to do a .waitForSelector(???) waiting for this checkmark.

For what it's worth, the HTML is very simple like this:

<tr>
    <td>
        New User
    </td>
    <td>
        ✓
    </td>
    <td>
        ...
    </td>
</tr>

Solution

  • You can use page.waitForFunction to wait for an arbitrary predicate like this.

    Here's the site we're testing. After 2 seconds the checkmark appears:

    <!DOCTYPE html><html><body>
    <table><tbody><tr>
      <td>
        New User
      </td>
      <td>
    
      </td>
      <td>
        ...
      </td>
    </tr></tbody></table>
    <script>
    setTimeout(() => {
      const td = [...document.querySelectorAll("td")][1];
      td.textContent = "✓";
    }, 2000);
    </script></body></html>

    Here's the full code to wait for this checkmark:

    const puppeteer = require("puppeteer"); // ^24.20.0
    
    const html = `<!DOCTYPE html><html><body>
    <table><tbody><tr>
      <td>
        New User
      </td>
      <td></td>
      <td>...</td>
    </tr></tbody></table><script>
    setTimeout(() => {
      const td = [...document.querySelectorAll("td")][1];
      td.textContent = "✓";
    }, 2000);
    </script></body></html>`;
    
    let browser;
    (async () => {
      browser = await puppeteer.launch();
      const [page] = await browser.pages();
      await page.setContent(html);
      console.log("waiting for checkmark...");
      await page.waitForFunction((newUser) => {
        const newUserEl = [...document.querySelectorAll("td")]
          .find(el => el.textContent.trim() === newUser);
        return newUserEl?.nextElementSibling?.textContent?.trim() === "✓";
      }, {}, "New User");
      console.log("checkmark is guaranteed to exist at this point");
    })()
      .catch(err => console.error(err))
      .finally(() => browser?.close());