In this chapter, let us learn in detail about style guide for protractor.
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 −
The following are some generic rules that must be taken care while using protractor for testing −
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.
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.
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.
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.
Another important key point regarding the style guide of Protractor is the structure of your project. The following is the recommendation about project 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
The following are some locator strategies that must be taken care while using protractor for testing −
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.
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.
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.
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.
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 −
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.
We should define each page object in its own file because it keeps the code clean and finding of things becomes easy.
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;
We should declare all the required modules at the top of the page object because it makes module dependencies clear and easy to find.
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.
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.