CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jest-puppeteer

Jest preset that enables end-to-end testing with Puppeteer, providing browser automation and testing utilities.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

dialog-management.mddocs/

Dialog Management

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.

Capabilities

toDisplayDialog

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 navigation

Dialog Types and Behaviors

Alert Dialogs

Alert 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

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

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

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();

Complex Dialog Scenarios

Multiple Dialog Sequence

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");

Conditional Dialog Handling

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;
}

Dialog Timeout Handling

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);
}

Error Handling

The toDisplayDialog matcher will throw errors when:

  • No dialog appears: The block executes but no dialog is triggered within the timeout
  • Multiple dialogs: Multiple dialogs appear simultaneously (not supported)
  • Dialog already present: A dialog is already open when the matcher is called
  • Invalid dialog interaction: Attempting to dismiss an alert or calling invalid methods

Error messages include:

  • The timeout used for waiting
  • Information about any dialogs that were detected
  • Guidance on proper dialog handling

Best Practices

  • Single Dialog Per Call: Only handle one dialog per toDisplayDialog call
  • Proper Cleanup: Always accept or dismiss dialogs to avoid blocking subsequent operations
  • Type Checking: Check dialog type before deciding how to handle it
  • Timeout Consideration: Increase timeouts for dialogs that may appear slowly
  • Message Validation: Verify dialog messages match expected content before interacting
  • Error Recovery: Handle cases where expected dialogs don't appear
  • Sequential Handling: For multi-step processes, handle dialogs in sequence rather than simultaneously

docs

configuration.md

content-matching.md

dialog-management.md

element-interaction.md

form-handling.md

index.md

tile.json