我使用selenium来测试AngularJS应用程序。我面临的问题是,在完全加载之前,我无法在页面上执行任何操作。我可以把Thread.sleep(),但这不是我所知道的好解决方案。有很多方法可以等到页面加载(我谷歌它),但我想我尝试了所有这些仍然没有运气。在我的应用程序中,当转到网页时,所有内容看起来都是加载的(从可视角度来看),但在完整页面加载(大约1秒)之前我无法进行任何活动。 你们可以分享你的实施方式吗?你实际上是如何工作的
谢谢
我的代码:
public By ngWait(final By by) {
return new FluentBy() {
@Override
public void beforeFindElement(WebDriver driver) {
driver.manage().timeouts().setScriptTimeout(30, TimeUnit.SECONDS);
((JavascriptExecutor) driver).executeAsyncScript("var callback = arguments[arguments.length - 1];" +
"angular.element(document.body).injector().get('$browser').notifyWhenNoOutstandingRequests(callback);");
super.beforeFindElement(driver);
}
@Override
public List<WebElement> findElements(SearchContext context) {
return by.findElements(context);
}
@Override
public WebElement findElement(SearchContext context) {
return by.findElement(context);
}
@Override
public String toString() {
return "ngWait(" + by.toString() + ")";
}
};
}
答案 0 :(得分:3)
我在使用selenium对角应用程序编写测试时遇到了类似的情况。实际上,在角度应用程序中,页面的骨架或视图会立即加载,但它会在后台调用$http
请求以获取数据。一旦角度应用程序完成$http
调用,它就会以$ http call的响应呈现视图。因此,像waitUntilPageToBeLoad
那样经常等待硒,waitUntilElementToBeClickable
根本不起作用。另一个解决方案是拥有Thread.Sleep()
,但正如您所提到的,这不是一个智能等待。
那么为什么没有等待方法来确保$http
调用在后台完成。你可以尝试下面的等待方法,它对我有用。我希望它也适合你!
public void untilAngularFinishHttpCalls() {
final String javaScriptToLoadAngular =
"var injector = window.angular.element('body').injector();" +
"var $http = injector.get('$http');" +
"return ($http.pendingRequests.length === 0)";
ExpectedCondition<Boolean> pendingHttpCallsCondition = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript(javaScriptToLoadAngular).equals(true);
}
};
WebDriverWait wait = new WebDriverWait(driver, 20); // timeout = 20 secs
wait.until(pendingHttpCallsCondition);
}
答案 1 :(得分:1)
抱歉,我还不能发表评论,所以这是我的帮助作为答案。
关于对Priyanshu Shekhar的回答的评论错误,所有这意味着jqLite(Angular的基本jquery版本)不足以完成该代码试图做的事情。
在页面中包含完整的jquery版本可以解决这个问题。