有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我正在尝试使用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) 个答案

  1. # 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();
    
  2. # 2 楼答案

    你能试试吗

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

    另外,如果你能通过html找到正确的xpath,那就更好了,因为我认为更好的xpath会产生点击子菜单的结果

  3. # 3 楼答案

    流畅的等待应该很好。 试着用这样的方法:

    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")));
    

    或者如果你的子菜单是菜单的孩子,我会选择

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

    试试这个

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

    希望这能奏效

  5. # 5 楼答案

    很久以前,我也有类似的问题(不记得确切的情况,所以你的HTML页面被剪掉会很有帮助),所以我不得不使用线程。睡眠() 为了避免长时间等待,我们将提出以下方法:

    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%完整的解决方案,只是一个想法