AngularJS example MotoAds end-to-end tests

E2E (end-to-end) tests result: Application folders tree:
In previous post I showed how to write and run unit tests. Now, I will present how to test DOM manipulation or the wiring of our application. Angular Scenario Runner which simulates user interactions that will help us to do that.

Recall adverts.html code which we should know to simulate user interaction: <div class="row-fluid"> <div class="span3"> <h4>Adverts</h4> <div class="ma-left-filter-panel"> <accordion close-others="oneAtATime"> <accordion-group heading="{{brand.name}}" ng-repeat="brand in brands"> <ul ng-repeat="model in brand.models"> <li><a href="" ng-click="addBrandModelFilter(brand, model)">{{model.name}}</a></li> </ul> </accordion-group> </accordion> </div> </div> <div class="span9"> <div class="ma-top-filter-panel"> <h4>Adverts search</h4> <form> <div class="row-fluid"> <div class="span4"> <label>Country</label> <select ng-model="filter.country" ng-options="c.name for c in countries"> <option value=""></option> </select> </div> <div class="span4"> <label>Region</label> <select ng-model="filter.region" ng-options="r.name for r in filter.country.regions"> <option value=""></option> </select> </div> <div class="span4"> <label>Year of production</label> <input ng-model="filter.yearFrom" class="input-small" min="1980" max="2013" ng-minlength="4" ng-maxlength="4" type="number" placeholder="From"> <input ng-model="filter.yearTo" class="input-small" min="1980" max="2013" ng-minlength="4" ng-maxlength="4" type="number" placeholder="To"> </div> </div> <div class="row-fluid"> <div class="span12"> <span ng-show="isAnyFilter()">Filters:</span> <div class="ma-chosen-filter-div"> <span ng-show="filter.modelName">{{filter.brandName}} {{filter.modelName}} <i class="icon-remove-sign icon-white" ng-click="filter.brandName = null; filter.modelName = null"></i></span> <span ng-show="filter.country.name">{{filter.country.name}} <i class="icon-remove-sign icon-white" ng-click="filter.country = null; filter.region = null"></i></span> <span ng-show="filter.region.name">{{filter.region.name}} <i class="icon-remove-sign icon-white" ng-click="filter.region = null"></i></span> <span ng-show="filter.yearFrom">{{filter.yearFrom}} <i class="icon-remove-sign icon-white" ng-click="filter.yearFrom = null"></i></span> <span ng-show="filter.yearTo">{{filter.yearTo}} <i class="icon-remove-sign icon-white" ng-click="filter.yearTo = null"></i></span> </div> <a ng-show="isAnyFilter()" href="" ng-click="removeAllFilter()">Remove all</a> </div> </div> </form> </div> <div> <div class="row-fluid"> <div class="span4"> <h4>Adverts found ({{adverts.length}})</h4> </div> <div class="offset3 span5"> <form class="form-inline"> <label>Sort by</label> <select ng-model="sortByCol" ng-options="s.name for s in sortByCols"> <option value=""></option> </select> </form> </div> </div> <table class="table table-striped ma-advert-table"> <tr class="ma-advert-table-headers"> <th>Image/Country/Region</th> <th>Brand</th> <th>Model</th> <th>Year</th> <th>Price ($)</th> </tr> <tr class="ma-advert-table-row" ng-repeat="advert in adverts| orderBy:sortByCol.key"> <td><a href="#/"><img class="img-rounded" ng-src="{{advert.imageUrl}}"></a><br/> <span>{{advert.countryName}}, {{advert.regionName}}</span></td> <td>{{advert.brandName}}</td> <td>{{advert.modelName}}</td> <td>{{advert.year}}</td> <td>{{advert.price}}</td> </tr> </table> </div> </div> </div>
We should write the simple html page for running unit tests (runner.html): <html lang="en"> <head> <title>End2end Test Runner</title> <meta charset="utf-8"> &lt;script src="../../app/lib/angular/angular-scenario.js" ng-autotest&gt;&lt;/script&gt; &lt;script src="scenarios.js"&gt;&lt;/script&gt; </head> <body> </body> </html>
When everything is ready we can start writing tests in scenarios.js.

Step 1
Navigate web browser to index.html which route to adverts.html view:
'use strict';

describe('MotoAds App', function() {

  describe('Adverts view', function() {

    beforeEach(function() {
      browser().navigateTo('../../app/index.html#/');
    });

    // TEST WILL BE HERE

  });
});
]]>

Step 2
We write first E2E test - filtering by brand and model on real data:
    it('should filter on brand and model link click', function() {
      expect(repeater('.ma-advert-table-row').count()).toBe(29);
      
      element('.accordion-group:eq(0) ul:eq(0) a').click();
      expect(repeater('.ma-advert-table-row').count()).toBe(4);
      
      element('.accordion-group:eq(3) ul:eq(0) a').click();
      expect(repeater('.ma-advert-table-row').count()).toBe(2);
    });
]]>

Step 3
We write second E2E test - filtering by country and region:
    it('should filter on country and region select choose', function() {
      expect(repeater('.ma-advert-table-row').count()).toBe(29);
      
      select('filter.country').option('Germany');
      expect(repeater('.ma-advert-table-row').count()).toBe(20);
      
      select('filter.region').option('Bavaria');
      expect(repeater('.ma-advert-table-row').count()).toBe(18);
    });
]]>

Step 4
We write third E2E test - filtering by year:
    it('should filter on yearFrom and yearTo type', function() {
      expect(repeater('.ma-advert-table-row').count()).toBe(29);
      
      input('filter.yearFrom').enter('2010');
      expect(repeater('.ma-advert-table-row').count()).toBe(16);
      
      input('filter.yearTo').enter('2011');
      expect(repeater('.ma-advert-table-row').count()).toBe(14);
    });
]]>

Step 5
We write fourth E2E test - sorting by year:
    it('should sort by year', function() {
      expect(repeater('.ma-advert-table-row').count()).toBe(29);
      
      select('sortByCol').option("Year");
      expect(element('.ma-advert-table-row:eq(0) td:eq(3)').text()).toContain('2005');
      expect(element('.ma-advert-table-row:eq(28) td:eq(3)').text()).toContain('2012');
    });
]]>

Step 6
We run E2E test by typing in web browser URL http://localhost:8000/test/e2e/runner.html (motoAds application must be run on the web server). In web browser we should see the same as the screenshot E2E (end-to-end) tests result.

If you want to run this example on your computer, you can download sources from GitHub.

Any comment would be highly appreciated.

Komentarze

Popularne posty z tego bloga

Java ESL program for connecting to the FreeSWITCH

AngularJS example MotoAds more advanced than the tutorial on angularjs.org

Java program for connecting to the FreeSWITCH XML-RPC