1822nikki
1822nikki

Reputation: 21

Protractor wait for event

During an it... will do something.... function test on an angular coded website, I have a counter field, that increments when a given job completes its background task.

How can i get protractor to wait till the counter goes from 0 to 1?

I have tried browser.wait, onprepare and isdisplayed but the time varies on the job to complete.

Basically, I want the test to do the following: login to site follow some button clicks to submit a job verify counter is 0 and when job is complete, wait for counter to be 1 Then continue other test actions

Thanks

Upvotes: 2

Views: 1770

Answers (2)

Gaurav
Gaurav

Reputation: 1233

You can write your own custom function that will verify the counter value. This custom function could be passed to browser.wait function.

Assuming following are the files:

HTML file

<html ng-app="myApp" ng-controller="MainController">

<head>
  <title>{{title}}</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
  <script src="src/app.js"></script>
</head>

<body>

  <div ng-controller="MyController">

    <div class="main">{{data}}</div>

    <div class="counter">{{counterVal}}</div>

    <button class="counter-btn" ng-click="increaseCounter()">Increase Counter</button>

  </div>
</body>

</html>

JS(Angular) file

angular.module('myApp', [])
  .controller('MainController', MainController)
  .controller('MyController', MyController);

function MainController($scope) {
  $scope.title = 'Protractor test';
}

function MyController($scope, $timeout) {

  $scope.data = 'Hi!';
  $scope.counterVal = 0;

  $scope.increaseCounter = function () {

    // Async call, can be a network call.
    $timeout(function () {
      $scope.counterVal++;
    }, 1000);
  }

}

Protractor test file

describe('localhost test page', function () {

  it('should open webpage', function () {

    browser.get('http://localhost/angularjs/index.html');

    expect(element(by.css('.main')).getText()).toEqual('Hi!');
    expect(element(by.css('.counter')).getText()).toEqual('0');

    // Click the button.
    element(by.css('.counter-btn')).click();

    browser.wait(waitForCounterIncrease('1'));

    // Click again
    element(by.css('.counter-btn')).click();

    browser.wait(waitForCounterIncrease('2'));

  });

  // This is the custom funtion.
  // Note: If condition is not met, this function will timeout based on the settings.
  function waitForCounterIncrease(val) {

    return function () {
      var deferred = protractor.promise.defer();
      element(by.css('.counter')).getText()
        .then(function (counterVal) {
          console.log(counterVal)
          if (counterVal === val) {
            deferred.fulfill(counterVal);
          }
        });
      return deferred.promise;
    }
  }

});

If you run the above test, it should pass verifying the counter values.

Upvotes: 1

AdityaReddy
AdityaReddy

Reputation: 3645

You can make Protractor halt for any non-browser action by handling the execution flow using done. There is a beatiful answer by @cnishina here on the same but in a different context

describe('Step 1:Log in and wait for Job to complete', function _loginTo() {
    it('wait for Job to finish', function _setupStart(done) {
         //Regular Protractor Commands
         doLogin();
         submitJob();

         //Initiate the wait function. Wait till watever the state you need
         waitForJobToBeFinished().then(function(){
         done();
         }) 
    });
});

Upvotes: 0

Related Questions