How to handle random modal windows in Selenium

Many sites use modal windows for sales events, announcements and user surveys.

Especially in the last 2 months of the year when there are so many holidays (Christmas, New Year’s Eve, Boxing Day).

1

A modal is an HTML element that is displayed above the current page.

It includes

  • title
  • description
  • action button (take a survey, visit on sale section, etc)
  • close button

The user cannot interact with the main page until the modal is closed.

Modals can be a problem for test automation scripts.

If the modal is displayed consistently on a page, it is easy for the automation script to interact with it (take the action suggested by the modal or close it).

But if the modal is displayed randomly, the test automation script needs to be able to deal with the modal when displayed and not displayed.

How do we interact with random modal windows?

Let’s see how to do it for a simple web page.

The web page displays initially a button:

2

When clicking the button, the modal is not displayed some times.

In these cases, the page displays the “popup not displayed” and “done” messages:

3

Other times, when clicking the button, the modal is displayed:

4

After closing the modal, the page displays “done”.

5

The sample code consists in 3 classes:

  • test class – includes setUp() and tearDown() methods and the test script
  • main class – implements the interactions with the main page
  • popup class – implements the interaction with the popup

TEST CLASS

import static org.testng.AssertJUnit.assertTrue;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class TestClass {

WebDriver driver;

@BeforeMethod
public void setUp()
{
driver = new ChromeDriver();
System.setProperty("webdriver.chrome.driver",
"C:\\Selenium\\chromedriver.exe");
}

@AfterMethod
public void tearDown() {
driver.quit();
}

@Test(invocationCount = 10)
public void testRandomPopup() {
MainPage mainPage = new MainPage(driver);
mainPage.open();

Popup popup = mainPage.displayPopup();
popup.close();

assertTrue(mainPage.done().equalsIgnoreCase("done"));
}

}

The test script does the following

  • opens the main page
  • clicks the button that may display the popup
  • closes the popup; if the popup is displayed, then it is closed; if the popup is not displayed, nothing happens
  • asserts that the work is done

MAIN PAGE CLASS

 
import org.openqa.selenium.By;
import org.openqa.selenium.NotFoundException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
 
public class MainPage {
 
  private final WebDriver driver;
  private final By doneStatusId = By.id("done");
  private final By displayPopupId = By.id("displayPopup");
 
  public MainPage(WebDriver driver) {
    this.driver = driver;
  }
 
  public void open() throws InterruptedException {
    driver.get("file:///C:/Users/home/Desktop/modal.html");
 
    if (driver.getTitle().contains("Test Random Popup") == false)
        throw new NotFoundException("main page not displayed");
  }
 
  public String done() {
    WebElement doneLabel = driver.findElement(doneStatusId);
    return doneLabel.getText();
  }
 
  public Popup displayPopup() {
    WebElement displayButton = driver.findElement(displayPopupId);
    displayButton.click();
 
    return new Popup(driver);
  }
 
}

The MainPage class has the following methods:

  • open() – opens the page and checks that the opened page is the correct one
  • displayPopup() – clicks the button that may display the popup
  • done() – returns the message displayed after the popup is handled

POPUP CLASS

 
import org.openqa.selenium.By;
import org.openqa.selenium.InvalidElementStateException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import static org.openqa.selenium.support.ui.ExpectedConditions.*;
import org.openqa.selenium.support.ui.WebDriverWait;
 
public class Popup {
 
  private final WebDriverWait wait;
  private final By closeElementLocator = By.id("closePopup");
  private final By popupIdLocator = By.id("popupId");
 
  public Popup(WebDriver driver) {
    this.wait = new WebDriverWait(driver, 5);
  }
 
  public void close() throws InterruptedException {
    if (isDisplayed()) {
        WebElement closeElement = wait.until(
               visibilityOfElementLocated(closeElementLocator));
        closeElement.click();
    }
  }
 
  private Boolean isDisplayed() throws InterruptedException {
     try {
        WebElement popup = wait.until(
                visibilityOfElementLocated(popupIdLocator));
        return popup.isDisplayed();
     }
     catch (Exception ex) {
       return false;
     }
 }
}

The popup class has 2 methods:

1. isDisplayed()

This is the most important method for managing the random modal.

It tries finding the modal element.

If the modal element is found, isDisplayed() returns true if modal is displayed and false otherwise.

If the popup is not displayed, an exception is thrown.

The exception is caught and isDisplayed() returns false;

2. close()

It closes the popup if it is displayed.

Thanks for reading.

Want to get started with Selenium WebDriver and Java in 10 short lessons?

Advertisements