Selenium WebDriver - 确定元素是否可点击(即不被 dojo 模态灯箱遮挡)

问题描述 投票:0回答:6

我编写自动化脚本来测试大量依赖 ajax 的 Web 应用程序。例如,保存设置时会显示一个带有文本“

Saving...
”的模式对话框,而灯箱会使页面的其余部分变灰。

我的测试脚本试图在消息消失之前单击测试中的下一个链接。驱动 Firefox 时它几乎总是有效,但驱动 Chrome 时会显示以下错误:

Exception in thread "main" org.openqa.selenium.WebDriverException: Element is not clickable at point (99.5, 118.5). Other element would receive the click: <div class="dijitDialogUnderlay _underlay" dojoattachpoint="node" id="lfn10Dijit_freedom_widget_common_environment_Dialog_8_underlay" style="width: 1034px; height: 1025px; "></div> (WARNING: The server did not provide any stacktrace information)

发生这种情况是因为灯箱遮挡了我想要单击的元素。我想等待灯箱消失后再尝试单击链接。

检查灯箱是否不再存在并不是一个有效的解决方法,因为有时存在多个级别的模式对话框和灯箱,并且没有简单的方法来区分它们。

Selenium 中有没有办法检测元素是否可点击(没有其他元素遮挡它)? try/catch 将是一种解决方法,但如果可能的话,我更愿意进行适当的检查。

ajax selenium dojo webdriver
6个回答
20
投票

使用 WebDriverWait 条件。

    WebDriverWait wait = new WebDriverWait(yourWebDriver, 5);
    wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//xpath_to_element")));

Webdriver 将等待 5 秒才能单击您的元素。


6
投票

您可以使用

ExpectedConditions.invisibilityOfElementLocated(By by)
方法,该方法会一直等到元素不可见或不存在于 DOM 上。

WebDriverWait wait = new WebDriverWait(yourWebDriver, 10);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("yourSavingModalDialogDiv")));

因此,根据模式对话框变得不可见或脱离 DOM 所需的时间,webdriver 将等待。等待时间最长为 10 秒。


2
投票

您可以创建一个

clickUntil
函数/方法,让 WebDriver 等待,直到元素可点击并超时。它会尝试单击该元素,并每次都会丢弃“元素不可单击”错误消息,直到它被单击或超时。

不知道如何在道场中编写它,但这是一个想法。


0
投票

我也有同样的问题,但我在网站上测试了很多输入。一个是我测试过的可点击的,另一个是不可点击的,只是跳过了。我通过 try() catch() 做到了 简单的代码:

for(){ // for all my input
try {
    driver.findElement(By.xpath("...."
                                + "//input)["+(i+1)+"]")).click();

  ... tests...


} catch(Exception e) {
     if(e.getMessage().contains("is not clickable at point")) {

          System.out.println(driver.findElement(By.xpath(locator)).
          getAttribute("name")+" are not clicable");
     } else {
          System.err.println(e.getMessage());
     }
}

更优雅:

 @SuppressWarnings("finally")
       public boolean tryClick(WebDriver driver,String locator, locatorMethods m) {

           boolean result = false;
           switch (m) {

           case xpath:
            try {
                driver.findElement(By.xpath(locator)).click();
                result= true;
            } catch (Exception e) {
                   if(e.getMessage().contains("is not clickable at point")) {
                       System.out.println(driver.findElement(By.xpath(locator)).getAttribute("name")+" are not clicable");
                   } else {
                       System.err.println(e.getMessage());
                   }
            } finally {
                break;
            }
        case id:
            try {   
                driver.findElement(By.id(locator)).click();
                return true;
            } catch (Exception e) {
               if(e.getMessage().contains("is not clickable at point")) {
                   System.out.println(driver.findElement(By.id(locator)).getAttribute("name")+" are not clicable");   
               } else {
                   System.err.println(e.getMessage());
               }
            } finally {
                break;
            }

          default:
              System.err.println("Unknown locator!");

        }
           return result;
  }

0
投票

在 Scala 中:

  1. 标准等待代码(可见/不可见)

    (new WebDriverWait(remote, 45)).until(
        ExpectedConditions.visibilityOf(remote.findElement(locator))
    )
    Thread.sleep(3000)
    
  2. 日志中的更多可见性:

    while (remote.findElement(locator).isDisplayed) {
        println(s"isDisplayed: $ii $a : " + remote.findElement(locator).isDisplayed)
        Thread.sleep(100)
    }
    
  3. 如果您有异步 JavaScript 进程,请使用带有时间戳的 Web 元素:

    val oldtimestamp = remote.findElements(locator).get(0).getAttribute("data-time-stamp")
    
    while (oldtimestamp == remote.findElements(locator).get(0).getAttribute("data-time-stamp")) {
        println("Tstamp2:" + remote.findElements(locator).get(0).getAttribute("data-time-stamp"))
        Thread.sleep(200)
    }
    

0
投票

受到 sreeharimohan 回答的启发,我成功了:

WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "page-loading-overlay")))
WebDriverWait(driver, 10).until(EC.invisibility_of_element_located((By.ID, "page-loading-overlay")))
© www.soinside.com 2019 - 2024. All rights reserved.