How to Check If 100% Covered WebElement is Clickab

2019-02-26 00:53发布

问题:

I have two divs with absolute position

<div id="4711" style="position:absolute;top:0px;bottom:0px;left:0px;right:0px;background-color:red">Visible later</div>
<div id="4712" style="position:absolute;top:0px;bottom:0px;left:0px;right:0px;background-color:green">To be removed</div>

and some Javascript (not shown here) that removes 4712 after a while (lets say after 2 seconds) from the DOM.

Now, in my Selenium tests I want to check if 4711 is clickable. From a user's perspective it is only clickable after 4712 has been removed.

So I tried

new WebDriverWait(browserInstance.getWebDriver(), 5).until(ExpectedConditions.elementToBeClickable(By.id("4711")));

However, 4711 is always clickable (enabled=true, displayed=true), even before 4712 is removed.

Is there any way how to check if 4711 is realy clickable, that is, clickable from a user's perspective (ideally without using Javascript)?

回答1:

Have you tried waiting for the invisibility of 4712 before checking the clickability of 4711. 4711 may still register as clickable while 4712 is still visible and that may be causing the issues.

new WebDriverWait(browserInstance.getWebDriver(), 5).until(!ExpectedConditions.elementToBeVisible(By.id("4712")));
new WebDriverWait(browserInstance.getWebDriver(), 5).until(ExpectedConditions.elementToBeClickable(By.id("4711")));


回答2:

As you mentioned, a Javascript removes the element 4712 it is a bit unclear if the element becomes stale or becomes invisible. So for this step you can use either of the following options:

  • stalenessOf():

    new WebDriverWait(browserInstance.getWebDriver(), 5).until(ExpectedConditions.stalenessOf(driver.findElement(By.id("4712"))));
    
  • invisibilityOfElementLocated():

    new WebDriverWait(browserInstance.getWebDriver(), 5).until(ExpectedConditions.invisibilityOfElementLocated(By.id("4712")));
    
  • not along with visibilityOfElementLocated()

    new WebDriverWait(browserInstance.getWebDriver(), 5).until(ExpectedConditions.not(ExpectedConditions.visibilityOfElementLocated(By.id("4712"))));
    
  • not along with presenceOfElementLocated()

    new WebDriverWait(browserInstance.getWebDriver(), 5).until(ExpectedConditions.not(ExpectedConditions.presenceOfElementLocated(By.id("4712"))));
    

For the next step you want to validate if element 4711 is clickable or not and you can use the following line of code:

new WebDriverWait(browserInstance.getWebDriver(), 5).until(ExpectedConditions.elementToBeClickable(By.id("4711")));

Note: An element's state as enabled=true and displayed=true isn't equivalent to element is interactable i.e. clickable