How to Handle Popups and Alerts in Playwright Easily


You write a perfect test script. It runs fine. But then, a popup appears. Your script breaks. It happens more often than you think. Alerts and popups can crash automated tests if they are not handled well. If you're learning through a Playwright TypeScript Online Training, you’ll realize these tiny popups are not optional. They're essential to test.
Cities like Bangalore are seeing rapid automation adoption. Local companies are now shifting from manual to full-stack automation. And as part of their agile pipelines, they can’t afford flaky scripts. Many of them face problems when their UI test breaks due to a surprise alert box or modal window.
The playwright has clear answers to these problems. It gives us simple and powerful ways to manage popups and alerts. Not just detect them but actually interact with them. Let’s explore how.
Native Browser Alerts: Using dialog Listener
Popups that are triggered using alert(), confirm(), or prompt() are known as native alerts. The playwright treats them using an event listener. Instead of waiting for the alert, you listen to it using page.on('dialog').
This is better than polling or using timeouts. Your test doesn’t need to switch context. It automatically catches the popup.
Example in TypeScript:
page.on('dialog', async dialog => {
console.log(dialog.message());
await dialog.accept(); // or dialog.dismiss();
});
await page.click('#trigger-alert');
You can also validate the message inside the alert. For example, you may want to accept if it says "Delete item?" and dismiss if it says something else. Playwright gives full control.
This matters for apps that use a lot of confirm() boxes. For example, enterprise apps where every action needs approval.
Custom Popups: Handled Like Regular DOM Elements
Not all popups use browser alerts. Many are just HTML modals styled with CSS. The playwright doesn’t treat these specially. They are DOM elements and need to be handled like any other button or input.
Here’s a simple example:
await page.waitForSelector('.modal-dialog');
await page.click('.modal-dialog .close-button');
This code waits for the modal to show, then clicks the close button. You can also add assertions to check the modal content.
Unlike native alerts, modals don’t block scripts. So, they won’t crash the test but may cause test failures if ignored.
For testers in fast-growing cities like Pune, where frontend-heavy applications are common, understanding this difference is important. Many teams there are adopting Playwright with C# and face challenges with popup modals created using Angular or React.
Popup Windows: Testing Tabs and Child Windows
Sometimes clicking a button opens a new browser window or tab. These are also called popups. Playwright handles this using context.on('page').
You don’t switch manually. The playwright listens to the new tab, captures it, and lets you work with it.
Example:
const [popup] = await Promise.all([
context.waitForEvent('page'),
page.click('#open-new-tab')
]);
await popup.waitForLoadState();
console.log(await popup.title());
This helps you test multi-tab flows. For example, opening a PDF, OAuth login, or help page.
This is an area where Playwright beats other tools like Selenium or Cypress. In Selenium, managing window handles is complex. Cypress doesn’t support multi-tab testing at all.
Table: How Playwright Handles Different Popups
Popup Type | How to Detect | How to Handle | Blocking? |
alert() | page.on('dialog') | dialog.accept() | Yes |
confirm() | page.on('dialog') | dialog.accept() / dismiss() | Yes |
prompt() | page.on('dialog') | dialog.accept('value') | Yes |
HTML modal popup | page.waitForSelector() | DOM element clicks | No |
New tab/window | context.waitForEvent() | Capture new page object | No |
This table summarizes how each popup is managed in Playwright. It also tells you which ones block the script and which ones don’t.
Replacing Timeouts with once
Many testers add a timeout after a click, hoping the alert appears. That’s not reliable. Playwright offers a better way using page.once('dialog'). It handles just one alert and clears itself.
Example:
page.once('dialog', async dialog => {
await dialog.accept();
});
This makes your script faster and less flaky. It's good for performance testing or CI pipelines where speed matters.
This is especially helpful when working in shared CI environments in larger cities. Bangalore's testing teams often run hundreds of tests in CI/CD pipelines. A flaky alert can slow down the whole build.
Why Does This Matters for Learners?
If you're taking a Playwright with TypeScript, dealing with alerts is a core skill. Many real-world applications rely heavily on popups for error messages, confirmations, and user flows.
Just learning the basics is not enough. You must test how your application behaves under real conditions—alerts, modals, and multi-tab workflows.
Mastering popup handling in Playwright means your tests are more stable. You’ll avoid random failures and flaky builds. You’ll write tests that actually reflect what users do.
Sum up,
Native alerts can break tests if not handled. Use page.on('dialog') to manage them. Custom modals are just DOM elements. Use selectors and visibility checks. Playwright supports new tab popups using context.waitForEvent('page'). Don’t use timeouts. Use once or on for cleaner and faster tests. Playwright is better than Selenium and Cypress for popup handling. Learn popup handling if you want complete test coverage.
Subscribe to my newsletter
Read articles from Manoj Agrawal directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Manoj Agrawal
Manoj Agrawal
Hi, I’m Manoj — a passionate blogger who loves sharing insights, tips, and stories on travel, tech, parenting, personal growth. When I’m not writing, you’ll find me sipping coffee, reading a good book, or exploring new places. Welcome to my corner of the internet!