web-dev-qa-db-ja.com

Selenium WebDriver-要素がクリック可能かどうかを判断します(つまり、dojoモーダルライトボックスによって隠されていません)

私は、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は回避策になりますが、可能であれば適切なチェックを行うことをお勧めします。

17
Matthew

WebDriverWait条件を使用します。

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

Webdriverは、要素がクリックできるようになるまで5秒間待機します。

19
Pavel Zorin

ExpectedConditions.invisibilityOfElementLocated(By by)メソッドを使用すると、要素が非表示になるか、DOMに存在しなくなるまで待機します。

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

したがって、モーダルダイアログが非表示になるか、DOMから消えるまでの時間に応じて、webdriverは待機します。待機時間は最大10秒です。

6
sreeharimohan

要素がタイムアウトでクリック可能になるまでWebDriverを待機させるclickUntil関数/メソッドを作成できます。要素をクリックしようとし、クリックされるかタイムアウトになるまで、毎回「要素はクリックできません」というエラーメッセージを破棄します。

それを道場でどのように書くかわかりませんが、それはアイデアです。

2
bbbco

私も同じ問題を抱えていますが、サイトで多くの入力をテストしました。 1つは私がテストしたクリック可能なもので、もう1つはスキップしただけです。私は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
Bartosz Gurgul

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
nexoma