我们使用Selenium WebDriver自动化基于UI的测试。我们的挑战之一是检测页面何时真正完成加载,而Angular 1在这方面也是一个挑战。我们最终执行这段代码专门检测Angular 1是否完成:
if(typeof window.angular !== \"undefined\")
{
var injector = window.angular.element(\"*[ng-app]\").eq(0).injector();
if(injector)
{
var $rootScope = injector.get(\"$rootScope\");
var $http = injector.get(\"$http\");
if($rootScope.$$phase === \"$apply\" || $rootScope.$$phase === \"$digest\" || $http.pendingRequests.length !== 0)
{
return false;
}
}
}
我们最近测试的应用程序切换为使用Angular 2.上面的代码片段不等待Angular 2完成。有什么建议吗?
答案 0 :(得分:13)
对于Angular 2,您应该等待所有Angular 2应用程序的"testabilities"的稳定性:
functions.waitForAllAngular2 = function(callback) {
try {
var testabilities = window.getAllAngularTestabilities();
var count = testabilities.length;
var decrement = function() {
count--;
if (count === 0) {
callback();
}
};
testabilities.forEach(function(testability) {
testability.whenStable(decrement);
});
} catch (err) {
callback(err.message);
}
};
Taken from Protractor source code。量角器是围绕WebDriverJS javascript selenium绑定的包装器;旨在测试AngularJS应用程序(不仅是,但最适合)。
答案 1 :(得分:4)
使用@alecxe答案我最后使用javascript one liner来检查所有Angular Testabilities是否稳定
window.getAllAngularTestabilities().findIndex(x=>!x.isStable()) === -1
答案 2 :(得分:2)
基于alexce的答案,这是我们在硒测试中等待角度的代码:
false
答案 3 :(得分:1)
我通过编写一个动作类来修复此问题,在使用Paul Hammants ngWebDriver执行动作(点击,填充,检查等)之前我等待Angular:
import com.paulhammant.ngwebdriver.NgWebDriver;
public class ActionsWithWaits {
private NgWebDriver ngdriver;
private JavascriptExecutor js;
public ActionsWithWaits(){
WebDriver driver = getDriver();
js = (JavascriptExecutor) driver;
driver.manage().timeouts().setScriptTimeout(9, TimeUnit.SECONDS);
ngdriver = new NgWebDriver(js);
}
public void waitForAngular(){
ngdriver.waitForAngularRequestsToFinish();
}
public void waitAndClick(WebElementFacade button){
waitForAngular();
button.click();
}
public void waitAndFillIn(String text, WebElementFacade field){
waitForAngular();
field.type(text);
}
etc..
现在你可以使用这些动作而不是标准的硒动作,你不必担心一件事(=
答案 4 :(得分:0)
我会从根组件
中的ngAfterViewInit()
内发出一个事件
@Component({
selector: 'my-app',
...
})
export class AppComponent {
constructor(private renderer:Renderer, private elementRef:ElementRef){}
ngAfterViewInit() {
this.renderer.invokeElementMethod(this.elementRef.nativeElement,
'dispatchEvent',
[new CustomEvent('angular2-loaded', { bubbles: true })]);
}
}
然后使用WebDriver收听此事件。