我有一个Selenium测试套件,它针对许多Web应用程序运行Selenium集成测试,其中一些是用Angular 2+编写的,而另一些是用AngularJS编写的。
我们使用带有ExpectedCondition
的自定义WebDriverWait
和private static ExpectedCondition<Boolean> angularIsFinished() {
return new ExpectedCondition<Boolean>() {
public Boolean apply(final WebDriver driver) {
Object result = null;
while(result == null || result.toString().equals("undefined")) {
result = ((JavascriptExecutor)driver).executeScript("return typeof angular;");
try {
Thread.sleep(200L);
} catch (final InterruptedException ex) {
logger.error("Error while trying to sleep", ex);
}
}
final String script = " var el = document.querySelector(\"body\");\n" +
" var callback = arguments[arguments.length - 1];\n" +
" angular.element(el).injector().get('$browser').notifyWhenNoOutstandingRequests(callback);";
((JavascriptExecutor)driver).executeAsyncScript(script);
return true;
}
public String toString() {
return "Wait for AngularJS";
}
};
}
来使测试用例等待AngularJS应用完成加载,以避免等待任意时间:
return typeof angular;
但是,undefined
对于Angular 2+应用程序将始终返回NgZone
。可以使用与AngularJS的notifyWhenNoOutstandingRequests类似的方法来确定Angular 2+应用何时完成加载吗?
This question提到使用JavascriptExecutor
作为一种可能的解决方案,但是您如何通过通过 ID PFT area
1 alnfru_00001 alnfru Yukon_Delta
2 alnfru_00002 alnfru Yukon_Delta
3 alnfru_00003 alnfru Yukon_Delta
4 alnfru_00004 alnfru Yukon_Delta
5 alnfru_00001 alnfru Yukon_Delta
6 alnfru_00002 alnfru Yukon_Delta
7 alnfru_00003 alnfru Yukon_Delta
8 alnfru_00004 alnfru Yukon_Delta
9 alnfru_00005 alnfru Yukon_Delta....................................
18 alnfru_00001 alnfru Yukon_Delta
19 alnfru_00002 alnfru Yukon_Delta
20 alnfru_00003 alnfru Yukon_Delta
21 alnfru_00004 alnfru Yukon_Delta
22 alnfru_00001 alnfru Yukon_Delta
23 alnfru_00002 alnfru Yukon_Delta
24 alnfru_00003 alnfru Yukon_Delta
25 alnfru_00004 alnfru Yukon_Delta
The data frame should look like this
ID PFT area
1 alnfru_00001 alnfru Yukon_Delta
2 alnfru_00002 alnfru Yukon_Delta
3 alnfru_00003 alnfru Yukon_Delta
4 alnfru_00004 alnfru Yukon_Delta
5 alnfru_00005 alnfru Yukon_Delta
6 alnfru_00006 alnfru Yukon_Delta
7 alnfru_00007 alnfru Yukon_Delta
8 alnfru_00008 alnfru Yukon_Delta
9 alnfru_00009 alnfru Yukon_Delta....................................
18 alnfru_00010 alnfru Yukon_Delta
19 alnfru_00011 alnfru Yukon_Delta
20 alnfru_00012 alnfru Yukon_Delta
21 alnfru_00013 alnfru Yukon_Delta
22 alnfru_00014 alnfru Yukon_Delta
23 alnfru_00015 alnfru Yukon_Delta
24 alnfru_00016 alnfru Yukon_Delta
25 alnfru_00017 alnfru Yukon_Delta
执行的脚本来处理呢?
答案 0 :(得分:1)
您可以通过致电例如document.querySelector('app-root')
?或任意组件选择器...
或者打电话给document.readyState
呢?完整载入wep页面后,结果应该为'complete'
,并且网页是否基于角度都没关系。
答案 1 :(得分:0)
针对Protractor code,我提出了两种可能的解决方案:
首先,我们有一个选项,可以在其中找到可测试性列表,然后为所有可添加性添加回调,然后等待其中一个将站点标记为可测试性(这确实意味着您的脚本将在任何一种可测性都已经成为可测性,它不会等待所有可测性都变为可测性。
private static ExpectedCondition angular2IsTestable() {
return (ExpectedCondition<Boolean>) driver -> {
JavascriptExecutor jsexec = ((JavascriptExecutor) driver);
Object result = jsexec.executeAsyncScript("window.seleniumCallback = arguments[arguments.length -1];\n" +
"if (window.getAllAngularTestabilities()) {\n" +
" window.getAllAngularTestabilities().forEach(function (testability) {\n" +
" testability.whenStable(window.seleniumCallback(true))\n" +
" }\n" +
" );\n" +
"} else {\n" +
" window.seleniumCallback(false)\n" +
"}"
);
return Boolean.parseBoolean(result.toString());
};
}
第二个选项是专门检查角根元素的可测试性状态:
private static ExpectedCondition angular2ElementIsTestable(final WebElement element) {
return (ExpectedCondition<Boolean>) driver -> {
JavascriptExecutor jsexec = ((JavascriptExecutor) driver);
Object result = jsexec.executeAsyncScript(
"window.seleniumCallback = arguments[arguments.length -1];\n" +
"var element = arguments[0];\n" +
"if (window.getAngularTestability && window.getAngularTestability(element)) {\n" +
" window.getAngularTestability(element).whenStable(window.seleniumCallback(true));\n" +
"} else {\n" +
" window.seleniumCallback(false)\n" +
"}"
, element);
return Boolean.parseBoolean(result.toString());
};
}
第二个选项更具针对性,因此如果要测试站点的特定区域,则更可靠。
第三个选择是编写一些更复杂的东西,以跟踪所有可测试性的状态,然后仅在所有条件变为真时才触发真正的回调。我还没有实现方案。
答案 2 :(得分:0)
由于@Ardesco's answer,我可以使用window.getAllAngularTestabilities
函数来完成类似于量角器的工作。这是我用来确定Angular 2+页面是否加载的脚本:
var testability = window.getAllAngularTestabilities()[0];
var callback = arguments[arguments.length - 1];
testability.whenStable(callback);
这是完整的ExpectedCondition
看起来对AngularJS和Angular 2+都适用的样子:
private static ExpectedCondition<Boolean> angularIsFinished() {
return new ExpectedCondition<Boolean>() {
public Boolean apply(final WebDriver driver) {
Object result = null;
boolean isAngular2Plus = false;
while(result == null || result.toString().equals("undefined")) {
result = ((JavascriptExecutor)driver).executeScript("return typeof angular;");
if (result == null || result.toString().equals("undefined")) {
result = ((JavascriptExecutor)driver).executeScript("return typeof window.getAngularTestability;");
if (result != null && !result.toString().equals("undefined")) {
isAngular2Plus = true;
}
}
try {
Thread.sleep(200L);
} catch (final InterruptedException ex) {
logger.error("Error while trying to sleep", ex);
}
}
final String script;
if (isAngular2Plus) {
script =" var testability = window.getAllAngularTestabilities()[0];\n" +
" var callback = arguments[arguments.length - 1];\n" +
" testability.whenStable(callback);";
} else {
script =" var el = document.querySelector(\"body\");\n" +
" var callback = arguments[arguments.length - 1];\n" +
" angular.element(el).injector().get('$browser').notifyWhenNoOutstandingRequests(callback);";
}
((JavascriptExecutor) driver).executeAsyncScript(script);
return true;
}
public String toString() {
return "Wait for AngularJS";
}
};
}