Handling Alerts,windows and frames in Playwright (Complete Guide)

Handling playwright alerts, windows, and frames is an essential skill for automation testing. In this guide, you will learn how to manage browser alerts, switch between multiple windows, and interact with iframes using Playwright.

What are Alerts?

Alerts are browser popup dialogs triggered by JavaScript.
They are used by web applications to display messages or ask users for confirmation before performing actions.

Playwright Alerts, Windows and Frames

When an alert appears, the browser blocks interaction with the rest of the page until the alert is handled.

In automation testing, these alerts must be accepted or dismissed programmatically.

Playwright handles alerts using the dialog event.


Types of JavaScript Alerts

There are three main types of alerts.

1. Alert Box

An alert box displays a message to the user and only has an OK button.

Example:

alert("Login Successful");

The user must click OK to continue.


2. Confirm Dialog

A confirm dialog asks the user to confirm an action.

It contains:

  • OK
  • Cancel

Example:

confirm("Are you sure you want to delete this record?");

3. Prompt Dialog

Prompt dialogs allow the user to enter text input.

Example:

prompt("Enter your name");

How Playwright Handles Alerts

Playwright uses an event listener called dialog.

When an alert appears, Playwright captures it using:

page.on('dialog', async dialog => {

});

The dialog object contains:

  • dialog.type()
  • dialog.message()
  • dialog.accept()
  • dialog.dismiss()

Accepting an Alert

Accepting an alert means clicking OK.

Example:

page.on('dialog', async dialog => {
  await dialog.accept();
});

await page.click('#deleteButton');

What happens here?

  1. A click action triggers the alert
  2. Playwright listens for the dialog event
  3. The alert is accepted automatically

In Playwright, dialog handlers (alerts, confirms, prompts) must be registered before the action that triggers them.Playwright emits a ‘dialog’ event the moment a popup appears. If the listener is registered after the click, the event is missed.


Dismissing an Alert

Dismissing means clicking Cancel.

Example:

page.on('dialog', async dialog => {
  await dialog.dismiss();
});

await page.click('#deleteButton');

Handling Prompt Alerts

Prompt dialogs require text input.

Example:

page.on('dialog', async dialog => {
  await dialog.accept('Arun');
});

await page.click('#enterName');

Here:

  • The prompt receives the value Arun
  • Then the alert is accepted

Capturing Alert Message

Often we need to verify the alert message.

Example:

page.on('dialog', async dialog => {

  console.log(dialog.message());

  await dialog.accept();

});

Output example:

Are you sure you want to delete?

Getting Alert Type

Playwright allows retrieving the alert type.

Example:

page.on('dialog', async dialog => {

  console.log(dialog.type());

  await dialog.accept();

});

Possible types:

  • alert
  • confirm
  • prompt
  • beforeunload

Full Alert Handling Example

Example test scenario:

User deletes a record and a confirmation alert appears.

import { test, expect } from '@playwright/test';

test('Handle delete confirmation alert', async ({ page }) => {

  await page.goto('https://example.com');

  page.on('dialog', async dialog => {

    console.log(dialog.message());

    await dialog.accept();

  });

  await page.click('#deleteRecord');

});

Best Practices for Handling Alerts

  1. Always register the dialog listener before triggering the alert

Correct:

page.on('dialog', handler)
page.click()

Incorrect:

page.click()
page.on('dialog')

  1. Validate alert messages when possible
expect(dialog.message()).toContain("Delete");

  1. Handle alerts inside test steps clearly.

Handling Multiple Windows / Tabs in Playwright

Some web applications open new pages in:

  • New tabs
  • New browser windows
  • External pages

Examples:

  • Payment gateway
  • Documentation links
  • Reports
  • Login through OAuth

Automation scripts must switch between these windows.


Playwright Architecture

Playwright manages browser tabs using:

Browser → Context → Page

Browser
   └── Context
          ├── Page 1
          ├── Page 2
          └── Page 3

Each tab or window is represented by a Page object.


Handling a New Tab

When clicking a link that opens a new tab:

Example:

const [newPage] = await Promise.all([

  context.waitForEvent('page'),

  page.click('#openWindow')

]);

Why Promise.all?

This ensures Playwright waits for the new tab event while clicking the button.


Waiting for the New Page to Load

After the tab opens:

await newPage.waitForLoadState();

This ensures the page loads completely before interaction.


Interacting With New Window

Example:

await newPage.fill('#search','Playwright');
await newPage.click('#searchButton');

Switching Between Tabs

Playwright does not require explicit window switching like Selenium.

Simply use the page object.

Example:

page → original tab
newPage → new tab

Example:

await page.bringToFront();

Getting All Open Tabs

Example:

const pages = context.pages();

Output example:

[
  Page1,
  Page2,
  Page3
]

Closing a Tab

Example:

await newPage.close();

This closes the new tab.


Real Example – Multiple Windows

Example test scenario:

Click a link that opens documentation in a new tab.

test('Handle new tab', async ({ page, context }) => {

  await page.goto('https://example.com');

  const [newPage] = await Promise.all([
    context.waitForEvent('page'),
    page.click('#documentation')
  ]);

  await newPage.waitForLoadState();

  console.log(await newPage.title());

});

Best Practices for Window Handling

  1. Always use Promise.all()
  2. Always wait for page load
  3. Store the new page object
  4. Close unnecessary tabs

Handling Frames in Playwright

Before handling frames, make sure you understand Playwright locators.

What are Frames?

Frames (also called iframes) are HTML elements that embed another webpage inside the main page.

Example:

<iframe src="payment.html"></iframe>

Frames are commonly used for:

  • Payment gateways
  • Ads
  • Embedded widgets
  • External login pages

Why Frames Are Challenging

Elements inside frames belong to a different DOM context.

Automation scripts cannot directly access them from the main page.


Example Frame Structure

Main Page
   └── iframe
           └── Login form

The script must switch to the frame first.


Accessing Frames in Playwright

Playwright provides frameLocator().

Example HTML

<iframe id="login-frame">

Playwright code:

await page.frameLocator('#login-frame')
          .locator('#password')
          .fill('123456');

Handling Nested Frames

Sometimes frames contain other frames.

Example structure:

Main Page
   └── Frame 1
         └── Frame 2
               └── Element

Example:

page.frameLocator('#outer-frame')
    .frameLocator('#inner-frame')
    .locator('#submit')
    .click();

Listing All Frames

Example:

const frames = page.frames();
console.log(frames.length);

Finding Frame by Name

Example:

const frame = page.frame({ name: 'payment-frame' });

Finding Frame by URL

Example:

const frame = page.frame({ url: /payment/ });

Example Test – Login Inside Frame

test('Login inside iframe', async ({ page }) => {

  await page.goto('https://example.com');

  const frame = page.frameLocator('#login-frame');

  await frame.locator('#username').fill('admin');

  await frame.locator('#password').fill('password');

  await frame.locator('#login').click();

});

Best Practices for Frames

  1. Always identify frames first
  2. Use frameLocator() instead of manual switching
  3. Avoid XPath across frames
  4. Wait for frames to load

Leave a Comment

Your email address will not be published. Required fields are marked *