Data Driven Testing In Protractor

While automating any web application we need to manage the test data as per the test cases. For this purpose, we need to use some persistent data storage like CSV or JSON. We are able to store the data and also we can add and modify that data whenever required.
 
The below image gives you a better picture. We can automate the web application using a protractor and the data required that we can store in the JSON file or files. And, we can retrieve that data while executing the test cases.
 
Here, we will try to understand how we can separate test data with test cases.
 
Data Driven Testing In Protractor
 
As we all know, Protractor is a JavaScript-based web automation testing framework which is basically developed to test Angular applications. If you are not aware of protractor, then please go through the below URLs to get more understanding on the protractor
 
https://www.protractortest.org
https://angular.io/guide/testing 
https://www.c-sharpcorner.com/article/introduction-to-protractor/
 
Now, let us try to develop one sample protractor and try to integrate a data-driven framework.
 
First, we need to create a protractor automation framework application. We can create a sample JavaScript application, then include any unit testing framework like Jasmine using npm install commands. Then, we can include Selenium or Protractor dependencies and then start the application. I have given you single lines for installation but don’t worry. We will try to install all this stuff with a single install. So for anyone who is not aware of it, the answer is Angular CLI. Please first install Angular CLI on your local machine using this command.
 
npm install -g @angular/cli
 
If you need to understand more of Angular CLI, then please go through the below link.
 
https://cli.angular.io/
 
Using Angular CLI, we can create not only Angular applications but also Protractor readymade projects where we can easily write automation test cases and run without much effort.
 
First, create a sample application using "ng new protractor-sample-app" command.
 
After successful installation, open the new folder protractor-sample-app.
 
Now, open the application in Visual Studio Code.
 
Data Driven Testing In Protractor
 
Using Angular CLI, you will get the whole project including Angular sample applications, along with unit test cases for each component and service and one separate e2e folder for Protractor.
 
Here, we will focus only on the e2e folder since src is related to Angular application development.
 
So now, we will try to understand the files inside the e2e folder.
 
First, open the protractor.e2e.json file.
  1. // Protractor configuration file, see link for more information  
  2. // https://github.com/angular/protractor/blob/master/lib/config.ts  
  3.   
  4. const { SpecReporter } = require('jasmine-spec-reporter');  
  5.   
  6. exports.config = {  
  7.  allScriptsTimeout: 11000,  
  8.  specs: [  
  9.    './src/**/*.e2e-spec.ts'  
  10.  ],  
  11.  capabilities: {  
  12.    'browserName''chrome'  
  13.  },  
  14.  directConnect: true,  
  15.  baseUrl: 'http://localhost:4200/',  
  16.  framework: 'jasmine',  
  17.  jasmineNodeOpts: {  
  18.    showColors: true,  
  19.    defaultTimeoutInterval: 30000,  
  20.    print: function() {}  
  21.  },  
  22.  onPrepare() {  
  23.    require('ts-node').register({  
  24.      project: require('path').join(__dirname, './tsconfig.e2e.json')  
  25.    });  
  26.    jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));  
  27.  }  
  28. };  
In the above json file I have highlighted specs, capabilities, baseUrl and framework.
 
We can change this node as per our application requirement.
 
Now, I am only going to change the base URL but before changing the URL, we can run the application using ng e2e command and find out if everything is working fine or not.
 
For this article, I will use https://angularjs.org/ as base URL. Here, we do have one sample Angular application available for automation testing.
 
Data Driven Testing In Protractor
 
Here, we can add small text and click the add button then new item gets added in the todo list.
 
Open the app.e2e-spec.ts folder.
 
The actual test case we need to write is here:
  1. import { AppPage } from './app.po';  
  2.   
  3. describe('workspace-project App', () => {  
  4.  let page: AppPage;  
  5.   
  6.  beforeEach(() => {  
  7.    page = new AppPage();  
  8.  });  
  9.   
  10.  it('should display website', () => {  
  11.    page.navigateTo();  
  12.  });  
  13. });  
