selenium 驱动程序单击项目然后重定向到新页面并尝试查找上一页的相同项目

selenium driver clicks item then redirected to new page and tries to find same item of previous page

检查我用来等待 selenium webdriver 中元素的方法的代码 我这样称呼它 waitForElement(By.id(idOfElement));

public void waitForElement(By by) {
    for (int second = 0;; second++) {
        //System.out.println("seconds : " + second);
        if (second >= 15) {
            System.out.println("element not found");
            break;
        }
        try {
            if (driver.findElement(by).isDisplayed()) {
                driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS); 
                //System.out.println("found element before click");
                driver.findElement(by).click();
                //System.out.println("found element after click");
                return;
            }
        } catch (Exception e) {
//              e.printStackTrace();
            //System.out.println("inside exception");
        }
    }
    //System.out.println("click on element after being not found");
    driver.findElement(by).click();
}

此方法应该找到元素并点击它

它工作正常,它应该从方法中单击元素然后 return 但现在它失败了,因为驱动程序单击重定向到另一个页面的元素并且在新页面出现驱动程序而不是 return从方法进入捕获异常,最后代码失败,因为驱动程序试图找到上一页中的元素

对修复此方法有什么帮助吗?

更新:第一次点击后有一个return 如果找到该元素,它应该退出该方法这里的问题是有时执行代码会找到该元素并单击它并且在第一次单击后不会到达代码(即 return;) 我使用这种方法来避免未找到元素的异常,因为有时我使用等待并且元素存在但代码失败,因为未找到元素或因为异常说 "time out receiving message from renderer"

您的问题似乎是因为您没有将驱动程序切换到新页面。 所以如果按页面你的意思是:

  • 一个新的 window : check this out
  • 新标签页:check there

那个方法太可怕了。您有很多不需要的代码,一个不需要的 try|catch,如果没有抛出错误,您将尝试单击该元素两次。

我建议这样重写:

WebDriverWait wait = new WebDriverWait(driver, 15, 100);
WebElement myElement = wait.until(ExpectedConditions.elementToBeClickable(By.id("my-id")));
myElement.click();

这使用了 selenium 支持包中提供的 ExpectedConditions class:

import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

上面的代码将创建一个 Web 驱动程序等待对象,该对象最多等待 15 秒直到条件变为真。每 100 毫秒检查一次条件。预期条件将 return 元素解析为真时(在这种情况下,我们正在等待元素变得可点击,因为您想点击它)。

定义等待对象后,您可以针对不同的条件一次又一次地重用该等待对象,这样您就不需要每次都重新初始化它。例如:

WebDriverWait wait = new WebDriverWait(driver, 15, 100);
WebElement myElement = wait.until(ExpectedConditions.elementToBeClickable(By.id("my-id")));
myElement.click();
WebElement anotherElement = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("another-element")));
//TODO do something with another element

您还可以设置描述等待时间的等待名称:

WebDriverWait fifteenSecondWait = new WebDriverWait(driver, 15, 100);
WebDriverWait fiveSecondWait = new WebDriverWait(driver, 5, 100);

我建议永远不要在代码中使用 implicitlyWait,而是始终使用显式等待。混合显式和隐式等待可能会产生意想不到的后果,如果您忘记取消设置隐式等待,当您检查是否有东西存在时,您的测试会变得非常慢。