Skip to content

Puppeteer not picking up dialog box

I’m trying to test for an alert box in Puppeteer:

    msg = '';
    await page.goto('http://localhost:8080/', {
      waitUntil: 'networkidle2'
    });
    await page.$eval('#value', el => el.value = '<script>alert("BLEH")</script>');
    page.on('dialog', async dialog => {
      msg = dialog.message();
      await dialog.dismiss()
    })
    // submit comment
    await page.$eval('#message', form => form.submit());
    expect(msg).toEqual('BLEH');

However, it doesn’t seem to return the message inside the alert box (even though I’ve confirmed it works doing it manually). Any ideas why page.on('dialog', async dialog => { isn’t being entered?

Answer

I’m not sure what’s going on with your page — it looks like you’re testing XSS, but in any case, you can promisify the dialog handler to resolve to the dialog.message() value as in this example.

Note that I’m submitting the form with Enter — calling form.submit() seems to override the default prevention, killing the page, but if it works on your site, that modification doesn’t change the fundamental point of the code below.

Keep in mind that await dialogDismissed; will never time out since it’s not a Puppeteer function. If you want that, call setTimeout(reject, someDelay) in the promise.

const puppeteer = require("puppeteer");

let browser;
(async () => {
  const html = `
    <form id="message"><input id="value"></form>
    <script>
      document
        .getElementById("message")
        .addEventListener("submit", e => {
          e.preventDefault();
          alert(document.getElementById("value").value);
        })
      ;
    </script>
  `;
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  const dialogDismissed = new Promise((resolve, reject) => {
    const handler = async dialog => {
      await dialog.dismiss();
      resolve(dialog.message());
    };
    page.once("dialog", handler);
  });
  await page.setContent(html);
  const inputEl = await page.$("#value");
  await inputEl.type("hello world");
  await inputEl.press("Enter");
  const msg = await dialogDismissed;
  console.log(msg); // => hello world
  await page.close();
})()
  .catch(err => console.error(err))
  .finally(async () => await browser.close())
;