Sunday, August 28, 2016

AngularJS directives support of animations

The following directives support animations:



1. ngRepeat – It supports enter, leave and move animations.
2. ngInclude – It supports enter and leave animations.
3. ngView – It supports enter and leave animations.
4. ngIf – It supports enter and leave animations.
5. ngSwitch – It supports enter and leave animations.
6. ngClass – It supports addClass and removeClass animations.
7. ngShow & ngHide – These support addClass and removeClass animations.

Wednesday, August 24, 2016

AngularJS - Test application using protractor

Test your application using protractor

Please read the previous post to configure Protractor
How to configure Protractor?


Once the setup is done, you are ready to write and run e2e scripts. When we start testing with Protractor, we set up our tests to work through Jasmine.
That is, we simply start writing our tests like we do when we write our Karma tests. A simple Protractor test setup might look like the below structure :





Protractor Global Variables

The browser variable is a wrapper around the Web Driver instance. We use the browser variable for any navigation or for grabbing any information off the page. We can use the browser variable to navigate to a page using the get() function

·        browser: browser.get()
·        element and by: element(by.model('yourName'))
·        protractor: protractor.Key

Searching for elements on the page

Ø  element() vs element.all()
o   element() - Single element selection
o   element.all() - Collection of elements
Ø  Multiple ways to select elements for making assertions:
o   by.binding
§  element( by.binding('myModel') );
o   by.model
§  element( by.model('myModel') );
o   by.repeater
§  element( by.repeater('user in users').row(0).column('name') );
o   by.css
§  element( by.css('[ng-click="submitRefill()"]') );
List of Protractor API methods - http://www.protractortest.org/#/api


Searching elements best practices


1,  Take the advantage of AngularJS attributes using by.model, by.repeater, by.binding etc.,
2,  Avoid using potential CSS attributes, mainly IDs and Classes.

Executing events



Ø  click  - To simulate the click of the button, select the element and call click method

element( by.css('[ng-click="submitRefill()"]') ).click();

Ø  sendKeys – To simulate the values to be entered in the textbox

element( by.model('commentText') ).sendKeys("Hi!", protractor.Key.ENTER);

Control Flow

WebDriverJS maintains a queue of pending promises, called the control flow, to keep execution organized.




In the example above, the control flow would execute the queue following the sequence we see in the comments. Basically method by.binding would only run oncebrowser.get promise is resolved, and so on.



Example




Reporter – Test Case Results



Next you need a report of failed and passed test cases along with screenshots. protractor-html-screenshot-reporter, an npm module, provides you with an Html report of the test cases along with screenshots

Using onPrepare - Export HTML results of your automated Suites.




Executing Tests with GRUNT


To run your E2E tests with Grunt, you will need to have Grunt installed. Also install the grunt-protractor-runner plugin.
Configure this plugin in your Gruntfile.js. I set up two targets. One target called e2e will stop the build if a test fails. Another called continuous will be used with grunt-watch to keep the build alive and re-run tests when changes are made.




Getting started with Protractor

Getting started with Protractor



Test Suite
A test suite begins with a call to the global Jasmine function ‘describe’ with two parameters: a string and a function.  The string is a name or title for a spec suite – usually what is being tested. The function is a block of code that implements the suite.

Test Spec
Specs are defined by calling the global Jasmine function ‘it’ with two parameters: a string and a function.  The string is the title of the spec and the function is the spec, or test. A spec contains one or more expectations that test the state of the code.
Variables declared inside a ‘describe’ are available to any ‘it’ block inside the suite.

Matchers
Each matcher implements a Boolean comparison between the actual value and expected value. It reports to Jasmine if the expectation is true or false. Ex: toBeDefined, toHaveBeenCalled, toEqual, toBeGreaterThan, toBeTruthy etc..,

Expectations                                                                                                                                                                          
Global Jasmine function ‘expect’ is used to define how we are expecting the testing target to behave. It takes one parameter, the actual value. It makes use of Matcher function, which takes the expected value. Matcher implements a Boolean comparison between the actual value and the expected value. 

AngularJS - Difference between $http and $resource

Difference between $http and $resource


$http service is a core Angular service which allows you to make AJAX requests by using GET, HEAD, POST, PUT, DELETE, JSONP and PATCH methods. It is very much like the $.ajax() method in jQuery. It can be used with RESTful and Non-RESTful server-side data sources.

$http is good for quick retrieval of server-side data that doesn’t really need any specific structure or complex behaviors.

