Testing Angularjs Application with Selenium

All we need is an easy explanation of the problem, so here it is.

I am testing an angular js application

Link Angular js App

when i click on the UI Kit link on the web application i am getting the following error –

at demoaj.Ajapp.main(Ajapp.java:16) Caused by:
org.openqa.selenium.NoSuchElementException: Unable to locate element:
{“method”:”xpath”,”selector”:”html/body/div1/div1/aside/div/div/ul/li[2]/a”}
Command duration or timeout: 51 milliseconds For documentation on this
error, please visit:
http://seleniumhq.org/exceptions/no_such_element.html

I am new to this i did some research on this AngularJS

java Code

    package demoaj;

    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;

    public class Ajapp {

        public static void main(String[] args) throws InterruptedException {
        WebDriver d=new FirefoxDriver();
        d.manage().window().maximize();
        d.get("http://iarouse.com/demo/index.html?product=square");
        WebDriverWait wait = new WebDriverWait(d, 20);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("html/body/div[1]/div[1]/aside/div/div/ul/li[2]/a"))).click();
        //d.findElement(By.xpath("html/body/div[1]/div[1]/aside/div/div/ul/li[2]/a")).click();

        }

}

I think it is not able to find the element because in angularjs the dom is not rendering. when i check the page source it does not display anything all things are hidden after doing some research on angularjs testing i have few question please help,

for Angular App testing.

  1. i think i have to use protractor? i guess
  2. if i use protractor i have to write code in javascript or jquery?
  3. if i use protractor can i write my code in java using eclipse ide or intellij?

Please Help,

Thanks in advance.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Here are your answers –

  • Yes for AngularJS testing you need to use Protractor as it has inbuilt support to wait for Angular to load.
  • If you use Protractor, then you need to write code in JavaScript and not jquery.
  • If you use Protractor you cannot use Java as Protractor is built on top of Selenium WebDriverJS.

Advantage would be that you can write Javascript code (which is simpler than Java) to test your angular app and you don’t have to worry about how the AngularJS works on your page. Only thing that might confuse you is using promises which is taken from WebdriverJS. Hope this helps.

Method 2

Here are some of the techniques I use to test my AngularJS Applications :

  1. Look into Karma framework. It is very good and has good documentation as well.
    https://karma-runner.github.io/0.8/plus/AngularJS.html
  2. If you’re more into end-to-end testing please use Protractor as it is proven time and time again that it is the best.
    https://angular.github.io/protractor/#/

Method 3

I think angular has rendered your element and selenium is finding it, but it is not clickable yet. You can find it out by getting some properties for the element (i.e. text). The problem is with angular not finished with $http calls (and probably the $digest cycle). One think you can do is to wait until angular is done with pending $http requests and then find your desired element and call .Click() on it. Below is a working code snippet I use for our test project in C#.

 new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(angularIsDoneLoading);
//Add the rest of your code in here(like finding element, clicking on it etc.)


         Func<IWebDriver, bool> angularIsDoneLoading = (IWebDriver drv) =>
                {
                    string ngFinishedAllRequests =
                         @"var injector = window.angular.element('body').injector();
                         var $http = injector.get('$http');
                         return ($http.pendingRequests.length === 0)";

                    return ((IJavaScriptExecutor)drv).ExecuteScript(ngFinishedAllRequests).ToString() == "True";
                };

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply