Handle a beforeunload dialog

Register a dialog handler for the leave-page prompt, and know what the PHP API can trigger today.

A page with unsaved changes can register a beforeunload handler, so the browser asks "Leave site?" when the user navigates away. Playwright surfaces that prompt as a dialog. Register a handler with onDialog() before the action that leaves the page, exactly as you would for alert() or confirm().

Status: partial. The dialog handler is implemented, so you can accept or dismiss a beforeunload prompt when one fires. What the PHP API does not expose is a way to force one: Page::close() takes no arguments, so there is no runBeforeUnload flag as in Playwright JavaScript. You catch the prompt when a real navigation triggers it, not on demand from close().

Register the handler before you leave

Attach the handler first. A beforeunload dialog carries no message text of its own, so branch on $dialog->type(), then accept to leave or dismiss to stay.

php
$context = Playwright::chromium();
$page = $context->newPage();
$page->goto('https://app.example.test/editor');

$page->getByLabel('Title')->fill('Draft with unsaved changes');

$page->events()->onDialog(static function ($dialog): void {
    if ('beforeunload' === $dialog->type()) {
        $dialog->accept();
    }
});

Register the handler before the navigation, not after. A handler attached after the action misses the dialog, and the navigation hangs on the open prompt.

Trigger it with a navigation

The prompt fires when the page unloads. Navigate away with goto() after the handler is in place, and the handler accepts the prompt so the navigation completes.

php
$page->goto('https://app.example.test/dashboard');

expect($page->getByRole('heading', ['name' => 'Dashboard']))->toBeVisible();

What you cannot do yet

You cannot ask Page::close() to run the beforeunload handler: it takes no options. To exercise the prompt, drive a navigation that leaves the page, as above. If your test needs to assert that closing a tab runs the handler, that path is not reachable from the PHP API today.

Expected result

The navigation completes after the handler accepts the prompt, and the destination page becomes visible. If you dismiss the prompt instead, assert that the editor page remains open.

Go next

← All recipes