Search code examples
javascripttestingerror-handlingprotractorjasmine2.0

Protractor/Jasmine2 - async callback not invoked within specified timeout


I've struggled in problem with my e2e tests runs on selenium grid. Sometimes the tests are failed due to

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

Tried to solve it somehow bo changing defaultTimeoutInterval to higher value in protracotr.conf.js but in result the wait is longer but error is the same.

exports.config = {
    chromeOnly: true,
    chromeDriver: '../node_modules/.bin/chromedriver',
    framework: 'jasmine2',
    capabilities: {
        'browserName': 'chrome',
        shardTestFiles: true,
        maxInstances: 3
    },
    specs: ['../e2e/protractor/spec/*.js'],
    jasmineNodeOpts: {
        showColors: true,
        defaultTimeoutInterval: 30000,
        isVerbose: true,
        includeStackTrace: true,
    },

My example spec with failed test:

var LoginPage = require('../pages/login_page.js');
var UsersPage = require('../pages/users_page.js');
var WelcomePage = require('../pages/welcome_page.js');

describe('Test -> my test', function () {
  var loginPage;
  var EC = protractor.ExpectedConditions;
  var waitTimeout = 30000;

  function logIn() {
    loginPage.setUser('user');
    loginPage.setPassword('password');
    loginPage.login();
  }

  var clickOn = function (element) {
    browser.wait(EC.visibilityOf(element), waitTimeout).then(function () {
      element.click();
    });
  };

  beforeEach(function () {
    browser.ignoreSynchronization = true;
    loginPage = new LoginPage();
    browser.wait(EC.presenceOf(loginPage.userLogin), waitTimeout);
    logIn();
    var welcomePage = new WelcomePage;
    clickOn(welcomePage.usersButton);
  });

  afterEach(function () {
    var welcomePage = new WelcomePage();
    welcomePage.loginButton.click();
    welcomePage.logoutButton.click();
  });

  it('verifies counter on active tab', function () {
    var usersPage = new UsersPage();
    browser.wait(EC.visibilityOf(usersPage.firstRow), waitTimeout);
    usersPage.rowsCount.count().then(function (count) {
      expect(usersPage.activeTab.getText()).toContain('Active' + ' (' + count + ')');
    });
  });

Could anyone please provide any reasonable solution how to handle/avoid it and explain me why it occurs ?


Solution

  • I'd suggest to have a callback function in it block which will ensure that all the async code gets executed before that.For example:

    it('verifies counter on active tab', function (done) {
      var usersPage = new UsersPage();
      browser.wait(EC.visibilityOf(usersPage.firstRow), waitTimeout);
    
      usersPage.rowsCount.count()
        .then(function (count) {
            var text = usersPage.activeTab.getText();
            expect(text).toContain('Active' + ' (' + count + ')');
            done();
         });
    });