$resource warps $http and allows you to interact with RESTful server-side data sources. It requires the ngResource module to be installed which exist in angular-resource.js

$http is good for retrieval of RESTful server-side data sources that might need any specific structure or complex behaviors.




Tuesday, August 23, 2016

Parse your HTML data in AngularJS

ngSanitize 

AngularJS provides ngSanitize module to securely parse and manipulate HTML data in your application. To use it include the angular-sanitize.js file and set ngSanitize as a dependency in your angular app.



var app = angular.module('sanitizeExample', ['ngSanitize']); app.controller('ExampleController',function ($scope, $sce)
{
   var snippet ='an html\n' + 'click here\n snippet'; 
   $scope.trustedSnippet = $sce.trustAsHtml(snippet); //sce=Strict Contextual Escaping 
});

What is Protractor

Protractor 

Protractor is an end-to-end test framework for AngularJS applications. Protractor is a Node.js program built on top ofWebDriverJS. Protractor runs tests against your application running in a real browser, interacting with it as a user would.

Compatibility

Protractor 4 is compatible with nodejs v4 and newer.
When using nodejs v0.12, use protractor 2 (npm install -g protractor@2).

Getting Started

The Protractor documentation for users is located in the protractor/docs folder.
To get set up and running quickly:
Once you are familiar with the tutorial, you’re ready to move on. To modify your environment, see the Protractor Setup docs. To start writing tests, see the Protractor Tests docs.
To better understand how Protractor works with the Selenium WebDriver and Selenium Server see the reference materials.

Getting Help

Check the Protractor FAQ and read through the Top 20 questions on StackOverflow.
Please ask usage and debugging questions on StackOverflow (use the "protractor" tag), the Gitter chat room, or in theAngular discussion group. (Please do not ask support questions here on Github.)

For Contributors

Clone the github repository:
git clone https://github.com/angular/protractor.git
cd protractor
npm install
./bin/webdriver-manager update
cd website
npm install
cd ..
Start up a selenium server. By default, the tests expect the selenium server to be running at http://localhost:4444/wd/hub. A selenium server can be started with webdriver-manager which is included in bin/webdriver-manager.
webdriver-manager update
webdriver-manager start
Protractor's test suite runs against the included test application.
Install the test application dependencies with:
npm run install_testapp
Start that up with
npm start
Then run the tests with
npm test

How to configure protractor

Protractor is a preferred end-to-end testing framework for the Angular JS built applications. Protractor is built on Selenium’s Web Driver, which is an API, written as extensions, for controlling browsers. Web Driver has extensions for all sorts of different browsers.

Protractor is built on top of the Jasmine/Mocha/Cucumber framework for writing your assertions, so we don’t need to learn a new framework in order to use it. But It is recommended to use Jasmine 2.

How to Configure Protractor?

Protractor itself requires a configuration script that tells Protractor how to run, how to connect to Selenium.
·        Install Protractor locally
npm install protractor
·        Install the selenium Web Driver
/node_modules/protractor/bin/webdriver-manager update
·        Specify the Selenium web drive path
seleniumServerJar: ‘./node_modules/protractor/selenium/selenium-server-standalone-2.52.0.jar',
·        Default configuration script uses a Chrome driver, specify the path of the driver location
chromeDriver: './node_modules/protractor/selenium/chromedriver'
·        Point the test specs folder to execute
specs: ['test/e2e/**/*_spec.js']
·        Pass the capabilities to the webdriver instance
capabilities: {
    'browserName': 'chrome'
  }
·        Optionally provide the options for the Jasmine node
jasmineNodeOpts: {
        // If true, display spec names.
        isVerbose: true,
        // If true, print colors to the terminal.
        showColors: true,
        // If true, include stack traces in failures.
        includeStackTrace: true,
        // Default time to wait in ms before a test fails.
        defaultTimeoutInterval: 30000
    }



Monday, August 22, 2016

End to End Automation Testing

End to End testing is about testing the flow of the application. Basically, It is a Black Box testing to ensure the system works as planned from an end user’s perspective. From an end user perspective, user doesn’t care if a service works as planned; they care about the functionality of our app works as expected.
Why to Automate End to End testing?
We can think of it as a way to automate starting the app in our browser and clicking through the workflow of the application. It is important for us to be able to determine where the bugs are and try to eliminate them before they show up in production. It would be inefficient for us to click through the application manually, so we’ll script our tests to happen automatically.
Advantages
  1. ·        Will reduce the manual effort for E2E testing whenever the build is released for System Integration Testing.
  2. ·        Can be integrated into the part of build process, which will improve the continuous integration. 
  3. ·        Can be utilized in the Regression Testing cycle to reduce the manual effort

