Protractor - Style Guide For Protractor



In this chapter, let us learn in detail about style guide for protractor.

Introduction

The style guide was created by two software engineers named, Carmen Popoviciu, front-end engineer at ING and Andres Dominguez, software engineer at Google. Hence, this style guide is also called Carmen Popoviciu and Google’s style guide for protractor.

This style guide can be divided into the following five keypoints −

  • Generic rules
  • Project Structure
  • Locator strategies
  • Page Objects
  • Test suites

Generic Rules

The following are some generic rules that must be taken care while using protractor for testing −

Do not end-to-end test what has been already unit tested

This is the very first generic rule given by Carmen and Andres. They suggested that we must not perform e2e test on the code that already been unit tested. The main reason behind it is that the unit tests are much faster than e2e tests. Another reason is that we must have to avoid duplicate tests (don’t perform both unit and e2e testing) for saving our time.

Use only one configuration file

Another important point recommended is that we must have to use only one configuration file. Do not create configuration file for each environment you are testing. You can use grunt-protractor-coverage in order to set up different environments.

Avoid using logic to your test

We must have to avoid using IF statements or FOR loops in our test cases because if we do so then the test may pass without testing anything or it may run very slow.

Make the test independent at file level

Protractor can run the test parallelly when sharing is enabled. These files are then executed across different browsers as and when they become available. Carmen and Andres recommended to make the test independent at least at file level because the order in which they will be run by protractor is uncertain and moreover it is quite easy to run a test in isolation.

Project Structure

Another important key point regarding the style guide of Protractor is the structure of your project. The following is the recommendation about project structure −

Groping e2e test in a sensible structure

Carmen and Andres recommended that we must group our e2e tests in a structure that makes sense to the structure of your project. The reason behind this recommendation is that the finding of files would become easy and the folder structure would be more readable. This step will also separate e2e tests from unit tests. They recommended that the following kind of structure should be avoided −

|-- project-folder
   |-- app
      |-- css
      |-- img
      |-- partials
         home.html
         profile.html
         contacts.html
      |-- js
         |-- controllers
         |-- directives
         |-- services
         app.js
         ...
      index.html
   |-- test
      |-- unit
      |-- e2e
         home-page.js
         home-spec.js
         profile-page.js
         profile-spec.js
         contacts-page.js
         contacts-spec.js

On the other hand, they recommended the following kind of structure −

|-- project-folder
   |-- app
      |-- css
      |-- img
      |-- partials
         home.html
         profile.html
         contacts.html
      |-- js
         |-- controllers
         |-- directives
         |-- services
         app.js
         ...
      index.html
   |-- test
      |-- unit
      |-- e2e
         |-- page-objects
            home-page.js
            profile-page.js
            contacts-page.js
         home-spec.js
         profile-spec.js
         contacts-spec.js

Locator Strategies

The following are some locator strategies that must be taken care while using protractor for testing −

Never use XPATH

This is the first locator strategies that is recommended in protractor style guide. The reasons behind the same is that XPath is requires lots of maintenance because markup is very easily subject to change. Moreover, XPath expressions are the slowest and very hard to debug.

Always prefer protractor-specific locators such as by.model and by.binding

Protractor-specific locators such as by.model and by.binding are short, specific and easy to read. With the help of them it is very easy to write our locator also.

Example

View

<ul class = "red">
   <li>{{color.name}}</li>
   <li>{{color.shade}}</li>
   <li>{{color.code}}</li>
</ul>

<div class = "details">
   <div class = "personal">
      <input ng-model = "person.name">
   </div>
</div>

For the above code, it is recommended to avoid the following −

var nameElement = element.all(by.css('.red li')).get(0);
var personName = element(by.css('.details .personal input'));

On the other hand, the following is recommended to use −

var nameElement = element.all(by.css('.red li')).get(0);
var personName = element(by.css('.details .personal input'));
var nameElement = element(by.binding('color.name'));
var personName = element(by.model('person.name'));

When no Protractor locators are available, then it is recommended to prefer by.id and by.css.

Always avoid text locators for frequently changing text

We must have to avoid text-based locators such as by.linkText, by.buttonText and by.cssContaningText because text for buttons, links and labels frequently change over time.

Page Objects

As discussed earlier, page objects encapsulate information about the elements on our application page and due to this help us write cleaner test cases. A very useful advantage of page objects is that they can be reused across multiple tests and in case if the template of our application has been changed, we only need to update the page object. Followings are some recommendations for page objects that must be taken care while using protractor for testing −

To interact with page under test, use page objects

It is recommended to use page objects to interact with the page under test because they can encapsulate information about the element on the page under test and they can be reused also.

Always declare one-page object per file

We should define each page object in its own file because it keeps the code clean and finding of things becomes easy.

At the end of page object file always uses a single module.exports

It is recommended that each page object should declare a single class so that we only need to export one class. For example, the following use of object file should be avoided −

var UserProfilePage = function() {};
var UserSettingsPage = function() {};
module.exports = UserPropertiesPage;
module.exports = UserSettingsPage;

But on the other hand, following is recommended to use −

/** @constructor */
var UserPropertiesPage = function() {};

module.exports = UserPropertiesPage;

Declare all the required modules at the top

We should declare all the required modules at the top of the page object because it makes module dependencies clear and easy to find.

Instantiate all page objects at the beginning of the test suite

It is recommended to instantiate all the page objects at the beginning of the test suite because this will separate dependencies from the test code as well as makes the dependencies available to all the specifications of the suite.

Do not use expect() in page objects

We should not use expect() in page objects i.e. we should not make any assertions in our page objects because all the assertions must be done in test cases.

Another reason is that the reader of the test should be able to understand the behavior of the application by reading the test cases only.

Advertisements