Friday 19 May 2017

Selenium for Angular JS Pages


Selenium + NgWebDriver  =  Better AngularJS Support

Angular JS is a opensource web application framework based on Java-script. Any Angular JS implemented web page would have additional custom tag attributs like ng-app, ng-model, ng-bind, ng-repeat etc.

Automating the AngularJS based web application is possible using Selenium. However in certain cases where the web pages are built extensively using AngularJS  resulting in complex DOM structure, it is difficult to locate DOM elements with simple XPaths & CSS selectors.In this case, Protractor (an E2E test framework for Angular Applications) built on Java script version of Selenium makes it easy for identifying the locators easily.



For people who are on java version of Selenium & do not want to switch to Protractor, there is an option of enhancing the Selenium ability to locate angular tags by using NgWebDriver.

NgWebDriver: A small java library of WebDriver locators built to address AngularJS tags.
Like Protractor, it works with Angular versions greater than 1.* and is compatible with Angular 2 applications. In other words, this is alternative to Protractor in java version.



Below example demonstrate a way to use the NgWebDriver with the regular webDriver scripts.

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import com.paulhammant.ngwebdriver.ByAngular;
import com.paulhammant.ngwebdriver.NgWebDriver;

public class AngularWebDriver {

static WebDriver driver;
static NgWebDriver ngdriver;

public static void main(String[] args) throws InterruptedException{
System.setProperty("webdriver.chrome.driver","./chromedriver.exe");
driver = new ChromeDriver();

  //Sample AngularJs Webpage
driver.get("https://hello-angularjs.appspot.com/sorttablecolumn");
driver.manage().window().maximize();

  //Creating an instance of NgWebDriver
ngdriver = new NgWebDriver((JavascriptExecutor) driver);

driver.findElement(ByAngular.model("name")).sendKeys("Test Company");
driver.findElement(ByAngular.model("employees")).sendKeys("1000");
driver.findElement(ByAngular.model("headoffice")).sendKeys("Mysore");
driver.findElement(ByAngular.buttonText("Submit")).click();

Thread.sleep(2000);
String txt = driver.findElement(ByAngular.repeater("company in companies").row(4).column("name")).getText();
System.out.println(txt + " Added.");

if(txt.equalsIgnoreCase("Test Company")){
System.out.println("New Company Added. Now remove it");
driver.findElement(ByAngular.repeater("company in companies").row(4)).findElement(ByAngular.buttonText("Remove")).click();
}

Thread.sleep(3000);
driver.quit();

}

}

25 comments:

  1. Replies
    1. It should support irrespective of Angular version.

      Delete
    2. It even supports Selenium 3. There are regular updates on the ngWwebDriver.
      https://github.com/paul-hammant/ngWebDriver/blob/master/CHANGELOG.md

      Delete
  2. Excellent ! I am truly impressed that there is so much about this subject that has been revealed and you did it so nicely.
    Angularjs Development

    ReplyDelete
  3. Excellent article. Very interesting to read. I really love to read such a nice article. Thanks! keep rocking. AngularJS5 Online Training

    ReplyDelete
  4. Hi experts
    Please give ur suggestions please
    Our application is angular js application
    To automate that which one is best
    Protractor or selenium with ngwebdriver
    Please tell me why

    ReplyDelete
    Replies
    1. ngWebdriver is the best tool.
      • Enhance Selenium ability to locate angular tags by using ngWebDriver
      • ngWebDriver has capability to identify the AngularJS control elements directly:
      o byAngular.binding(Str)
      o byAngular.model(str)
      o byAngular.options(str)
      o byAngular.repeater(str)
      • As ngWebDriver can identify AngularJS controls elements directly, it reduces the failures due to compatibility issues with xpath in different browsers and also reduce the execution time.
      • If you are already using Selenium with Java then just add ngWebDriver library to your framework and this will help you to handle AngularJS elements within the current framework.

      Delete
  5. I think you forgot to add one line before locators line : ngDriver.waitForAngularRequestsToFinish(); without this it gives error.

    ReplyDelete
    Replies
    1. It worked either with/without the above statement for me. May with certain selenium instance it is throwing up. However, it is good to add it.

      Delete
  6. can u explain about retrieve as method with example please

    ReplyDelete
  7. I think you forgot to include what are all the imports you have to get. It is not difficult to figure out, but it would help

    ReplyDelete
    Replies
    1. Hi, Below are the imports. I would add it to the code snippet also.
      import org.openqa.selenium.By;
      import org.openqa.selenium.JavascriptExecutor;
      import org.openqa.selenium.WebDriver;
      import org.openqa.selenium.chrome.ChromeDriver;
      import com.paulhammant.ngwebdriver.ByAngular;
      import com.paulhammant.ngwebdriver.NgWebDriver;

      Delete
  8. My ignorant question ..
    Why it said
    static NgWebDriver ngdriver; and at the same time,
    //Creating an instance of NgWebDriver
    ngdriver = new NgWebDriver((JavascriptExecutor) driver);

    Is this legal in Java ?

    ReplyDelete
  9. Excellent ! I am truly impressed that there is so much about this subject that has been revealed and you did it so nicely
    Thanks
    Anika Digital Media
    seo services in UK
    web design development company in UK
    graphic design
    angularJs developer in london

    ReplyDelete
  10. Thank you a million time, it works well.

    ReplyDelete
  11. Will it also work for Angular 7

    ReplyDelete
    Replies
    1. It should work i feel. I haven't tested with angular 7 though

      Delete
  12. Thanks This is very nice article.
    We have single page angular cordova build iOS mobile application . Can we use ngwebdriver integrated with appium?

    ReplyDelete
  13. when ngwebdriver instance is created, why it was not used anywhere in the code? and how for the below line of code:
    driver.findElement(ByAngular.model("headoffice")).sendKeys("Mysore");
    driver is able to interact with angualr based websites.I can see, driver reference is not even assigned to ngwebdriver instance

    ReplyDelete
    Replies
    1. Only when you create an instance of the Ngwebdriver, ByAngular methods works..
      There are other methods which you can access with ngwebdriver instance, like
      ngWebDriver.waitForAngularRequestsToFinish();

      Delete
  14. Is there any way to handle non angular page. like login page ? it is giving error saying angular is not detected in login page itself

    ReplyDelete