Halmurat T.
· 2 min read

Playwright's onceDialog Saved Me From a Handler Leak

Table of Contents

I registered page.onDialog() to accept a delete confirmation in a test. The delete worked fine. Then, three steps later in the same test, the user clicked “Logout” — which also triggers a confirm() dialog. My delete handler was still registered. It silently accepted the logout confirmation, the user got logged out mid-test, and the next assertion failed with a session error. I spent 20 minutes blaming the app before realizing my own handler was the problem.

The Problem: onDialog Is Permanent

page.onDialog() registers a listener that stays active for the entire lifetime of the page. Every dialog that fires — whether you intended to handle it or not — goes through that handler.

src/test/java/tests/PatientTest.java
// This handler stays registered for ALL future dialogs on this page
page.onDialog(dialog -> dialog.accept());
// Delete confirmation — handled correctly
page.locator("[data-testid='delete-patient']").click();
// ... 3 steps later, logout also triggers confirm() ...
page.locator("[data-testid='logout']").click();
// Logout confirm silently accepted — NOT what we wanted

The logout dialog should have been dismissed (cancel the logout, stay in the app), but the permanent handler accepted it. The test continued on a logged-out session and failed on the next page interaction.

The Fix: onceDialog Auto-Removes

page.onceDialog() fires exactly once, then removes itself. The dialog handler is scoped to the next dialog only — after that, it’s gone.

src/test/java/tests/PatientTest.java
// This handler fires ONCE, then auto-removes
page.onceDialog(dialog -> dialog.accept());
// Delete confirmation — handled, handler now gone
page.locator("[data-testid='delete-patient']").click();
// Logout triggers confirm() — no active handler
// Falls through to default behavior (or your base class handler)
page.locator("[data-testid='logout']").click();

Now the delete confirmation gets accepted, the handler removes itself, and the logout dialog falls through to whatever default handler you’ve registered in your base test class.

When to Use Which

The rule of thumb: if you’re writing page.onDialog() inside a test method (not in @BeforeMethod), you almost certainly want page.onceDialog() instead.

Related Posts

Get weekly QA automation insights

No fluff, just battle-tested strategies from 10+ years in the trenches.

No spam. Unsubscribe anytime.