This blog gives a detailed explanation of Installation, the project set up and designing functional automation test framework using Page object model using a hybrid framework (Key and data-driven).
A brief read about Protractor/Selenium: click here
1. Installation windows: https://nodejs.org/en/
Download the exe and install it on the system
2. Install protractor using cmd
npm install -g protractor
3. Install/update webdriver manager using the command: npm webdriver-manager update
Else install for all users using: npm install -g webdriver-manager
Check the versions of webdriver-manager and protractor
Components of Protractor
- Configuration file: conf.js
This file controls the execution, browser details, unit test framework details (for now, jasmine), environment details, selenium hub details, browser options, etc. This is the starting point of automation test runs.
- Spec files (*spec.js)
These are the test case file where all your automation test specs (set of test cases) are written.
Writing the first test case
Create a folder named FunctionalTests under Source.
Create folder structure as shown in the screenshot below
The folder structure looks like this
Functional tests: Main folder for functional tests
Data: Data required for test cases
Pages: Pages which defines web elements does operations on web pages
Specs: Test cases
conf.js: This is the file protractor uses to run test cases, define browsers, reports, environment details and other configurations required.
Sample Application (Application Under Test): Protractor practice website.
Configuration file :
Suites: describe Your Tests
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.
Specs are defined by calling the global Jasmine function it, which, like describe takes 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. The expect in Jasmine is an assertion that is either true or false. A spec with all true expectations is a passing spec. A spec with one or more false expectations is a failing spec.
More info on jasmine: click here
In the above example, we use describe (Protractor demo app): AngularJS application and it should have a title.
browser.get(‘url’) launches and navigates to the given url.
browser.getTitle() : returns a promise.
expect and toEqual are methods in Jasmine
More about promise : click here
Running the tests
In the command prompt, navigate to the path of conf.js file. In my case, i’ll navigate to D:\SampleFunctionalTests\FunctionalTests\src
Run the command protractor conf.js
When the test runs, you can notice that there is a green “.” which says the script has run and has passed
Identifying DOM objects/Web Elements in protractor
Apart from the object locators provided by selenium, protractor provides additional operators specifically to identify AngularJS controls using by model, by repeater, by buttontext, by bindings, by partialbuttontext.
In the given test application, for username, when user inspects, the html displays as follows
When you inspect on Username text field, you’ll see the dom object as :
There’s an attribute ng-model=”Auth.user.name”. So user can locate this element by model as
When you spy on login button
This element can be identified by
However, buttontext is not an ideal/effective way to identify elements. If the text changes/localisation changes, this would break the tests. In the above example, it’s a good idea to identify the element using xpath
Events and actions
After identifying the element, the next part is to perform(simulate) actions like “Click”, Enter text, drag, etc. on the element.
Now let us add all this to the test case after identifying password and username description fields. The test case file looks something like this :
After a user logs in, the user needs to verify that the home page is displayed. At this point, we have to verify that some elements under the home page are displayed.
There is a header element defined by var txtHeader = element(by.xpath(‘//h1[text()=”Home”]’)); we use isPresent() method provided by selenium to verify if the element exists.
Test case flow :
- Enter angular in username field.
- Enter password in the password field .
- Enter angular in username description field.
- Verify that login is successful by checking header element exists
- Click on logout link.
- Verify logout is successful by checking username textbox element exists
The test case looks like below
Running (protractor conf.js) this on cmd displays
The result is seen as 1 spec, 0 failures and it also shows a green dot(.) which states that the spec is passed.
Page Object Model Design
This is a design pattern for automating test cases. When a user launches an application, a page is displayed and user navigates to different pages through clicks and other events. Ideally, each page has some functionality and upon performing actions, a new page/Next page is displayed. In the above test case, we have written the whole code in a single file without defining any pages. This makes maintenance problematic
Consider this table
|Login||Username, Password, Username description, Login button||Click Elements, Enter text in username and other fields, click on login button||Login function|
|Home page||Header, Logout Button||Check if Header exists, Click on Logout Button||Logout Function|
So every page has a set of DOM objects on which user performs actions. User can group a set of actions in method for better structure, reusability, maintenance etc.
- In Page Object model, each page will have a class(js file in our case) which defines page and all its elements including the functions which the page allows.
- It’s basically a page Repository for the elements in the page.
- When the user navigates from the current page, the action/set of actions will return the next page to the calling function(Usually test case)
In the above example, there are two pages
- Login Page
- Home page
Create two js file named loginPage and homePage under Pages folder which defines the web elements and functions related to each page.
The login page has User Name, password, User name description, Login button and the functionality includes Login. Apart from the major functionality, the user can write functions to check if elements exist, enter texts in the text fields.
We can write function to login which is similar to this in LoginPage object
The actual function(Keywords) looks like
The definition of page objects is described at the beginning of the page
The entire Login Page with definitions looks like this and it’s pretty much self explanatory
The test case would look like this :
Test case using Page Object Model
Test case without using Page object Model
It’s always advisable to keep the data in different files/folders so that user can change the data before executing test cases without changing the details in the script
In the above examples, I’ve kept the environment and login data in a JSON file under Data folder. The file looks like this
Accessing these data in the test case
Advantages of using Page Object model
- Easier/Simpler to use compared to traditional designs
- Easy to maintain
- Builds object repository. In case an object locator is changed, we can change it at one place
- Gives a logical flow in the test case when the function returns a new page upon an event