Ora

How do you handle alerts in Puppeteer?

Published in Puppeteer Dialog Handling 5 mins read

To handle alerts and other native browser dialogs in Puppeteer, you primarily use the page.on('dialog') event listener. This powerful mechanism allows your script to intercept, inspect, and interact with various types of dialogs like alert, confirm, and prompt, preventing your automation from hanging and enabling dynamic test flows.

Understanding Web Dialogs in Puppeteer

Web dialogs (also known as JavaScript dialogs) are modal windows displayed by the browser, typically triggered by JavaScript. In Puppeteer, these dialogs are represented by a Dialog object that provides methods to interact with them programmatically.

There are three main types of dialogs you'll encounter:

  • alert: Displays a message and an "OK" button.
  • confirm: Displays a message and "OK" and "Cancel" buttons, returning true or false based on the user's choice.
  • prompt: Displays a message, a text input field, and "OK" and "Cancel" buttons, returning the entered text or null.

The dialog Event Listener

The core of dialog handling in Puppeteer is the page.on('dialog', handler) event. When a JavaScript dialog is initiated on the page, Puppeteer emits a 'dialog' event, passing a Dialog object to your specified handler function.

Here's the basic structure:

page.on('dialog', async dialog => {
  // Your logic to handle the dialog
  // e.g., inspect type, message, then accept or dismiss
});

It's crucial to either accept() or dismiss() the dialog within the event listener, as unhandled dialogs will cause your script to halt execution until they are dealt with.

Key Dialog Properties and Methods

The Dialog object received by the event handler provides several essential properties and methods for interaction:

Property/Method Type Description
type() string Returns the type of the dialog: 'alert', 'confirm', or 'prompt'.
message() string Retrieves the message text displayed in the dialog.
defaultValue() string? Returns the default value displayed in the text input for 'prompt' dialogs, if any.
accept([promptText]) Promise<void> Accepts the dialog. For 'prompt' dialogs, an optional promptText can be provided to fill the input field.
dismiss() Promise<void> Dismisses (cancels) the dialog. This is effective for 'confirm' and 'prompt' dialogs.

Practical Examples of Handling Dialogs

Let's look at how to handle each type of dialog with concrete examples.

1. Handling alert Dialogs

alert dialogs are the simplest as they only have an "OK" button. You typically just accept them.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // Set up the dialog listener
  page.on('dialog', async dialog => {
    console.log(`Alert message: "${dialog.message()}"`);
    await dialog.accept(); // Accept the alert
  });

  await page.goto('https://example.com'); // Navigate to a page

  // Trigger an alert (example)
  await page.evaluate(() => alert('Hello, Puppeteer! This is an alert.'));

  await browser.close();
})();

2. Handling confirm Dialogs

confirm dialogs allow you to choose between "OK" (accept) or "Cancel" (dismiss).

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  page.on('dialog', async dialog => {
    console.log(`Confirm message: "${dialog.message()}"`);
    if (dialog.message().includes('proceed')) {
      await dialog.accept(); // Click 'OK'
      console.log('Confirmed!');
    } else {
      await dialog.dismiss(); // Click 'Cancel'
      console.log('Dismissed!');
    }
  });

  await page.goto('https://example.com');

  // Trigger a confirm dialog (example - will be accepted)
  await page.evaluate(() => confirm('Do you want to proceed?'));

  // Trigger another confirm dialog (example - will be dismissed)
  await page.evaluate(() => confirm('Are you sure you want to delete?'));

  await browser.close();
})();

3. Handling prompt Dialogs

prompt dialogs allow you to input text before accepting or dismissing.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  page.on('dialog', async dialog => {
    console.log(`Prompt message: "${dialog.message()}"`);
    console.log(`Default value: "${dialog.defaultValue()}"`);
    if (dialog.type() === 'prompt') {
      await dialog.accept('My Name is Puppeteer'); // Enter text and click 'OK'
      console.log('Prompt accepted with text.');
    } else {
      await dialog.dismiss();
    }
  });

  await page.goto('https://example.com');

  // Trigger a prompt dialog (example)
  await page.evaluate(() => prompt('Please enter your name:', 'Guest'));

  // You can also get the value returned by the prompt if the page uses it
  const result = await page.evaluate(() => prompt('Enter a number:'));
  console.log(`Prompt evaluated result on page: ${result}`); // This will show 'My Name is Puppeteer' from the first prompt

  await browser.close();
})();

Best Practices for Dialog Handling

  • Always Handle Dialogs: Ensure your page.on('dialog') listener is always set up before any action that might trigger a dialog. Unhandled dialogs will cause your tests to hang indefinitely.
  • Inspect Dialog Type: Use dialog.type() to differentiate between alert, confirm, and prompt dialogs, and apply the appropriate action.
  • Asynchronous Handling: Remember that dialog handling is asynchronous. Use await when calling dialog.accept() or dialog.dismiss().
  • Contextual Actions: Use dialog.message() to read the dialog's content and make conditional decisions on whether to accept, dismiss, or input text.
  • Error Handling: Consider adding try-catch blocks around your page.evaluate() calls if dialogs are not always expected, to gracefully handle cases where dialogs might or might not appear.

By implementing these strategies, you can robustly manage all types of browser dialogs, ensuring your Puppeteer scripts run smoothly and accurately reflect user interactions.

For more detailed information, refer to the Puppeteer Dialog documentation.