元素不可见异常 - 即使使用了不同的Selenium等待

时间:2016-02-24 07:54:30

标签: java selenium-webdriver wait

我正在尝试使用Selenium和Java自动化Web应用程序的功能测试。在我的应用程序中有几个菜单。单击特定菜单时,会显示子菜单下拉列表 click to view screenshot of menu

我使用下面的代码点击子菜单

driver.findElement(By.xpath("id=menu")).click();
driver.findElement(By.xpath("id=sub_menu_a")).click();

但问题是它在第二行抛出'ElementNotVisibleException'。即使我使用隐式等待

,也会发生同样的情况
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

显式等待

WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("id=sub_menu_a")));

和流利的等待。

Wait<WebDriver> fluentWait=new FluentWait<WebDriver>(driver)
                .withTimeout(60, TimeUnit.SECONDS)
                .pollingEvery(2, TimeUnit.SECONDS)
                .ignoring(NoSuchElementException.class,ElementNotVisibleException.class);
        WebElement element=fluentWait.until(new Function<WebDriver, WebElement>() {
            public WebElement apply(WebDriver driver){
                driver.findElement(By.xpath("id=menu"));
                return driver.findElement(By.xpath("id=sub_menu_a"));
            }
        });
        element.click();

但没有运气。但是如果使用

添加睡眠时间,代码工作正常
Thread.sleep(sleeptime);

第一行代码之前和之后。但它不是一个永久的解决方案,因为页面加载时间可能会有所不同,具体取决于网络速度和页面中的数据。还有其他解决方案吗?

5 个答案:

答案 0 :(得分:1)

尝试使用Actions类,看看它是否有效......

driver.findElement(By.xpath("id=menu")).click(); 
WebElement subMenu=driver.findElement(By.xpath("id=sub_menu_a"));   
Actions myaction = new Actions(driver);
myaction.moveToElement(subMenu);
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.elementToBeClickable(subMenu));
myaction.click().perform();

答案 1 :(得分:1)

试试这个

    WebElement menu=driver.findElement(By.xpath("id=menu"));
    JavascriptExecutor executor = (JavascriptExecutor)driver;
    executor.executeScript("arguments[0].click();", menu);
    WebElement subMenu=driver.findElement(By.xpath("id=sub_menu_a"));
    executor.executeScript("arguments[0].click();", subMenu);

希望这项工作

答案 2 :(得分:0)

流利的等待应该可以正常工作。 尝试使用这样的东西:

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(10, TimeUnit.SECONDS).ignoring(NoSuchElementException.class);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("id=sub_menu_a")));

但我会选择css选择器,它们非常适合HTML页面。

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(10, TimeUnit.SECONDS).ignoring(NoSuchElementException.class);
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#sub_menu_a")));

或者如果您的 sub_menu_a 菜单的孩子,我会选择

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(10, TimeUnit.SECONDS).ignoring(NoSuchElementException.class);
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#menu #sub_menu_a")));

答案 3 :(得分:0)

你可以试试吗?

WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("id=sub_menu_a")));

如果你能给html找到合适的xpath会更好,因为我认为更好的XPATH会产生点击子菜单的结果。

答案 4 :(得分:0)

很久以前我有类似的问题(不记得确切的情况,所以确实你的HTML页面剪切会有帮助)所以我被迫使用Thread.sleep() 为避免长时间等待会提出类似这种方法:

static void waitAndClick(WebDriver driver, By by, int attempts, int sleep) throws InterruptedException {
    for (int i = 0; i < attempts; i++) {
        WebElement element = null;
        try {
            element = driver.findElement(by);
        } catch (NoSuchElementException e) {
            // Do nothing
        }
        if (element == null) {
            int time = sleep * (i + 1);
            Thread.sleep(time);
        } else {
            element.click();
            break;
        }
    }
    throw new NoSuchElementException("Error");
}

它不是100%完整的解决方案,而只是一个想法。