1

I do have a Select and I try to wait patiently for it to be available, but that won't do.

    WebDriverWait wait = new WebDriverWait(getWebDriver(), 20);
    WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("myxpath")));
    Select select = new Select(element);
    select.selectByVisibleText(text);

When I run the code on this particular Element I get an error message:

... is not clickable at point (1311,183) because another element <p class="ng-tns-c4-0"> obscures it

I suppose this is because the page has these annoying status messages showing on the upper right corner for some seconds and then fading away. Though they are far away from my dropdown, they still seem to obscure it.

The whole thing works if I add a 2 second explicit wait, but that somehow offends my sense of stile and I most likely would end up spreading them all over the tests and slow them down a lot.

Is there any generic way of waiting for an element not to be obscured? I mean a way without having to know which particular message pops in.

POSTSCRIPT: Since I cannot add an answer on my own, I add this postscript. In the end I have settled for this solution:

protected void secureSelect(String text, Select select) {
    try {
        select.selectByVisibleText(text);
    } catch(ElementClickInterceptedException e) {
        Wait.seconds(2);
        select.selectByVisibleText(text);
    }
}

I know that these problems will occur all over the application with different messages of the same type. So in case of an error I just try once again and the let it fail if it goes wrong again.

Jefe infiltrado
  • 364
  • 2
  • 15

1 Answers1

1

To answer your last question, is there a generic way of waiting for an element to not be obscured? Outside of elementToBeClickable, not really. Web pages are dynamic and each one of them loads content differently so there's not exactly a catch-all for this. It is unfortunate that elementToBeClickable is encountering a ClickIntercepted error for your scenario, but there are a few workarounds.

You could try adding an additional wait to wait on invisibilityOfAllElements for the status messages that keep popping up, if these are what is getting in the way:

wait.until(ExpectedConditions.invisibilityOfAllElements(By.xpath("//p[contains(@class, 'ng-tns')]")));

This may encounter a timeout exception depending on the nature of displayed p elements compared with the rest of the page content. Another possible workaround would be leaving your code as it, and using Javascript to select elements from the Select instead:

WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("myxpath")));

JavascriptExecutor js = (JavascriptExecutor)driver; 

// expand the Select dropdown
js.executeScript("arguments[0].click();", element);

// wait for Select options menu to expand
WebElement optionToClick = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("xPathForDropdownOption")));

// select desired option
js.executeScript("arguments[0].click();", optionToClick);

The above code is a bit more 'explicit' in what we are waiting on -- specifically, the dropdown option value. Clicking both the Select dropdown and the dropdown option with Javascript are meant to be workarounds for the ClickIntercepted error.

CEH
  • 5,701
  • 2
  • 16
  • 40