Special matcher for handling browser dialogs (alerts, confirmations, prompts) that appear as a result of page interactions. This matcher is only available on Page instances.
Executes a block of code and captures any dialog that appears during execution.
/**
* Execute block and capture any dialog that appears
* @param page - Page instance (not available on Frame or ElementHandle)
* @param block - Async function that should trigger a dialog
* @returns Promise resolving to the Dialog instance
*/
function toDisplayDialog(
page: Page,
block: () => Promise<void>
): Promise<Dialog>;Usage Examples:
// Capture alert dialog
const dialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("button", { text: "Show Alert" });
});
console.log(dialog.message()); // Access dialog message
await dialog.accept(); // Accept the dialog
// Capture confirmation dialog
const confirmDialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("button", { text: "Delete Item" });
});
if (confirmDialog.type() === "confirm") {
await confirmDialog.accept(); // or dialog.dismiss()
}
// Capture prompt dialog with input
const promptDialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("button", { text: "Enter Name" });
});
await promptDialog.accept("John Doe"); // Provide input and acceptThe captured Dialog object supports all standard Puppeteer dialog operations:
// Dialog interface from Puppeteer
interface Dialog {
/** Get the dialog type */
type(): "alert" | "beforeunload" | "confirm" | "prompt";
/** Get the dialog message text */
message(): string;
/** Get the default value (for prompt dialogs) */
defaultValue(): string;
/** Accept the dialog, optionally providing input for prompts */
accept(promptText?: string): Promise<void>;
/** Dismiss/cancel the dialog */
dismiss(): Promise<void>;
}// Simple alert acknowledgment
const dialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#alert-button");
});
expect(dialog.type()).toBe("alert");
expect(dialog.message()).toBe("Operation completed!");
await dialog.accept();// Handle confirmation dialog
const dialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#delete-button");
});
expect(dialog.type()).toBe("confirm");
expect(dialog.message()).toContain("Are you sure");
// Accept or dismiss based on test scenario
await dialog.accept(); // Confirm deletion
// or
// await dialog.dismiss(); // Cancel deletion// Handle prompt dialog with user input
const dialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#name-input-button");
});
expect(dialog.type()).toBe("prompt");
expect(dialog.defaultValue()).toBe(""); // Check default value
await dialog.accept("Test User"); // Provide input and accept// Dialog triggered by multiple actions
const dialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toFill("#amount", "1000");
await expect(page).toSelect("#currency", "USD");
await expect(page).toClick("#submit-transfer");
});
expect(dialog.message()).toContain("Transfer $1000");
await dialog.accept();The toDisplayDialog matcher will:
Common error scenarios:
// This will timeout if no dialog appears
try {
const dialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#normal-button"); // No dialog triggered
});
} catch (error) {
console.log("No dialog was displayed");
}
// This will fail if the action throws before dialog
try {
const dialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#nonexistent-button"); // Throws error
});
} catch (error) {
console.log("Block failed before dialog could appear");
}The matcher automatically sets up dialog event listeners before executing the block and cleans up afterwards. This ensures:
Implementation Note:
The matcher uses Puppeteer's page.on('dialog') event listener internally, so you should not set up competing dialog listeners while using this matcher.
The dialog matcher inherits timeout behavior from the global configuration:
import { setDefaultOptions } from "expect-puppeteer";
// Set longer timeout for slow dialog operations
setDefaultOptions({ timeout: 2000 });
const dialog = await expect(page).toDisplayDialog(async () => {
// This action might take time to trigger the dialog
await expect(page).toClick("#slow-dialog-button");
});Dialog handling works with all dialog types across different browsers:
Note: beforeunload dialogs are typically triggered by navigation attempts and may require specific test setup.