Thursday, August 18, 2016

Tips For AngularJS

Using "ControllerAs"
= Allows to create named scope on the controller.
    Ex. : <div ng-app="app" ng-controller="AnimalCtrl as animal"> <div>
= Instead of defining variables or functions on the $scope, we define it on “this” within the controller function. $scope can be avoided.
               Ex.: app.controller("AnimalCtrl", function(){
                this.survive= function(){
                      alert("breathe");
                  };
               });
= Can be used to share data between controllers.
Similar ways of sharing data between controllers:
1. Using Services. [The most preferred way compared to the other below ways]
2. Using events
3. Using 
$parentnextSibling,  etc. to directly access the controllers
4. Using the 
$rootScope to add the data on (not a good practice)  
Usage of "controllerAs"
1. No need to use $scope in your controller;
<div ng-controller="MainController as main">  
  {{ main.someProp }}
</div>  
app.controller('MainController', function () {  
  this.someProp = 'Some value.' 
// the above is equal  to $scope.MainController = this; this.someProp = 'Some value.' 
 
});
2. Can share data between two controllers; the values in both the text boxes update as we change either the child controller text or parent controller text box.
<div ng-controller="ParentController as parent">  
  ParentController: <input type="text" ng-model="parent.foo" />
  parent.foo: {{ parent.foo }}
  <div ng-controller="ChildController as child">
    ChildController: <input type="text" ng-model="parent.foo" />
    parent.foo: {{ parent.foo }}
  </div>
</div>  
app  
  .controller('ParentController', function () {
    this.foo = "bar";
  })
  .controller('ChildController', function () { /*empty*/ });

Tips for Angular Js Perfomance

Introduction
AngularJS is powerful framework to create large scale web application. 
Provides lot of special features to develop the single page performance driven 
web application.
  1. ·        Data Binding
  2. ·        Directive
  3. ·        Services
  4. ·        Routing
  5. ·        Controllers
  6. ·        Dependency Injection

Angular JS is beyond above mentioned concepts.
 Being MVVM framework applications maintained in single source of model to synch 
data between various layers. We can build reusable components with declarative approach with directive in place.
Any of the modern MVC frameworks fails on the performance concerns.
 It obviously depends on understanding core process how such framework works and how to get best out of it.
This newsletter summarizes top critical points to be considered while developing angular application to gain the performance.

Performance Angular
Angular is sooooooo SLOW!  Well many of us over time experienced or heard this phrase from people saying. AngularJS is one of the modular frameworks with all performance enhancements built in, but they can’t solve all our problems.
No matter how fast the framework, we can all create sluggish code through bad practices and not understanding key concepts that help it perform well.

Performance of angular is highly depends on digest cycle and scope hierarchy.
 Angular is not basically slow. You can make it slow relatively easy by coding the way it should not be.
I have listed here top performance points which I had come across developing angular application over the years.



1.   Restrict ng-repeat Usage

One of the amazing directives from Angular JS is ng-repeat. We cannot even think about an app based on angular without its presence as a beginner.
Ng-repeat quietly affect performance when not used properly. Having nested ng-repeats is a quick and easy way to increase
your watcher count exponentially and should be avoided if at all possible.



tick

cross

1.      Use  ng-repeat  with "track by" expression  to boost performance

<li ng-repeat="item in array track by item.id></li>


1.      Refrain binding function to ng-repeat. Binded function called every time of digest cycle.

<tr ng-repeat="user in getUsers()">…</tr>

2.      Applying filter in ng-repeat is expensive and called for each digest cycle. Instead filter in controller and bind it.

<tr ng-repeat="product in products | filter: { color: 'red' }
">…</tr>



2. Prefer ng-if/ ng-switch over ng-show

Use ng-if in place of ng-show wherever possible. ng-show merely hides the element with display none and bounded
element would still hang in DOM.

ng-if  directive add or remove the elements based on demand which avoids the unnecessary DOM rendering.
Therefore the additional DOM elements and data-bindings are evaluated on demand.



tick

cross

1.      Here form would not render and model inside evaluated on demand

<button ng-click="item.showForm = !item.showForm”>Show</button>

<form ng-if=”item.showForm”>
  <input type=”text” ng-model=”item.userName” name=”username” />
</form>


1.      userName model value would be still evaluated and add the burden to watchers.

<button ng-click=" item.showForm = !item.showForm”>Show</button>

