2012-03-26 21 views
14

Ich schreibe automatisierte Skripte zum Testen von Web-Anwendungen, die sehr schwer auf Ajax sind. Zum Beispiel wird beim Speichern der Einstellungen ein modaler Dialog mit dem Text "Saving..." angezeigt, während ein Leuchtkasten den Rest der Seite ausgraut.Selenium WebDriver - Bestimmen, ob Element anklickbar ist (d. H. Nicht durch Dojo-Modal Lightbox verdeckt)

Meine Testskripte versuchen, auf den nächsten Link im Test zu klicken, bevor die Nachricht verschwindet. Es funktioniert fast immer, wenn Firefox fahren, aber wenn Chrome die folgenden Fehler Fahren angezeigt:

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) 

Dies geschieht, weil die Leuchtkasten das Element verschleiern ich klicken Sie möge. Ich möchte warten, bis der Leuchtkasten verschwindet, bevor ich versuche, auf den Link zu klicken.

Die Überprüfung, ob die Lightbox nicht mehr existiert, ist kein gültiger Workaround, da es manchmal mehrere Ebenen von modalen Dialogen und Lightboxen gibt und es keine einfache Möglichkeit gibt, zwischen ihnen zu unterscheiden.

Gibt es eine Möglichkeit im Selenium zu erkennen, ob das Element anklickbar ist (keine anderen Elemente verdecken es)? Ein Versuch/Catch wäre ein Workaround, aber ich würde lieber eine ordnungsgemäße Überprüfung durchführen, wenn das möglich ist.

Antwort

18

Verwenden Sie die WebDriverWait-Bedingungen.

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

WebDriver wird für 5 Sekunden warten, bis Ihr Element in der Lage sein, angeklickt werden.

+14

Letztes Mal habe ich es mit Chrome versucht, es hat nicht funktioniert: die "klickbaren" Bedingung erfüllt ist obwohl andere Ebenen den Klick blockieren. – anttix

+3

funktioniert nicht mit Firefox 20, selen-firefox-driver 2.31.0. Das ElementToBeClickable gibt true zurück, wenn das Element durch einen modalen Dialog blockiert wird. – skong

+0

Es gibt nichts zu Firefox 20 in den Versionshinweisen zu 2.31. Funktioniert es in Firefox 19? –

2

Sie könnten eine clickUntil Funktion/Methode erstellen, die einen WebDriver wartet, bis das Element mit einem Timeout klickbar ist. Es würde versuchen, auf das Element zu klicken und die Fehlermeldung "Element ist nicht anklickbar" jedes Mal wegzuwerfen, bis es angeklickt wird oder abläuft.

Nicht sicher, wie man das im Dojo schreibt, aber das ist eine Idee.

6

Sie können die Methode ExpectedConditions.invisibilityOfElementLocated(By by) verwenden, die wartet, bis das Element entweder unsichtbar oder nicht im DOM vorhanden ist.

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

Also, je nachdem, wie viel Zeit Ihr Modal-Dialog braucht, um unsichtbar zu werden oder aus dem DOM gehen, wird der Webdriver warten. Die Wartezeit beträgt maximal 10 Sekunden.

0

In Scala:

  1. Standardcode für Warte (Sichtbarkeit/Unsichtbarkeit)

    (new WebDriverWait(remote, 45)).until(
        ExpectedConditions.visibilityOf(remote.findElement(locator)) 
    ) 
    Thread.sleep(3000) 
    
  2. Mehr Sichtbarkeit in Protokollen:

    while (remote.findElement(locator).isDisplayed) { 
        println(s"isDisplayed: $ii $a : " + remote.findElement(locator).isDisplayed) 
        Thread.sleep(100) 
    } 
    
  3. Wenn Sie asynchrone JavaScript Prozesse Verwenden Sie Web-Elemente mit Zeitstempel:

    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

Ich habe auch dieselben Probleme, aber ich viele Eingang in Ort getestet. Einer ist anklickbar was ich getestet habe und andere - nicht anklickbar wurde einfach übersprungen.Ich habe es durch try() catch() Einfach Code:

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()); 
    } 
} 

und eleganter:

@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; 
    } 
Verwandte Themen