Java 等待图元可见性后超时

Java 等待图元可见性后超时,java,selenium,selenium-webdriver,Java,Selenium,Selenium Webdriver,我在旅行搜索网站上选择航班返回日期时遇到了麻烦。有时它是有效的,但大多数时候它不是,我在这一点上相当困惑。我收到的错误是:线程main org.openqa.selenium.TimeoutException中的异常:等待by.id:ui-datepicker div定位的元素的可见性20秒后超时 我已经为要单击的日期元素设置了一些等待语句,但仍然收到一个错误。我正试图找到一个解决方案,避免使用Thread.sleep。任何帮助都将不胜感激 这是我的剧本: public class DatePi

我在旅行搜索网站上选择航班返回日期时遇到了麻烦。有时它是有效的,但大多数时候它不是,我在这一点上相当困惑。我收到的错误是:线程main org.openqa.selenium.TimeoutException中的异常:等待by.id:ui-datepicker div定位的元素的可见性20秒后超时

我已经为要单击的日期元素设置了一些等待语句,但仍然收到一个错误。我正试图找到一个解决方案,避免使用Thread.sleep。任何帮助都将不胜感激

这是我的剧本:

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

关于元素的可见性,需要记住几件事

可见与当前的元素不同。如果您查找错误的子元素或对象中实际不可见的部分,这可能会给您带来麻烦。您可能希望尝试使用元素的presenceofelementlocated,或者尝试使用另一个可能是可见部分的元素

有时,同一页上的元素常常具有相同的标识符。如果您使用findElement,并且大多数事情都是这样做的,那么它只会得到它找到的第一个。如果这一个是隐藏的,你可以等待一整天,它将永远不可见。尝试使用By.cssSelector帮助更具体地选择对象。例如:

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

您还可以创建一个findDisplayedElement函数。这可能会查找元素并遍历它们,直到找到一个元素。isDisplayed=true

关于元素的可见性,需要记住几件事

可见与当前的元素不同。如果您查找错误的子元素或对象中实际不可见的部分,这可能会给您带来麻烦。您可能希望尝试使用元素的presenceofelementlocated,或者尝试使用另一个可能是可见部分的元素

有时,同一页上的元素常常具有相同的标识符。如果您使用findElement,并且大多数事情都是这样做的,那么它只会得到它找到的第一个。如果这一个是隐藏的,你可以等待一整天,它将永远不可见。尝试使用By.cssSelector帮助更具体地选择对象。例如:

[class*='exampleContainer'] [id='ui-datepicker-div']
您还可以创建一个findDisplayedElement函数。这可能会查找元素并遍历它们,直到找到一个元素。isDisplayed=true

我发现了一些问题:

离开日期是一个div,你不应该点击它,而是点击我看到一些问题:


Deep_date是一个div,您不应该点击它,而是点击我在使用Selenium的过程中注意到,有时我的显式等待会出现xpath元素问题,而driver.findelee在查找它时没有问题。我还注意到,尽管我尽量不使用By.cssSelector,但是By.cssSelector似乎总能解决我的显式应用程序中那些令人讨厌的超时问题。所以我同意恰克的观点。如果从显式等待中的xpath元素超时,请尝试使用By.cssSelector。您可能会感到惊讶。

在使用Selenium的过程中,我注意到有时候我的显式等待会出现xpath元素问题,而driver.findelee在查找它时没有问题。我还注意到,尽管我尽量不使用By.cssSelector,但是By.cssSelector似乎总能解决我的显式应用程序中那些令人讨厌的超时问题。所以我同意恰克的观点。如果从显式等待中的xpath元素超时,请尝试使用By.cssSelector。你可能会感到惊讶

...
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);
}
...
public void isCalendarVisible() {
    try {
        WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("ui-datepicker-div")));
        return true;
    } catch (TimeOutException e) {
        return false;
}
// wait for calendar interface to appear
if(!isCalendarVisible()) {
    // try to reopen calendar
    driver.findElement(By.id("depart")).click();
}
Integer.toString(year);
Integer.toString(month);
Integer.toString(day);