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