<form ng-show=”item.showForm”>
  <input type=”text” ng-model=”item.userName” name=”username” />
</form>


3. Bind Once When Possible

One of the reasons being Angular App slowness is more bindings in the app.  When watchers set in application angular
internal engine hold the responsibility to keep track of changes and update wherever required.

Applying changes to the bounded model set by watchers is called digest cycle. The more watchers present will take longer
digest cycle result in slow and unresponsive application.

Angular becomes slower with around 2,000 bindings due to the process behind dirty-checking. Lesser binding will boost up performance!



tick

cross

1.      Use one way binding moreover possible. The below fragment will be updated on page load and watcher would be removed after the first digest cycle.


<h1> {{ ::appTitle }} </h1>



1.      Do not bind the function in the view. Instead evaluate in controller and bind it.

<div> {{ getUserName()}} </div>




4. $watchCollection and $watch

$watch() function allow us to create custom watchers in angular application to manipulate the data on change. By default the deep checking of the reference would not be done on $digest cycle.

The $watch() function takes a third, optional argument for "object equality." If you pass-in "true" for this argument, AngularJS will actually perform a deep-object-tree comparison. This means that within each $digest, AngularJS will check to see if the new and old values have the same structure (not just the same physical reference).

This causes app to track larger foot print; however, the deep object tree comparison is far more computationally expensive. Instead we could use $watchCollection() to fulfill that scenario.


tick

cross

$watchCollection() works by comparing physical object references; however, unlike the $watch() function, the $watchCollection() goes one-level deep and performs an additional, shallow reference check of the top level items in the collection.

$scope.$watchCollection(
    "collection",
    function( newValue, oldValue ) {
       // Code on change
    }                                                
 );



$scope.$watch("collection",
     function( newValue, oldValue ) {
            // Code on change
     },
     true // Object.
     );



5. Limit Filter Usage      
        
Filters are powerful service provided in angular which transform your application data at runtime based on business need.
Even though filters are allowed to place it in the view Its good practice to transform the data in the controller applying
necessary filters before binding.

When filters are applied in the view with pipe symbol which in turn creates watchers. If digest cycle is triggered with
any changes to the model all the filters would execute.

This again adds heavy lifting to angular engine to keep track and run filter function on each digest cycle.








tick

cross

Translating in controller and bind it.

$scope.description = $translate.instant(‘Title Description’);


– In HTML {{::description}}


Avoid binding filter in the view. This filter will run through each digest cycle irrespective of changes.


$scope.decription = ‘Title Description’;

{{ description | translate}}




6. Disable debug info in production    

Angular provides all the necessary information for debugging along with other features. This debugging supported through adding some addition properties and classes to the DOM.  Manipulating attributes and classes will also cost to performance
and expensive operation on DOM elements.

We need to turn off this debug flag while distributing the code to production.


tick




app.config(['$compileProvider', function ($compileProvider) {

// disable debug info
  $compileProvider.debugInfoEnabled(false);
}]);





7. $digest over $apply  

$scope.$apply() is costly operation which typically trigger the digest cycle from root scope. Calling all the watchers to recheck and update the value.

We should use $scope.$digest() instead of $scope.$apply() when we know the $scope changes are needed to update in the
child node. Because $digest() will propagate the update downwards through child node from where it started. 
  

8. $interval and $timeout

Do not use the standard JavaScript setTimeout and setInterval function over Angular wrappers functions such as$timeout and $interval to avoid manually calling $scope.$apply().

These wrapper functions internally call $scope.$apply when handler is completed execution. One important thing to take
care of setting $interval or $timeout is setting optional invokeApplly parameter.

By default the third parameter is set to true which indicated angular engine to trigger $scope.$apply internally.
InvokeApplly parameter should set to false explicitly if there are no $scope updating is required.







tick

cross

$timeout(function(){
   // Snippet here will not
  // trigger digest   cycle
},
4000,
true);

// This function change the scope we leave the invokeApply to default value.


$interval(function(){
   $scope.name = ‘hello’;
},
4000);



function timerCallback(){
   // Snippet here not updating $scope
}


$timeout(timerCallback,4000,true);

$interval(timerCallback,4000,true);





9. Unregister Watchers and Destroy Polling

$watch() function is used to create custom watchers in application to do some operation based on model changes.
When this watch is registered and called it returns a callback function.

This function holds unregistering instruction for the respective watchers. Unregistering must be done calling this
function to avoid the memory leak.

Similarly $timeout and $interval ids must be cleared using $timeout.cancel() function after its usage and scope destroy.