Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing AngularJS with Selenium

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()

like image 645
deeptowncitizen Avatar asked Jul 31 '14 15:07

deeptowncitizen


People also ask

Can selenium be used to test AngularJS applications?

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.

Why is selenium not used with Angular?

Selenium supports different wait conditions like implicit, explicit, and fluent waits but these wait conditions might not be ideal for angular applications.

Can js be used with selenium?

Selenium is an open-source automation testing tool that supports a number of scripting languages like C#, Java, Perl, Ruby, JavaScript, etc.

Can we use selenium with python for Angular applications?

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.


1 Answers

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; } /*"); });*/ 
like image 200
npjohns Avatar answered Oct 02 '22 20:10

npjohns