Глядя на код Транспортир Я предложил два возможных решения:
Прежде всего, у нас есть опция, где мы находим список тестируемости, затем добавляем обратный вызов для всех из них, а затем ждем, пока один из них отметит сайт как тестируемый (это означает, что ваш сценарий будет продолжен после любая тестируемость стала тестируемой, она не будет ждать, пока все они станут тестируемыми).
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());
};
}
Второй вариант более целенаправленный и, следовательно, более надежный, если вы хотите протестировать определенную область сайта.
Третий вариант - написать что-то более сложное, отслеживающее состояние всех тестируемых объектов, и затем запускать истинный обратный вызов только тогда, когда все они станут истинными. У меня пока нет реализации для этого.