11

I am trying to run data-driven testing using csv file in protractor:

I have created a read csv promise module:

    let readSync = async function (path1) {
    console.log(path1)
      const csv = require('csv-parser')
      const fs = require('fs')
      const results = [];
    
    
      function getIdRequest(path2) {
        console.log(path2)
        return new Promise((resolve, reject) => {
    
         
          fs.createReadStream(path2)
            .pipe(csv(path2))
            .on('data', (data) => results.push(data))
            .on('end', () => {
              resolve(results);
            })
        });
      }
      console.log(path1)
      return getIdRequest(path1);
    }
    // to get the request body 
    
      module.exports = readSync;

Now i am calling the same from my test file:

    let readCSV = require('../commons/readSync.js');
    
    describe('Validate stage 1 behaviour', function () {
    
      let testdata=await readCSV(browser.params.testFile);
    
      for (let a of testdata) {
     
        it('test {Regression} {Sanity} {Sanity}', async function () {
          //check title
          console.log("inside")
          await mainPage.goto();
          await mainPage.clickElement('inputField')

But i cannot use await inside describe, so I tried using :

    let readCSV = require('../commons/readSync.js');   
    
    describe('Validate stage 1 behaviour', function () {
    
      readCSV(browser.params.testFile).then(function(testdata){
    
      for (let a of testdata) {
        console.log("outside")
        it('test {Regression} {Sanity} {Sanity}', async function () {
          //check title
          console.log("inside")
        });
    
      }

but in this, 'it' function is not getting executed, its printing only 'outside'

Challenges

  1. Cannot use await inside describe as it accepts only synchronous function

  2. Cannot use promise.then(describe(function(){} because 'IT' and 'Describe' is not recognized when called inside the callback. I get 0 spec executed message.

  3. Tried calling the testdata in before hooks but this also fails as the for loop is outside the It block . So, the compiler tries to run for loop even before 'before hook' is executed .

  4. I tried using nested describe and calling await testdata in before each and before all . But even that fails with the same reason , refer: https://stackoverflow.com/q/48344674/6793637

Questions:

  1. So is there a better way to run data driven testing using csv in protractor ?

  2. Is there a way to synchronously make the suggest solution work?

  3. Why is describe or IT block doesn't work inside a callback ? Eg Promise.then(describe()) won't execute describe

3

2 Answers 2

9

Hi i found another csv module : csv-parse : https://csv.js.org/parse/ (Its used in postman)

const parse = require('csv-parse/lib/sync');

Use this module for data-driven testing instead of below-step

Below method is deprecated:

Made it work.

Please suggest any better ways if anyone knows:

Solution:

Install system-sleep module:

npm install system-sleep

.............Updated..........

Now run your tests as:

let testdata=readSync(browser.params.testFile);
var sleep = require('system-sleep');

describe('Validate dfsfdsf 1 behaviour', function () {

//Assign the value when promise gets resolved
//This is asynchronous so we will add a implicit wait
testdata.then(function(b){testdata=b}); 

//sleep till the test resolves
  while(typeof testdata.then === 'function'){
    sleep(1)
  }     

  for(let a of testdata){
    it('test {Regression} {Sanity} {Sanity}', async function () {
      console.log(a)
    });
  }

Update:

https://www.npmjs.com/package/csv-parser-sync-plus-promise

Happy days guys I have created an npm package for this, anyone is free to use it

Now data driven testing is as simple as :

let parser= require('csv-parser-sync-plus-promise');
let testdata = parser.readCsvSync(browser.params.testFile);



describe('Validate dfsfdsf 1 behaviour', function () {


  for(let a of testdata){
    it('test {Regression} {Sanity} {Sanity}', async function () {
      console.log(await parser.readCsvPromise(browser.params.testFile))
    });
  }
9
  • 1
    Sleep should never the solution, why not: testdata.then(function(b){ for(let a of b){ // code here}}); Jan 24, 2020 at 8:58
  • 1
    Or use async/await Jan 24, 2020 at 8:59
  • @NielsvanReijmersdal he please see my question , I tried that , but it and describe block is not being identified inside callback function
    – PDHide
    Jan 24, 2020 at 8:59
  • @NielsvanReijmersdal async doesn't work inside describe . Describe block supports only synchronous function . I can't keep it inside before hooks also because the for loop is outside the 'it' block and so will get executed before the 'before' hook get executed
    – PDHide
    Jan 24, 2020 at 9:02
  • Your example is missing async on the describe function, e.g. describe('Test Suite 1', async function(){ let testdata = await asyncMethod() Jan 24, 2020 at 9:02
0

A simpler approach using map function: (Considering testArray is an array of objects)

var testParams =testConfig.testArray;   
testParams.map(function(testdata) { 

   it('write your test here', function() { 
         console.log('Username: ',         
          testData.username); 
    });
});
1
  • Hi the issues here is of getting the test array :) , if we get an array , then map or for or while any loop works .but the csv parse returns a promise that resolves to a array
    – PDHide
    Jan 25, 2020 at 11:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.