2016-04-19 11 views
1

Ich habe Probleme mit der konsequenten Auswahl des Flug-Rückreisedatums von einer Reisesuch-Website. Manchmal funktioniert es, aber die meiste Zeit nicht und ich bin an dieser Stelle ziemlich ratlos. Der Fehler, den ich erhalte, ist: Exception in thread "main" org.openqa.selenium.TimeoutException: Timed out after 20 seconds waiting for visibility of element located by By.id: ui-datepicker-divTimeout nach Warten auf Sichtbarkeit des Elements

Ich habe einige Warteanweisungen für die Datumselemente eingerichtet, auf die ich klicke, aber ich erhalte immer noch einen Fehler. Ich versuche eine Lösung zu finden, bei der ich Thread.sleep vermeiden kann. Jede Hilfe würde sehr geschätzt werden!

Hier ist mein Skript:

public class DatePickerTest { 
    private static WebDriver driver = new FirefoxDriver(); 
    static WebDriverWait wait = new WebDriverWait(driver, 20); 

    public static void main(String[] args) {  
     driver.get("http://lowfares.com"); 
     selectDepartDate(2016, 5, 18); 
     selectReturnDate(2016, 5, 21); 
    } 

    public static void selectDepartDate(int year, int month, int day) { 
     month--; // replacing zero based index 
     Integer.toString(year); 
     Integer.toString(month); 
     Integer.toString(day); 

     wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("depart_date"))); 

     // click on text box to open up date picker calendar 
     driver.findElement(By.id("depart_date")).click(); 

     // close pop up window 
     String parentWindowHandler = driver.getWindowHandle(); 
     String subWindowHandler = null; 
     Set<String> handles = driver.getWindowHandles(); 
     Iterator<String> iterator = handles.iterator(); 
     while (iterator.hasNext()) { 
      subWindowHandler = iterator.next(); 
     } 
     driver.switchTo().window(subWindowHandler); 
     driver.close(); 
     driver.switchTo().window(parentWindowHandler); 

     // wait for calendar interface to appear 
     wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("ui-datepicker-div"))); 

     // select depart date 
     driver.findElement(By.xpath("//td[contains(@data-month, " + month + ") and contains(@data-year, " + year + ")]//a[contains(text(), " + day + ")]")).click(); 
    } 

    public static void selectReturnDate(int year, int month, int day) { 
     month--; // replacing zero based index 
     Integer.toString(year); 
     Integer.toString(month); 
     Integer.toString(day); 

     wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("return_date"))); 

     // click on text box to open up date picker calendar 
     driver.findElement(By.id("return_date")).click(); 

     // wait for calendar interface to appear 
     wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("ui-datepicker-div"))); 

     // select return date 
     driver.findElement(By.xpath("//td[contains(@data-month, " + month + ") and contains(@data-year, " + year + ")]//a[contains(text(), " + day + ")]")).click(); 
    } 
} 

Antwort

2

ich ein paar Probleme sehen:

  1. depart_date ist ein div, sollten Sie nicht darauf klicken, klicken Sie stattdessen auf <input id="depart":

    driver.findElement(By.id("depart")).click(); 
    
  2. Nicht sicher, was Popup-Fenster tut (ich habe kein Popup erhalten). In jedem Fall, überprüfen Sie zuerst, dass Popup-Fenster war wirklich da:

    ... 
    Set<String> handles = driver.getWindowHandles(); 
    for (String windowHandle : handles) { 
        subWindowHandler = windowHandle; 
    } 
    if(subWindowHandler != null && !subWindowHandler.equals(parentWindowHandler) { 
        driver.switchTo().window(subWindowHandler); 
        driver.close(); 
        driver.switchTo().window(parentWindowHandler); 
    } 
    ... 
    
  3. Wenn Sie Pop-up schließen tat, und wechselte zurück in das Hauptfenster, müssen Sie sicherstellen Kalender machen, ist noch offen; wenn nicht, öffnen Sie es erneut:

    public void isCalendarVisible() { 
        try { 
         WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("ui-datepicker-div"))); 
         return true; 
        } catch (TimeOutException e) { 
         return false; 
    } 
    

    und dann unter

    // wait for calendar interface to appear 
    if(!isCalendarVisible()) { 
        // try to reopen calendar 
        driver.findElement(By.id("depart")).click(); 
    } 
    
  4. Ordentlich-Picking: die folgenden nicht alles tun:

    Integer.toString(year); 
    Integer.toString(month); 
    Integer.toString(day); 
    
1

Ein paar Dinge im Auge mit Sichtbarkeit eines Elements zu halten.

Sichtbar ist anders als das vorhandene Element. Dies kann Sie in Schwierigkeiten bringen, wenn Sie nach dem falschen Unterelement oder Teil des Objekts suchen, das nicht wirklich sichtbar ist. Sie können versuchen, presenceOfElementLocated(by) oder versuchen Sie ein anderes Element, das möglicherweise ein sichtbarer Teil.

Manchmal (ziemlich oft) Elemente auf der gleichen Seite haben die gleichen Kennungen. Wenn Sie findElement verwenden (und die meisten Dinge tun), erhält es nur das erste, das es findet. Wenn dieser versteckt ist, können Sie den ganzen Tag warten und es wird nie sichtbar sein. Versuchen Sie es mit By.cssSelector, um Objekte spezifischer auszuwählen. Beispiel:

[class*='exampleContainer'] [id='ui-datepicker-div'] 

Sie könnten auch eine findDisplayedElement() Funktion erstellen. Dies könnte findElements() und durchlaufen sie, bis es findet man, dass element.isDisplayed() = true;

0

ich durch bemerkt haben Meine Reise mit Selenium, die manchmal mein Explicit wartet, hat Probleme mit xpath Elementen, während die driver.findElement hat keine Probleme, es zu finden. Ich habe auch bemerkt, dass, obwohl ich versuche, von der Verwendung By.cssSelector weg zu bleiben, dass By.cssSelector immer scheint, diese lästigen Auszeiten von meinem ausdrücklichen zu beheben. Also stimme ich Chuck zu. Wenn Ihr Zeitlimit von einem xpath Element innerhalb Ihres expliziten Wartens ist, versuchen Sie es mit einem By.cssSelector. Sie werden überrascht sein.

Verwandte Themen