5

Problem

I am writing automated tests for my company's website using Java and Selenium. Right now I am writing tests that involve clicking on links, and verifying that the link leads to the correct place. We have a newsletter popup (from BounceExchange) that appears at very unpredictable times, and it's causing ElementClickInterceptedExceptions. This is the exception message:

org.openqa.selenium.ElementClickInterceptedException: element click intercepted: Element <li id="menu-item-78096" ... is not clickable at point (x, x). Other element would receive click <div class="bx-slab">...</div>

What I've Tried

Clicking with JavaScript

I have been clicking WebElements with driver.findElement(By...).click(), which I've read is the best way to click things when testing UI. I have tried doing a JavaScript click like this but that hasn't worked, and the page just hangs with the popup on screen.

Closing the Popup

This is the area where I have had the most success, but it still doesn't fully work. This is my click method:

public void click(By elementBy) {
        By bounceExchange = By.className("bx-slab");
        By bounceExchangeClose = By.className("bx-close");

        //close bouncex if its open
        if(elementExists(bounceExchange)) {
            WebElement bounceX = driver.findElement(bounceExchange);
            if(bounceX.isDisplayed()) {
                System.out.println("Closing bounce exchange");
                try {
                    driver.findElement(bounceExchangeClose).click();
                }
                catch(Exception e) {
                    //ignore
                }
            }
        }


        driver.findElement(elementBy).click();
    }

From looking at the HTML, I know that the close button on the popup has a class "bx-close". This method sometimes successfully closes the popup, but then link that is being tested is never clicked, and the test fails.

Pressing Escape

I have learned that pressing the escape key while the popup is on screen makes it go away. I have tried two ways to do this 1. Using Actions

Actions actions = new Actions(driver);
actions.keyDown(Keys.ESCAPE).build().perform();
actions.keyUp(Keys.ESCAPE).build().perform();

But this way was giving me an illegal argument error since the escape key is not a modifier key.

And I have tried WebDriver's sendKeys:

driver.findElement(By.tagName("html")).sendKeys(Keys.Escape);

This approach also did not work for me.

HTML of Popup

<div class="bx-slab">
  <div class="bx-align">
    <div class="bx-creative bx-creative-874700" id="bx-creative-874700">
      <div class="bx-wrap">
        <a id="bx-close-inside-874700" class="bx-close bx-close-link bx-close-inside" href="javascript:void(0)" data-click="close">
          <svg class="bx-close-xsvg" viewBox="240 240 20 20">..</svg>
        </a>
   ...
</div>

So my question is, what is a reliable way to close this unpredictable popup so I can stop getting ElementClickInterceptedExceptions?

  • can you share html code? – Pratik Dec 04 '19 at 20:34
  • 1
    you'll probably want to use a WebDriverWait with an expected condition for the close button to appear. It'll poll every 1/2 second until it is found or a timeout period is reached. You could also call your method from the catch block. (click intercepted exception) – pcalkins Dec 04 '19 at 20:36
  • 1
    It's possible the button you have located & wish to click is not the element you think it is. Try running `driver.findElements(...)` and print the length of the resulting list. If it is more than 1, then that may be your problem here. – CEH Dec 04 '19 at 21:06

2 Answers2

2

For popups that come up at unexpected times during your execution, event handlers are the way to go. The idea is to wrap your regular driver with an EventFiringWebDriver which then lets you register handlers on certain events; of which there are many to choose from. Creating the EventFiringWebDriver is fairly simple:

EventFiringWebDriver eventDriver = new EventFiringWebDriver(driver);
EventHandler handler = new EventCaptures();
eventDriver.register(handler);
// Do stuff here
eventDriver.unregister(handler);

The handler is a method that you will implement in a separate class, derived from WebDriverEventListener, which overrides one of the base methods from that class. There are many to choose from, but a good one for this case might be beforeClickOn. Here is a sample of how that would look:

public class EventCaptures implements WebDriverEventListener{
  @Override
  public void beforeClickOn(WebElement arg0, WebDriver arg1) {
    By bounceExchangeClose = By.className("bx-close");
    if (arg1.findElements(bounceExchangeClose).size() > 0) {
      arg1.findElement(bounceExchangeClose).click();
    }       
  }
  // Other listener overrides here...
}

So basically whenever you go to click on something, that handler will run and check to make sure the pop up isn't there (and if it is, close it). Others have mentioned waits and checks, however this gets very messy if the popup is unpredictable as you then have to call that check all over the place in your code, where as with this method it happens automatically. Simply unregister the handler when you're done using it.

For more info, this is a good resource: https://www.softwaretestingmaterial.com/webdriver-event-listeners/

0

Thank you everyone for your answers and comments.

Christine's comment helped me to solve my problem.

It's possible the button you have located & wish to click is not the element you think it is. Try running driver.findElements(...) and print the length of the resulting list. If it is more than 1, then that may be your problem here.

I found that I was finding 2 elements that have the "bx-close" class. I changed the way I locate the close button by making it specific to the actual button that needs to be pressed, and it appears my probelm is solved.