Get started

Dialogs

Introduction

CSTesting can interact with JavaScript dialogs: alert, confirm, prompt, and beforeunload. You register a dialog handler that receives the dialog type and message and returns whether to accept or dismiss, and (for prompt) what text to submit. By default, all dialogs are accepted automatically (prompt gets an empty string), so actions do not block. If you set a custom handler, it must return a result for every dialog; otherwise the action that triggered the dialog can hang because dialogs are modal and block page execution until they are handled.

You will learn

  • Default behavior (auto-accept)
  • How to set a dialog handler (accept or dismiss)
  • Handling prompt (provide text)
  • Handling beforeunload
  • What is not supported (print dialog, close options)

Default behavior

If you do not set a dialog handler, CSTesting uses a default: all dialogs are accepted. For prompt, the default sends an empty string. So alert(), confirm(), and prompt() do not block your test — the dialog is closed immediately with "OK" (and empty input for prompt).

await browser.goto('https://example.com');
await browser.click('button'); // If this triggers alert(), it is auto-accepted and execution continues.

Setting a dialog handler

Use setDialogHandler to control how each dialog is handled. The handler receives an object { type, message } and returns { accept: boolean, promptText?: string }.

  • type'alert' | 'confirm' | 'prompt' | 'beforeunload'
  • message — The text shown in the dialog (e.g. the message passed to alert(message)).

Return:

  • { accept: true } — Accept the dialog (OK). For prompt, you can also pass promptText.
  • { accept: false } — Dismiss the dialog (Cancel).
  • { accept: true, promptText: 'some value' } — For prompt only: accept and send this string as the input.

Example: accept all dialogs (same as default)

browser.setDialogHandler(({ type, message }) => {
  return { accept: true, promptText: '' };
});
await browser.click('button');

Example: dismiss confirm

browser.setDialogHandler(({ type, message }) => {
  if (type === 'confirm') return { accept: false };
  return { accept: true };
});
await browser.click('#delete-button');

Example: handle prompt with custom text

browser.setDialogHandler(({ type, message }) => {
  if (type === 'prompt') return { accept: true, promptText: 'My name' };
  return { accept: true };
});
await browser.click('#ask-name');

Example: log and accept

browser.setDialogHandler(({ type, message }) => {
  console.log(`Dialog [${type}]: ${message}`);
  return { accept: true, promptText: '' };
});

You can set the handler before the action that triggers the dialog. To stop handling explicitly and go back to default, pass null:

browser.setDialogHandler(null);

Important: handler must return a result

Dialogs are modal: the browser blocks until the dialog is handled. If your handler does not return (or throws before returning), or if you never call handleJavaScriptDialog (CSTesting does that for you based on your return value), the action that opened the dialog will hang.

Wrong — don't just log and forget to return; the click will hang:

browser.setDialogHandler(({ type, message }) => {
  console.log(message);
  // Missing return! Dialog is never handled.
});
await browser.click('button'); // Hangs here

Correct — always return { accept, promptText? }:

browser.setDialogHandler(({ type, message }) => {
  console.log(message);
  return { accept: true };
});
await browser.click('button');

The handler can be async (return a Promise); CSTesting will await it and then handle the dialog.


beforeunload dialog

When the page (or a navigation) triggers a beforeunload dialog (e.g. "Leave site?"), the same handler is used. Check type === 'beforeunload' and return accept: true to leave or accept: false to stay.

browser.setDialogHandler(({ type, message }) => {
  if (type === 'beforeunload') return { accept: true }; // Leave page
  return { accept: true };
});
// Trigger navigation or close that causes beforeunload
await browser.click('a[href="https://other.com"]');

CSTesting does not expose page.close({ runBeforeUnload: true }). Closing the browser/tab is done with browser.close(); there is no option to run beforeunload or to leave the page open. If you need to test beforeunload on a specific user action (e.g. closing a tab), use the dialog handler as above when that action is triggered.


What is not supported (current version)

FeatureSupported?Workaround
alert / confirm / prompt / beforeunloadYesUse setDialogHandler with { type, message } and return { accept, promptText? }.
Default auto-acceptYesDon't set a handler, or set handler that returns { accept: true }.
Accept with prompt textYesReturn { accept: true, promptText: 'value' } for type 'prompt'.
Dismiss (Cancel)YesReturn { accept: false }.
page.close({ runBeforeUnload })NoNo close options; use setDialogHandler when beforeunload is triggered by navigation or other actions.
Print dialog (window.print)NoNo built-in way to detect or handle the print dialog. Use evaluate to replace window.print and assert it was called if needed.

Summary

  • Default: All dialogs are accepted (prompt gets ''). No handler needed for simple flows.
  • Custom handling: Call browser.setDialogHandler(handler). Handler receives { type, message } and returns { accept: boolean, promptText?: string }.
  • Accept: return { accept: true }. For prompt, optionally return { accept: true, promptText: 'value' }.
  • Dismiss: return { accept: false }.
  • beforeunload: Same handler; check type === 'beforeunload' and return accept/dismiss.
  • Always return from the handler so the dialog is handled and the action does not hang.
  • To reset to default behavior: browser.setDialogHandler(null).
  • Print dialog is not supported; use evaluate if you need to detect or stub window.print.