Javascript 从selenium检测angular是否正在执行。。。东西
为什么Javascript 从selenium检测angular是否正在执行。。。东西,javascript,java,angularjs,selenium,selenium-webdriver,Javascript,Java,Angularjs,Selenium,Selenium Webdriver,为什么driver.findElement(静态文本).getText()会返回“” 我有一个angular应用程序,我正在osx上通过java通过chromedriver使用selenium进行测试 我有一些标记看起来像: <h1 id="my-unique-id" ng-if="model.shouldDisplayThisAttribute">static text</h1> 屈服: java.lang.AssertionError: Not true that
driver.findElement(静态文本).getText()会返回“”
我有一个angular应用程序,我正在osx上通过java通过chromedriver使用selenium进行测试
我有一些标记看起来像:
<h1 id="my-unique-id" ng-if="model.shouldDisplayThisAttribute">static text</h1>
屈服:
java.lang.AssertionError: Not true that <""> contains <"static text">
在我的页面中,我在预期的时间看到console.log消息
如果我将其粘贴到控制台中:
(function() {
function angularAppearsToBeIdle(callback) {
var untilNextDigest,
isIdle = angular.element(document.body).scope().$watch(function () {
clearTimeout(untilNextDigest);
untilNextDigest = setTimeout(function () {
isIdle();
callback('done');
}, 100);
});
}
angularAppearsToBeIdle(console.log.bind(console));
}());
我得到“未定义”
最后,我想做的是从Java:
@Test
public void clickOnSomethingThatIsProbablyNotGoingToChange(driver.findElement(By.id("some-id"));
private WebElement idleElement() {
new WebDriverWait(driver, 30).until(new Predicate<WebDriver>() {
@Override
public boolean apply(WebDriver input) {
Object result = ((JavascriptExecutor) driver).executeScript("return window.angularAppearsToBeIdle;");
return result.equals("idle");
}
}
@测试
public void单击可能无法更改的内容(driver.findelelement(By.id(“某些id”));
私有WebElement idleElement(){
新的WebDriverWait(驱动程序,30).until(新谓词(){
@凌驾
公共布尔应用(WebDriver输入){
对象结果=((JavascriptExecutor)driver.executeScript(“返回窗口.AngularAppeartToBeidle;”);
返回结果。等于(“空闲”);
}
}
我尝试了以下方法,但没有硒做类似的事情的例子:
public void waitForAngular() {
((JavascriptExecutor) driver).executeScript(
" window.angularAppearsToBeIdle = 'not idle'; ");
((JavascriptExecutor) driver).executeScript(
" window.signalThatAngularAppearsToBeIdle = function(signal) { " +
" var untilNextDigest, " +
" isIdle = angular.element(document.body).scope().$watch(function () { " +
" clearTimeout(untilNextDigest); " +
" untilNextDigest = setTimeout(function () { " +
" isIdle(); " +
" signal = 'idle'; " +
" }, 100); " +
" }); " +
" } ");
driver.manage().timeouts().setScriptTimeout(10, TimeUnit.SECONDS);
((JavascriptExecutor) driver).executeAsyncScript(
" var callback = arguments[arguments.length - 1]; " +
" signalThatAngularAppearsToBeIdle(callback) "
,
" window.angularAppearsToBeIdle ");
new WebDriverWait(driver, 30).until(new Predicate<WebDriver>() {
@Override
public boolean apply(WebDriver input) {
Object result = ((JavascriptExecutor) driver).executeScript("return window.angularAppearsToBeIdle;");
return result.equals("idle");
}
});
public void waitForAngular(){
((JavascriptExecutor)驱动程序).executeScript(
“window.angularsappeartobeidle=‘不空闲’;”;
((JavascriptExecutor)驱动程序).executeScript(
“window.signalThatAngularsAppearTobeidle=函数(信号){”+
“var untilNextDigest,”+
“isIdle=angular.element(document.body).scope().$watch(函数(){”+
“clearTimeout(直到下一个摘要);”+
“untilNextDigest=setTimeout(函数(){”+
“isIdle();”+
“信号=‘空闲’;”+
" }, 100); " +
" }); " +
" } ");
driver.manage().timeouts().setScriptTimeout(10,TimeUnit.SECONDS);
((JavascriptExecutor)驱动程序).executeAsyncScript(
“var callback=arguments[arguments.length-1];”+
“显示Angular似乎要回叫的信号(回叫)”
,
“window.angularAppearsToBeIdle”);
新的WebDriverWait(驱动程序,30).until(新谓词(){
@凌驾
公共布尔应用(WebDriver输入){
对象结果=((JavascriptExecutor)driver.executeScript(“返回窗口.AngularAppeartToBeidle;”);
返回结果。等于(“空闲”);
}
});
如何从Selenium中检测angular是否正在忙着做事?您需要编写一个自定义的ExpectedCondition,查询angular是否完成了工作。下面是我之前准备的一个:
public static ExpectedCondition angularHasFinishedProcessing() {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
String hasAngularFinishedScript = "var callback = arguments[arguments.length - 1];\n" +
"var el = document.querySelector('html');\n" +
"if (!window.angular) {\n" +
" callback('false')\n" +
"}\n" +
"if (angular.getTestability) {\n" +
" angular.getTestability(el).whenStable(function(){callback('true')});\n" +
"} else {\n" +
" if (!angular.element(el).injector()) {\n" +
" callback('false')\n" +
" }\n" +
" var browser = angular.element(el).injector().get('$browser');\n" +
" browser.notifyWhenNoOutstandingRequests(function(){callback('true')});\n" +
"}";
JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver;
String isProcessingFinished = javascriptExecutor.executeAsyncScript(hasAngularFinishedScript).toString();
return Boolean.valueOf(isProcessingFinished);
}
};
}
然后,只需将此预期条件插入如下等待即可:
WebDriverWait wait = new WebDriverWait(driver, 15, 100);
wait.until(angularHasFinishedProcessing());
希望这能有所帮助。我在C#Net上写作,所以我不得不翻译Ardesco的答案:
static class HelperFunctions
{
public static bool AngularHasFinishedProcessing(IWebDriver driver)
{
string HasAngularFinishedScript =
@"var callback = arguments[arguments.length - 1];
var el = document.querySelector('html');
if (!window.angular) {
callback('False')
}
if (angular.getTestability) {
angular.getTestability(el).whenStable(function(){callback('True')});
} else {
if (!angular.element(el).injector()) {
callback('False')
}
var browser = angular.element(el).injector().get('$browser');
browser.notifyWhenNoOutstandingRequests(function(){callback('True')});
}";
IJavaScriptExecutor javascriptExecutor = (IJavaScriptExecutor)driver;
return Convert.ToBoolean(javascriptExecutor.ExecuteAsyncScript(HasAngularFinishedScript));
}
}
我用了:
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until((d) => { return HelperFunctions.AngularHasFinishedProcessing(driver); });
将Python 2.7加入到混合中:
class angular_is_ready(object):
script = """var callback = arguments[arguments.length - 1];
var el = document.querySelector('html');
if (!window.angular) {
callback(false)
}
if (angular.getTestability) {
angular.getTestability(el).whenStable(function(){callback(true)});
} else {
if (!angular.element(el).injector()) {
callback(false)
}
var browser = angular.element(el).injector().get('$browser');
browser.notifyWhenNoOutstandingRequests(function(){callback(true)});
};"""
def __call__(self, driver):
try:
return driver.execute_async_script(self.script)
except:
return False
# Define driver and timeout,
# then use the condition like so:
WebDriverWait(driver, timeout).until(angular_is_ready)
首先,请更正以下代码断言(driver.findElement(By.id(“我的唯一id”)).getText()包含(“预期”);即使没有正确匹配的括号。否则它将误导他人。我严重怀疑任何人都不会理解我的问题。如果大家不理解,我将更新我的问题…请更新问题标题,使其更能描述实际问题。gragrator.js这样做,Ardesco的答案是一个很好的翻译f那是硒。
static class HelperFunctions
{
public static bool AngularHasFinishedProcessing(IWebDriver driver)
{
string HasAngularFinishedScript =
@"var callback = arguments[arguments.length - 1];
var el = document.querySelector('html');
if (!window.angular) {
callback('False')
}
if (angular.getTestability) {
angular.getTestability(el).whenStable(function(){callback('True')});
} else {
if (!angular.element(el).injector()) {
callback('False')
}
var browser = angular.element(el).injector().get('$browser');
browser.notifyWhenNoOutstandingRequests(function(){callback('True')});
}";
IJavaScriptExecutor javascriptExecutor = (IJavaScriptExecutor)driver;
return Convert.ToBoolean(javascriptExecutor.ExecuteAsyncScript(HasAngularFinishedScript));
}
}
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until((d) => { return HelperFunctions.AngularHasFinishedProcessing(driver); });
class angular_is_ready(object):
script = """var callback = arguments[arguments.length - 1];
var el = document.querySelector('html');
if (!window.angular) {
callback(false)
}
if (angular.getTestability) {
angular.getTestability(el).whenStable(function(){callback(true)});
} else {
if (!angular.element(el).injector()) {
callback(false)
}
var browser = angular.element(el).injector().get('$browser');
browser.notifyWhenNoOutstandingRequests(function(){callback(true)});
};"""
def __call__(self, driver):
try:
return driver.execute_async_script(self.script)
except:
return False
# Define driver and timeout,
# then use the condition like so:
WebDriverWait(driver, timeout).until(angular_is_ready)