0

I am working on Protractor for testing the Angular JS application. I have written a code to read the data from excel sheet.My scenario is like I have a end to end flow that should execute.The code will take the URL,UserName and Password from the excel sheet and will execute the entire flow. Than again it will iterate the other value. But its not going into the loop.

My code is:

    var Excel = require('exceljs');
    var XLSX = require('xlsx');
    var os = require('os');
    var TEMP_DIR = os.tmpdir();
    var wrkbook = new Excel.Workbook();

    //---------------------Duration as Days------------------------------------------
    describe('Open the clinicare website by logging into the site', function () {
      it('IP Medication Simple flows for Patient Keerthi for Days,Weeks and Months', function () {
        console.log("hello6");
        browser.driver.manage().window().maximize();
        var wb = XLSX.readFile('E:\\LAM WAH EE_Testing Enviornment\\IP_Medication_Flow\\Patients_Entry.xlsx');
        var ws = wb.Sheets.Sheet1;
        var json = XLSX.utils.sheet_to_json(wb.Sheets.Sheet1);
        console.log("json", json);  

        //var json = XLSX.utils.sheet_to_json(wb.Sheets.Sheet1);
        //console.log("json", json);

        for(var a = 0; a < json.length ; a++){           
          console.log("Test_URL", json[a].Test_URL);
          console.log("User_Name", json[a].User_Name);
          console.log("Password", json[a].Password);
          browser.get(json[a].Test_URL); 

          console.log("hello10");

          //Perform Login:UserName 
          element(by.model('accessCode')).sendKeys(json[a].User_Name); 
          browser.sleep(6000);
          // browser.driver.sleep(6000);

          //Perform Login:Password 
          element(by.model('password')).sendKeys(json[a].Password); 
          browser.sleep(6000);

          //Hospital Name
          element(by.cssContainingText('option', 'HLWE')).click();
          browser.sleep(6000);


          //Perform Login:LoginButton 
          element(by.css('.btn.btn-primary.pull-right')).click(); 
          browser.sleep(6000);


          //Clicking on Admitted Tab
          element(by.xpath("//span[contains(text(),' Admitted(25)')]")).click();
          browser.sleep(6000);
          // browser.driver.sleep(6000);


          //Clicking on First Admitted Patient
          element(by.cssContainingText('span.clearfloat', '35690')).element(by.xpath('//*[@id="searchPatientImgAdmittedF"]')).click();
          jasmine.DEFAULT_TIMEOUT_INTERVAL = 600000;
          // browser.sleep(600);


          //Clicking anywhere to proceed
          element(by.xpath('/html/body/div[3]/div[1]/div[16]/div[1]/div/table[4]/tbody/tr[2]/td/div/div/div[3]/table/tbody/tr[1]/td[3]')).click();
          jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
          browser.sleep(800);

Anyone's help is appreciated. Thanks in advance.

cnishina
  • 5,016
  • 1
  • 23
  • 40
Vinee
  • 11
  • 2
  • 10
  • When calling XLSX, they these call async? – cnishina Mar 09 '18 at 06:23
  • Sorry I could not get you. Can you please elaborate what you are asking – Vinee Mar 09 '18 at 07:34
  • Is there any output from the console log? Is it returning a promise that you need to resolve to read the file? – cnishina Mar 09 '18 at 08:42
  • Yes I have given 3 entries in the excel sheet. So its printing all the 3 entries and then its printing: Test_URL undefined User_Name ` Password undefined F Failures: 1) Open the clinicare website by logging into the site IP Medication Simple flows for Patient Keerthi for Days,Weeks and Months Message: Failed: ENOENT: no such file or directory, open 'E:\LAM WAH EE_Testing Enviornment\IP_Medication_Flow\Patients_Enties.xlsx' Stack: – Vinee Mar 09 '18 at 10:25
  • My concern is that after printing the first entry it should run the whole test case then it should take the second entry and then 3rd. But after execution of the test case it is taking and printing all the entries at once without running the complete test case. And at 4th time its giving undefined error. – Vinee Mar 09 '18 at 10:28
  • Can you post a sample of the `json` object? Will be easier to see what is happening if you can add that. Obviously just use sample data but being able to see the format of your object will help solve this one. – tehbeardedone Mar 09 '18 at 14:52
  • Next question, what does your Excel spreadsheet look like? Are the column names "Test_URL", "User_Name", and "Password"? Without putting any PII data on the comment thread, if you were to print out `console.log(json[0])` would it look like `{ Test_URL: "http://some_url", User_Name: "foo", Password: "Bar" }`? – cnishina Mar 09 '18 at 19:43
  • Oh okay, back up.... the problem is right there in the 4th comment, the file path is something that cannot be identified. I have an answer. – cnishina Mar 09 '18 at 20:16

2 Answers2

0

This because Protractor API execute Async, but the For loop execute Sync. Get detail explain from here, which is same issue as yours.

To fix your issue, we can use javascript closure.

 for(var a = 0; a < json.length ; a++) {

    (function(a){

        console.log("Test_URL", json[a].Test_URL);
        console.log("User_Name", json[a].User_Name);
        console.log("Password", json[a].Password);
        browser.get(json[a].Test_URL); 

        console.log("hello10");

        //Perform Login:UserName 
        element(by.model('accessCode')).sendKeys(json[a].User_Name); 
        browser.sleep(6000);
        //  browser.driver.sleep(6000);

        //Perform Login:Password 
        element(by.model('password')).sendKeys(json[a].Password); 
        browser.sleep(6000);

        ...

    })(a)     

}
yong
  • 13,357
  • 1
  • 16
  • 27
  • This is an unusual way of attempting to work around async and how Protractor methods sync async webdriver promises. My guess is that this probably does not work either. – cnishina Mar 09 '18 at 19:57
0

Alright initially confused with the 'exceljs' node module. It is not used in your test. I think the major problem here is that the file does not exist.

readFile and ENOENT

The first thing of the readFile is an alias for readFileSync which calls readSync which calls (probably) read_binary which offloads to node's fs.readFileSync. More than likely the fs.readFileSync is throwing the ENOENT because the path does not exist.

Looking at your path, you might need a backslash before your spaces.

var wb = XLSX.readFile('E:\\LAM\ WAH\ EE_Testing Enviornment\\IP_Medication_Flow\\Patients_Entry.xlsx');

It could be a good practice to get the file path with path.resolve prior to calling the read file method.

var path = require('path');
var patientEntryFilePath = path.resolve('E:\\LAM\ WAH\ EE_Testing Enviornment\\IP_Medication_Flow\\Patients_Entry.xlsx');
console.log(patientEntryFilePath);
var wb = XLSX.readFile(patientEntryFilePath);

Additional comments and thoughts about the original code snippet

Some additional comments about the code snippet from the original question. Maybe considerations for future cleanup.

  1. Think about using a beforeAll or beforeEach for setting your browser driver window size and reading in a file. Reading in the file once is potentially a time and resource saver.

    describe('Open the clinicare website by logging into the site', function () {
      var json = null;
    
      beforeAll(() => {
        browser.driver.manage().window().maximize();
        var wb = XLSX.readFile('E:\\LAM\ WAH\ EE_Testing Enviornment\\IP_Medication_Flow\\Patients_Entry.xlsx');
        var ws = wb.Sheets.Sheet1;
        json = XLSX.utils.sheet_to_json(wb.Sheets.Sheet1);
      });
    
    
      it('IP Medication Simple flows for Patient Keerthi for Days,Weeks and Months', function () {
        console.log("json", json); 
        ...
    
  2. Looking at your test that it is a login and it appears to have the same flow, you really only need to test this once. The for loop is acceptable since the json file is resolved and each line is executed in the control flow that Protractor uses.

  3. Avoid using xpath. It is better to find elements by css or id or partial path. In the developer adds an additional div in the list of div's will break your test, making your test more fragile and require more upkeep.

cnishina
  • 5,016
  • 1
  • 23
  • 40