Why is driver.findElement(<some static element ng-if=simplebool>static text</some>).getText() ever returned? "?
I have an angular application that I am testing with selenium via chromedriver via java on osx.
I have a markup that looks like this:
<h1 id="my-unique-id" ng-if="model.shouldDisplayThisAttribute">static text</h1>
Very often I get:
assert(driver.findElement(By.id("my-unique-id").getText().contains("static text");
getting:
java.lang.AssertionError: Not true that <""> contains <"static text">
For example, 30% of the time.
I do not understand how this .getText () element could be evaluated as "", so I assume that angular is either $ digesting or $ compilation of the page. It's great. This is normal. This is normal.
I want to know when angular finished compiling $ and $ digesting and $ watch, so I can look at the page and see what is.
If I add:
(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)); }());
to my page, I see console.log messages while I am expecting them.
If I paste this into the console:
(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)); }());
I get 'undefined'.
Ultimately, what I would like to do is 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"); } }
I tried the following, but there are no examples when Selenium does something like this:
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"); } });
How can I detect from Selenium if angular is busy with work?