Jest preset that enables end-to-end testing with Puppeteer, providing browser automation and testing utilities.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Page-specific functionality for handling browser dialogs, alerts, confirmations, and prompts. This capability is only available when working with Page instances and provides sophisticated dialog interaction patterns.
Executes a block of code that is expected to trigger a browser dialog and captures the dialog for further interaction. This matcher is essential for testing user workflows that involve JavaScript dialogs.
/**
* Execute a block of code that triggers a dialog and capture it
* @param block - Async function that should trigger a browser dialog
* @returns Promise that resolves to the Dialog instance when dialog appears
*/
toDisplayDialog(block: () => Promise<void>): Promise<Dialog>;
interface Dialog {
/** The type of dialog: 'alert', 'confirm', 'prompt', or 'beforeunload' */
type(): string;
/** The message text displayed in the dialog */
message(): string;
/** The default value for prompt dialogs, empty string for others */
defaultValue(): string;
/** Accept the dialog (OK button) */
accept(promptText?: string): Promise<void>;
/** Dismiss the dialog (Cancel button) - only available for confirm/prompt */
dismiss(): Promise<void>;
}Usage Examples:
import { expect } from "expect-puppeteer";
// Handle alert dialog
const alertDialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#show-alert-btn");
});
console.log("Alert message:", alertDialog.message()); // "This is an alert!"
console.log("Dialog type:", alertDialog.type()); // "alert"
await alertDialog.accept();
// Handle confirmation dialog
const confirmDialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#delete-item-btn");
});
console.log("Confirm message:", confirmDialog.message()); // "Are you sure you want to delete this item?"
if (confirmDialog.message().includes("delete")) {
await confirmDialog.accept(); // Click OK
} else {
await confirmDialog.dismiss(); // Click Cancel
}
// Handle prompt dialog
const promptDialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#rename-file-btn");
});
console.log("Prompt message:", promptDialog.message()); // "Enter new filename:"
console.log("Default value:", promptDialog.defaultValue()); // "document.txt"
await promptDialog.accept("my-new-document.txt");
// Handle beforeunload dialog
const beforeUnloadDialog = await expect(page).toDisplayDialog(async () => {
await page.goto("https://another-site.com");
});
console.log("Dialog type:", beforeUnloadDialog.type()); // "beforeunload"
await beforeUnloadDialog.accept(); // Continue navigationAlert dialogs only have an "OK" button and are used to display information to the user.
import { expect } from "expect-puppeteer";
// Basic alert handling
const alert = await expect(page).toDisplayDialog(async () => {
// Trigger action that shows alert
await page.evaluate(() => alert("Operation completed successfully!"));
});
console.log(alert.type()); // "alert"
console.log(alert.message()); // "Operation completed successfully!"
// Only accept() is available for alerts
await alert.accept();
// Verify dialog was handled
await expect(page).toMatchTextContent("Alert was dismissed");Confirmation dialogs have both "OK" and "Cancel" buttons and are used to get user consent.
import { expect } from "expect-puppeteer";
// Handle confirmation - accept
const confirmAccept = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#logout-btn");
});
console.log(confirmAccept.type()); // "confirm"
console.log(confirmAccept.message()); // "Are you sure you want to log out?"
await confirmAccept.accept(); // User clicked OK
await expect(page).toMatchTextContent("Logged out successfully");
// Handle confirmation - dismiss
const confirmDismiss = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#delete-account-btn");
});
await confirmDismiss.dismiss(); // User clicked Cancel
await expect(page).toMatchTextContent("Account deletion cancelled");Prompt dialogs allow users to enter text input and have both "OK" and "Cancel" buttons.
import { expect } from "expect-puppeteer";
// Handle prompt with custom input
const prompt = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#add-comment-btn");
});
console.log(prompt.type()); // "prompt"
console.log(prompt.message()); // "Enter your comment:"
console.log(prompt.defaultValue()); // "" (empty default)
await prompt.accept("This is my comment text");
await expect(page).toMatchTextContent("Comment added: This is my comment text");
// Handle prompt dismissal
const cancelledPrompt = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#rename-btn");
});
await cancelledPrompt.dismiss(); // User clicked Cancel
await expect(page).toMatchTextContent("Rename cancelled");
// Handle prompt with default value
const promptWithDefault = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#edit-title-btn");
});
console.log(promptWithDefault.defaultValue()); // "Current Title"
await promptWithDefault.accept("New Title Here");BeforeUnload dialogs appear when leaving a page that has unsaved changes.
import { expect } from "expect-puppeteer";
// Handle page navigation with unsaved changes
await expect(page).toFill("#editor", "Some unsaved content...");
const beforeUnload = await expect(page).toDisplayDialog(async () => {
await page.goto("https://example.com/other-page");
});
console.log(beforeUnload.type()); // "beforeunload"
// Continue navigation (lose changes)
await beforeUnload.accept();
// Or cancel navigation (stay on page)
// await beforeUnload.dismiss();import { expect } from "expect-puppeteer";
// Handle sequence of dialogs
const firstDialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#multi-step-action");
});
await firstDialog.accept();
const secondDialog = await expect(page).toDisplayDialog(async () => {
// First dialog triggers another action that shows second dialog
});
await secondDialog.accept("User input for second dialog");
await expect(page).toMatchTextContent("Multi-step process completed");import { expect } from "expect-puppeteer";
// Handle different dialog types based on content
const dialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#dynamic-action-btn");
});
switch (dialog.type()) {
case "alert":
console.log("Info:", dialog.message());
await dialog.accept();
break;
case "confirm":
if (dialog.message().includes("delete")) {
await dialog.accept(); // Confirm deletion
} else {
await dialog.dismiss(); // Cancel other actions
}
break;
case "prompt":
const defaultVal = dialog.defaultValue();
await dialog.accept(defaultVal + " (modified)");
break;
}import { expect } from "expect-puppeteer";
import { setDefaultOptions } from "expect-puppeteer";
// Increase timeout for slow dialog appearance
setDefaultOptions({ timeout: 10000 });
try {
const dialog = await expect(page).toDisplayDialog(async () => {
await expect(page).toClick("#slow-dialog-btn");
});
await dialog.accept();
} catch (error) {
console.error("Dialog did not appear within timeout:", error.message);
}The toDisplayDialog matcher will throw errors when:
Error messages include:
toDisplayDialog call