Browser pop-ups block the page until someone answers them. Learn to accept, dismiss and read them, and to tell them apart from dialogs built into the page.
Every solution on this page starts with this hook. With baseURL set to https://hiraanachwani.com in your playwright.config.ts, it opens this page before each test.
Before you start: Playwright closes browser pop-ups automatically by clicking Cancel, unless your test listens for them. Register the listener with page.once('dialog', …)before the click that opens the pop-up.
Alert
A message with a single OK button.
Try this
Open the alert and check its message is Hello from the practice page!
Accept it and check the result says Alert closed.
Locator tip: a browser pop-up isn't part of the page, so no locator can find it. You handle it through the dialog event, where dialog.message() gives you its text.
Show Playwright solution
test('alert', async ({ page }) => {
let message = '';
page.once('dialog', async (dialog) => {
message = dialog.message();
await dialog.accept();
});
await page.getByRole('button', { name: 'Show alert', exact: true }).click();
expect(message).toBe('Hello from the practice page!');
await expect(page.getByTestId('alert-result')).toHaveText('Alert closed');
});
Confirm
A question with OK and Cancel. The page reacts differently to each.
Try this
Click Delete item and accept. Check the result says You clicked OK.
Click it again and dismiss. Check the result says You clicked Cancel.
Locator tip:dialog.accept() clicks OK and dialog.dismiss() clicks Cancel. page.once handles only the next pop-up, so register a new one before each click.
This alert appears 2 seconds after the click, the way a slow server response might trigger one.
Try this
Click the button and check the result says Alert coming… straight away.
Wait for the alert, accept it, and check the result says Delayed alert closed.
Locator tip: the click finishes before the alert appears, so don't add a fixed wait. expect keeps retrying until the result text changes, which gives the alert time to show and be handled.
Show Playwright solution
test('delayed alert', async ({ page }) => {
const result = page.getByTestId('delayed-alert-result');
page.once('dialog', (dialog) => dialog.accept());
await page.getByRole('button', { name: 'Show alert in 2 seconds' }).click();
await expect(result).toHaveText('Alert coming…');
// expect retries for up to 5 seconds by default, long enough for the alert
await expect(result).toHaveText('Delayed alert closed');
});
Modal dialog
A dialog built into the page with HTML. Unlike a browser pop-up, it's a normal element you locate and click.
Try this
Open the terms and check the dialog called Terms of use is visible.
Press Escape and check it closes and the result says Dialog closed without accepting.
Open it again, click Accept, and check the result says Terms accepted.
Locator tip:page.getByRole('dialog', { name: 'Terms of use' }) finds the dialog by its heading. Look for buttons inside it, so Accept can't match a button elsewhere on the page.