playwright/docs/src/dialogs.md
Dmitry Gozman 53ed35ef96
feat(dialogs): auto-dismiss dialogs when there are no listeners (#5269)
This makes dialogs disappear and prevents stalling.

Pros:
- No need to worry about dialogs for most users.
- Those that wait for a specific dialog still get to control it.

Cons:
- Those who use Playwright to show interactive browser will have
  to add an empty 'dialog' handler to prevent auto-dismiss.
  We do this in cli.
2021-02-03 10:34:45 -08:00

2.8 KiB

id title
dialogs Dialogs

Playwright can interact with the web page dialogs such as alert, confirm, prompt as well as beforeunload confirmation.

alert(), confirm(), prompt() dialogs

By default, dialogs are auto-dismissed by Playwright, so you don't have to handle them. However, you can register a dialog handler before the action that triggers the dialog to accept or decline it.

page.on('dialog', dialog => dialog.accept());
await page.click('button');
page.on("dialog", lambda dialog: dialog.accept())
await page.click("button")
page.on("dialog", lambda dialog: dialog.accept())
page.click("button")

:::note [event: Page.dialog] listener must handle the dialog. Otherwise your action will stall, be it [method: Page.click], [method: Page.evaluate] or any other. That's because dialogs in Web are modal and block further page execution until they are handled. :::

As a result, following snippet will never resolve:

:::warn WRONG! :::

page.on('dialog', dialog => console.log(dialog.message()));
await page.click('button'); // Will hang here
page.on("dialog", lambda dialog: print(dialog.message))
await page.click("button") # Will hang here
page.on("dialog", lambda dialog: print(dialog.message))
page.click("button") # Will hang here

:::note If there is no listener for [event: Page.dialog], all dialogs are automatically dismissed. :::

API reference

  • [Dialog]
  • [method: Dialog.accept]
  • [method: Dialog.dismiss]

beforeunload dialog

When [method: Page.close] is invoked with the truthy [option: runBeforeUnload] value, it page runs its unload handlers. This is the only case when [method: Page.close] does not wait for the page to actually close, because it might be that the page stays open in the end of the operation.

You can register a dialog handler to handle the beforeunload dialog yourself:

page.on('dialog', async dialog => {
  assert(dialog.type() === 'beforeunload');
  await dialog.dismiss();
});
await page.close({runBeforeUnload: true});
async def handle_dialog(dialog):
    assert dialog.type == 'beforeunload'
    await dialog.dismiss()

page.on('dialog', lambda: handle_dialog)
await page.close(run_before_unload=True)
def handle_dialog(dialog):
    assert dialog.type == 'beforeunload'
    dialog.dismiss()

page.on('dialog', lambda: handle_dialog)
page.close(run_before_unload=True)