4

I am writing following JS code with protractor. Here I used a data.json file to read data for my test case. Within this test case, I am simple reading the item from this JSON and comparing it with a value that I am reading from the browser.

Problem that I am facing here is in my Expect statement,the value from JSON file is not correct.

Could any one please help to identify the problem here.

    var datafile = require('./Data.json')

    beforeEach(() => {
       browser.get("https://angularjs.org");  
     });  

    describe('Test Angular Page ', () => 
     {

       it('user name should be displayed correctly #try', () =>    
        { 

          var count = datafile.length; 

          for (var i=0; i<count; i++)  
              {
                var value = datafile[i];               
                browser.refresh();
                element(by.model('yourName')).sendKeys(value); 
                (element(by.binding('yourName'))).getText()
                        .then(function (txt)
                               {                                                                        
                           expect(txt).toEqual('Hello '+ value+'!'); 
                          //this is failing                             
})

       }       
      });  

below is my data.json

  [
   "A1","A2","A3"
  ]

below is some part of the result-

 1) Test Angular Page  user name should be displayed correctly #try
  Message:
   Expected 'Hello A1!' to equal 'Hello A3!'.
   Stack:
      Error: Failed expectation
       at D:\Demo_Protractor\test.spec.js:24:44
        at elementArrayFinder_.then (C:\User  s\leenasharma\AppData\Roaming\npm\node_modules\protractor\lib\element.ts:840:22)
    at ManagedPromise.invokeCallback_ (C:\Users\leenasharma\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:1366:14)
    at TaskQueue.execute_   (C:\Users\leenasharma\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2970:14)
    at TaskQueue.executeNext_ (C:\Users\leenasharma\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2953:27)
    at asyncRun (C:\Users\leenasharma\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2813:27)
    at C:\Users\leenasharma\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:676:7
    at process._tickCallback (internal/process/next_tick.js:109:7)
     Message:
        Expected 'Hello A2!' to equal 'Hello A3!'.
      Stack:
      Error: Failed expectation

2 Answers2

1
it('user name should be displayed correctly #try', () => {
  var count = datafile.length;
  var value, i;
  for (i = 0; i < count; i++) {
    value = datafile[i];
    browser.refresh();
    element(by.model('yourName')).sendKeys(value);
    (element(by.binding('yourName'))).getText()
      .then(function(txt) {
        expect(txt).toEqual('Hello ' + value + '!');
        //this is failing                             
      })
  }
});

var has only function level scope, there is no block level scope. Adding var value inside for loop doesn't create variables for each iteration. It will be hoisted to top of fuction with variable hoisting. Your getText() is asynchronous, by the time the then is called loop finishes and value become the value assignedd in last iteration ie. A3.

As a solution, you can use es6 let instead of var to declare your value. let will give you block level scope.

it('user name should be displayed correctly #try', () => {
  var count = datafile.length;
  for (let i = 0; i < count; i++) {
    let value = datafile[i];
    browser.refresh();
    element(by.model('yourName')).sendKeys(value);
    (element(by.binding('yourName'))).getText()
      .then(function(txt) {
        expect(txt).toEqual('Hello ' + value + '!');
        //this is failing                             
      })
  }
});

That being said, the latest versions of protractor/jasmine doesnt require getText() handled this way with then. Which version of angular, jasmine and protractor are you using?

expect() determines whether the parameter is a promise or not and executes asynchronously or synchronously based on that.

Why are you doing browser.refresh() on each iteration? The intention is not clear to me.

sabithpocker
  • 15,274
  • 1
  • 42
  • 75
  • regarding browser.refresh, I tried to do run this test case everytime on a fresh page. I could have used clear function also. experimenting and learning. The solution that Steve gave in his response below is also working. and now I am trying to relate both. Thanks again! – Pheonix68410 Jun 13 '17 at 10:48
1

The issue is that you are checking the value in a promise which is done async.

Refactor your code so expect() resolves the promise for you:

expect(element(by.binding('yourName'))).getText())).toEqual('Hello '+ value+'!');

More information can be found on the protractor documentation

Steverob2k
  • 445
  • 8
  • 11