I have a SPA application on stack ASP MVC + AngularJS and I'd like to test the UI. For now I'm trying Selenium with PhantomJS and WebKit drivers.
This is a sample testing page - view with single element. The list items <li> load dynamically from server and are bounded by Angular.
<div id="items">     <li>text</li>     <li>text2</li> </div>   I'm trying to pass a test and there is an error in this line:
_driver.FindElements(By.TagName('li'))   At this point there are no loaded elements and _driver.PageSource doesn't contain elements.
How can I wait for the items to load? Please do not suggest Thread.Sleep()
There is a library called ngWebDriver that is designed to automate AngularJS and Angular Web Applications using Selenium with Java. This library is developed by having all the JavaScript created for a Protractor Project.
Selenium supports different wait conditions like implicit, explicit, and fluent waits but these wait conditions might not be ideal for angular applications.
Selenium is an open-source automation testing tool that supports a number of scripting languages like C#, Java, Perl, Ruby, JavaScript, etc.
Selenium API has implementations in several major programming languages - allowing you to write your tests in Java, C#, python, ruby, JavaScript and more. If you already have a selenium-based e2e testing framework in place - you can use it also for AngularJS web-apps.
This will wait for page loads / jquery.ajax (if present) and $http calls, and any accompanying digest/render cycle, throw it in a utility function and wait away.
/* C# Example  var pageLoadWait = new WebDriverWait(WebDriver, TimeSpan.FromSeconds(timeout));             pageLoadWait.Until<bool>(                 (driver) =>                 {                     return (bool)JS.ExecuteScript( @"*/ try {   if (document.readyState !== 'complete') {     return false; // Page not loaded yet   }   if (window.jQuery) {     if (window.jQuery.active) {       return false;     } else if (window.jQuery.ajax && window.jQuery.ajax.active) {       return false;     }   }   if (window.angular) {     if (!window.qa) {       // Used to track the render cycle finish after loading is complete       window.qa = {         doneRendering: false       };     }     // Get the angular injector for this app (change element if necessary)     var injector = window.angular.element('body').injector();     // Store providers to use for these checks     var $rootScope = injector.get('$rootScope');     var $http = injector.get('$http');     var $timeout = injector.get('$timeout');     // Check if digest     if ($rootScope.$$phase === '$apply' || $rootScope.$$phase === '$digest' || $http.pendingRequests.length !== 0) {       window.qa.doneRendering = false;       return false; // Angular digesting or loading data     }     if (!window.qa.doneRendering) {       // Set timeout to mark angular rendering as finished       $timeout(function() {         window.qa.doneRendering = true;       }, 0);       return false;     }   }   return true; } catch (ex) {   return false; } /*"); });*/ 
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With