Alerts, Dialogs & Popups
Handle JavaScript alert/confirm/prompt dialogs and browser popup windows or new tabs opened by your application.
JavaScript Dialogs
JavaScript's native alert(), confirm(), and prompt() functions open modal dialogs that block the browser. Playwright fires a dialog event on the page object whenever one of these appears. Register a listener with page.on('dialog', handler) before the action that triggers the dialog, then call dialog.accept() or dialog.dismiss() inside the handler. For prompts you can supply a return value via dialog.accept(promptText).
New Tabs and Popup Windows
When a link or button opens a new browser tab or window, Playwright emits a popup event on the page that triggered the open. Use page.waitForEvent('popup') to capture the new Page object, then interact with it just like any other page. The popup is a fully independent browser context with its own URL, cookies, and DOM.
File Chooser Dialogs
Native OS file-chooser dialogs are handled similarly. Listen for the filechooser event before clicking the upload button, then call fileChooser.setFiles(path) to supply the file programmatically without ever interacting with the OS dialog.
import { test, expect } from '@playwright/test';
test('accept a confirm dialog', async ({ page }) => {
await page.goto('/delete-demo');
// Register handler BEFORE the action
page.on('dialog', dialog => {
expect(dialog.message()).toContain('Are you sure');
dialog.accept();
});
await page.getByRole('button', { name: 'Delete account' }).click();
await expect(page.getByText('Account deleted')).toBeVisible();
});
test('handle prompt dialog', async ({ page }) => {
await page.goto('/rename-demo');
page.on('dialog', dialog => {
// Supply a value for prompt() dialogs
dialog.accept('My New Name');
});
await page.getByRole('button', { name: 'Rename' }).click();
await expect(page.getByText('My New Name')).toBeVisible();
});
test('capture a new tab', async ({ page, context }) => {
await page.goto('/links');
// Wait for popup before clicking the link
const [popup] = await Promise.all([
page.waitForEvent('popup'),
page.getByRole('link', { name: 'Open in new tab' }).click(),
]);
await popup.waitForLoadState();
await expect(popup).toHaveURL(/external-page/);
});
import com.microsoft.playwright.*;
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
class DialogsTest {
void acceptDialog(Page page) {
page.navigate("/delete-demo");
// Register before click
page.onDialog(dialog -> {
System.out.println("Dialog: " + dialog.message());
dialog.accept();
});
page.getByRole(AriaRole.BUTTON,
new Page.GetByRoleOptions().setName("Delete account")).click();
assertThat(page.getByText("Account deleted")).isVisible();
}
void capturePopup(Page page) {
page.navigate("/links");
// waitForPopup wraps the action
Page popup = page.waitForPopup(() ->
page.getByRole(AriaRole.LINK,
new Page.GetByRoleOptions().setName("Open in new tab")).click()
);
popup.waitForLoadState();
assertThat(popup).hasURL("external-page");
}
}
from playwright.sync_api import Page, expect, Dialog
def test_accept_confirm_dialog(page: Page):
page.goto("/delete-demo")
# Register handler before the action that triggers dialog
def handle_dialog(dialog: Dialog):
assert "Are you sure" in dialog.message
dialog.accept()
page.on("dialog", handle_dialog)
page.get_by_role("button", name="Delete account").click()
expect(page.get_by_text("Account deleted")).to_be_visible()
def test_capture_popup(page: Page):
page.goto("/links")
# expect_popup context manager captures the new tab
with page.expect_popup() as popup_info:
page.get_by_role("link", name="Open in new tab").click()
popup = popup_info.value
popup.wait_for_load_state()
expect(popup).to_have_url(/external-page/)
Written by PV
© 2026 All Rights Reserved