app.po.ts
 
Here we can write the page object for the test case
 
I have specified the url:
  1. import { browser, by, element,protractor } from 'protractor';  
  2.   
  3. export class AppPage {  
  4.  navigateTo() {  
  5.    return browser.get('http://juliemr.github.io/protractor-demo/');  
  6.  }  
  7. }  
Again run the application ng e2e
 
You will get http://juliemr.github.io/protractor-demo/
 
Now, we try to automate this web application.
 
After adding the elements to app.po.ts file,
  1. import { browser, by, element,protractor } from 'protractor';  
  2.   
  3. export class AppPage {  
  4.  async navigateTo() {  
  5.    return await browser.get('http://juliemr.github.io/protractor-demo//');  
  6.  }  
  7.   
  8.  async firstTextEnterData(){  
  9.    await element(by.model('first')).sendKeys(1);  
  10.  }  
  11.   
  12.  async secondTextEnterData(){  
  13.    await element(by.model('second')).sendKeys(1);  
  14.  }  
  15.   
  16.  async gobuttonClick(){  
  17.    await element(by.id('gobutton')).click();  
  18.  }  
  19.   
  20.  async getResult(){  
  21.    return await element(by.binding('latest')).getText();  
  22.  }  
  23. }  
And app.e2e-spec.ts,
  1. import { AppPage } from './app.po';  
  2. import { async } from 'q';  
  3.   
  4. describe('workspace-project App', () => {  
  5.  let page: AppPage;  
  6.   
  7.  beforeEach(() => {  
  8.    page = new AppPage();  
  9.  });  
  10.   
  11.  it('should display angularjs website', async() => {  
  12.    await page.navigateTo();  
  13.    await page.firstTextEnterData();  
  14.    await page.secondTextEnterData();  
  15.    await page.gobuttonClick();  
  16.    await page.getResult().then((result) => {  
  17.      expect(result).toEqual('2')  
  18.    });  
  19.  });  
  20. });  
Here we have hardcoded the data.
 
Now, let us integrate data-driven framework in the protractor application.
 
Here I am going to store data in the JSON file.
 
For this purpose, we need to include some line of code in the tsconfig.json file.
 
In ”compilerOptions” add "resolveJsonModule": true
 
Now, create one data folder and inside that add new JSON file calc.json file.
  1. [{  
  2.    "num1":10,  
  3.    "num2":10,  
  4.    "result":20  
  5. },{  
  6.    "num1":100,  
  7.    "num2":100,  
  8.    "result":200  
  9. },{  
  10.    "num1":1,  
  11.    "num2":1,  
  12.    "result":2  
  13. }  
  14. ]  
Just copy paste the above JSON data in that file.
 
In the app.e2e-spec.ts file, import the JSON file.
  1. import * as calcJson from './data/calc.json';  
  2.  calcJson.forEach((item) => {  
We need to call the test cases and item is simple object of the list.
 
So, the actual changed code looks like below.
  1. calcJson.forEach((item) => {  
  2.    it('Calculator : ' + item.num1 + ' + ' + item.num2 + ' = ' + item.result, async () => {  
  3.      await page.navigateTo();  
  4.      await page.firstTextEnterData(item.num1);  
  5.      await page.secondTextEnterData(item.num2);  
  6.      await page.gobuttonClick();  
  7.      await page.getResult().then((result) => {  
  8.        expect(result).toEqual(item.result.toString())  
  9.      });  
  10.    });  
  11.  });  
And from the test case we are passing the test data to page object so we need to modify the firstTextEnterData and secondTextEnterData and we have to pass the data:
  1. async firstTextEnterData(num1) {  
  2.    await element(by.model('first')).sendKeys(num1);  
  3.  }  
  4.  async secondTextEnterData(num2) {  
  5.    await element(by.model('second')).sendKeys(num2);  
  6.  }  
This way we can integrate data driven testing in protractor.
 
Similarly, we can add multiple data files and integrate those with test cases as well.
 
I have uploaded the same application to GitHub.