Selenium和Angularjs等到执行一些操作 [英] Selenium and Angularjs wait until to do some actions
问题描述
我正在使用硒来测试AngularJS应用程序.我遇到的问题是,在页面完全加载之前,我无法在页面上执行任何操作.我可以放入Thread.sleep(),但这并不是我所知道的好解决方案.有很多方法可以等到页面被加载(我用谷歌搜索),但是我想我尝试了所有方法,但还是没有运气.在我的应用程序中,当转到网页时,所有内容看上去都已加载(从视觉角度来看),但是直到整页加载(大约1秒)后,我才能进行任何活动. 你们能分享您的实施过程,您是如何做到的?
I'm using selenium to test AngularJS application. I'm facing issue that I cannot do any actions on the page until it loads fully. I can put Thread.sleep(), but this is not good solution as I know. There many ways to wait until page will be loaded(I google it), but I think I tried them all and still no luck. In my applications when go to webpage, everything looks loaded(from visual perspective), but I can not do any activities until full page loads(around 1 sec). Can you guys share your implementation how you did it that is actually works
谢谢
我的代码:
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() + ")";
}
};
}
推荐答案
在针对角度应用程序使用硒编写测试时,我遇到了类似的情况.实际上,在有角度的应用程序中,页面的骨架或视图会立即加载,但它会继续在后台调用$http
请求以获取数据.一旦有角度的应用程序完成了$http
调用,它就会使用$ http调用的响应来渲染视图,因此像waitUntilPageToBeLoad
,waitUntilElementToBeClickable
这样的经典硒等待在这里根本不起作用.另一个解决方案是使用Thread.Sleep()
,但是正如您提到的那样,这不是明智的选择.
I have faced similar situation while writing tests using selenium against angular app. Actually, in angular app the skeleton or view of page loads instantly but it keeps calling $http
request in background to fetch the data. Once the angular app finishes the $http
call, it renders the view with response of $http call.So having a classical wait of selenium like waitUntilPageToBeLoad
, waitUntilElementToBeClickable
do not work here at all. The other solution is to have Thread.Sleep()
but as you mentioned that is not an intelligent wait.
所以为什么不使用wait方法来确保$http
调用在后台完成.您可以尝试以下等待方法,它对我有用.我希望它也对您有用!
So why not have wait method to ensure that $http
calls are finished in background. You can try below wait method,it worked for me.I Hope it works for you too!
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);
}
这篇关于Selenium和Angularjs等到执行一些操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!