Java Selenium优化getVisibleElement(当元素不存在时)

Java Selenium优化getVisibleElement(当元素不存在时),java,selenium,webdriver,selenium-webdriver,fluent,Java,Selenium,Webdriver,Selenium Webdriver,Fluent,我正在使用jBehave/Selenium进行自动化测试 现在,我使用以下代码获取页面上的可见元素 public WebElement getVisibleElement( final By by, final WebElement parentElement, int timeoutValue, TimeUnit timeoutPeriod, int pollingInterval, TimeUnit pollingPeriod ) { return fluentWait(tim

我正在使用jBehave/Selenium进行自动化测试

现在,我使用以下代码获取页面上的可见元素

public WebElement getVisibleElement( final By by, final WebElement parentElement, int timeoutValue, TimeUnit timeoutPeriod, int pollingInterval, TimeUnit pollingPeriod ) {
       return fluentWait(timeoutValue, timeoutPeriod, pollingInterval, pollingPeriod).until( new Function<WebDriver, WebElement>(){
                public WebElement apply(WebDriver driver) {
                    try{
                        WebElement element = parentElement.findElement(by);
                        if ( element.isDisplayed() ) {
                            return element;
                        } else {
                            return null;
                        }
                    } catch( NoSuchElementException e ) {}

                    return null; 
                }
        } );
    }
public WebElement getVisibleElement(final By By,final WebElement parentElement,int timeoutValue,TimeUnit timeoutPeriod,int pollingInterval,TimeUnit pollingPeriod){
return fluentWait(timeoutValue,timeoutPeriod,pollingInterval,pollingPeriod).until(new Function(){
公共WebElement应用(WebDriver){
试一试{
WebElement=parentElement.findElement(by);
if(element.isDisplayed()){
返回元素;
}否则{
返回null;
}
}catch(NoSuchElementException e){}
返回null;
}
} );
}
现在的问题是,如果元素不在页面上,Selenium会花费大量时间在页面上查找它。
是否有任何方法可以优化代码,使其在这种情况下不会花费很长时间?

首先,我认为您不应该通过调用findElement和捕获潜在异常来检查元素的存在。最好使用findElements并检查列表大小

公共WebElement getElementIfPresent(按定位器){
driver.manage().timeouts().implicitlyWait(100,TimeUnit.ms);
列表元素=driver.findElements(定位器);
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
如果(!elements.isEmpty()){
返回元素。get(0);
}
否则{
返回null;
}
}
问题是WebDriver将隐式地等待元素出现。因此,在执行上述代码之前,您可能希望通过将implicit WAITES time设置为较低的值来缩短该时间。在对可能不存在的元素执行任何查找之前,需要先执行dobe。然后需要恢复原始的隐式等待值,否则可能会影响其余测试的稳定性


最后,您只需使用
isDisplayed()
检查可见性,就像您在示例中所做的那样。

更优化的解决方案是使用
findelelements(locator).size()

    /**
     * Private method that acts as an arbiter of implicit timeouts of sorts.. sort of like a Wait For Ajax method.
     */
    private WebElement waitForElement(By by) {
        int attempts = 0;
        int size = driver.findElements(by).size();

        while (size == 0) {
            size = driver.findElements(by).size();
            if (attempts == MAX_ATTEMPTS) fail(String.format("Could not find %s after %d seconds",
                                                             by.toString(),
                                                             MAX_ATTEMPTS));
            attempts++;
            try {
                Thread.sleep(1000); // sleep for 1 second.
            } catch (Exception x) {
                fail("Failed due to an exception during Thread.sleep!");
                x.printStackTrace();
            }
        }

        if (size > 1) System.err.println("WARN: There are more than 1 " + by.toString() + " 's!");

        return driver.findElement(by);
    }
它的构建方式是,在对其进行操作之前先调用它。大概

WebElement myElement = waitforElement(By.cssSelector("input#someInput"));
myElement.sendKeys("something");

这是一个经过验证的解决方案,我已经在生产级回归测试系统中进行了测试并积极使用。

同样的主题在这里,我没有看到这种方法比
WebElement element=new WebDriverWait(driver,101000)有任何好处,直到(ExpectedConditions.presenceOfElementLocated(By.cssSelector(“#someElement”))Thx很多…我只是想知道我应该把代码的第二部分确切地放在哪里,即隐式等待…应该在检查…if(!elements.isEmpty()){}之前吗不,不是在isEmpty()之前。在调用findElement之前,在尝试查找元素(换句话说)之前需要检查它。我修改了我的答案,使之更清楚。