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

16,695

I think the problem is, that you are not waiting for asynchronous tasks. Most of the functions from browser object are asynchronous. Means that they are executed in different threads. So Whenever you call an asynchronous function it's not waited until it has finished. No, the next line of code is executed immediately. So in your particular case browser.get(), browser.wait() and element.click() functions are executed almost at the same time and it's never waited for one function to finish. They all run parallel and as the last function has finished your beforeEach() stops.

For waiting for asynchronous tasks you have to work with Promises Object. Following code would work in your test:

beforeEach(function() {
    browser.get(Utils.baseUrl + '/tickets').then(function () {
        // url '/tickets' opened now
        browser.wait(function() {
            return element(by.id('newTicket')).isPresent();
        }, 5000).then(function() {
            element(by.id('newTicket')).click();
           // next task here..
        });
    });
});

If you are using typescript this can be done in a very nice looking way, using await:

beforeEach(async function() {
    await browser.get(Utils.baseUrl + '/tickets');
    await browser.wait(function() { 
        return element(by.id('newTicket')).isPresent();
    }, 5000);
    await element(by.id('newTicket').click();
    // next task here..
});

When also using arrow functions it almost gets elegant:

beforeEach(async () => {
    await browser.get(Utils.baseUrl + '/tickets');
    await browser.wait(() => element(by.id('newTicket')).isPresent()),5000});
    await element(by.id('newTicket').click();
    // next task here..
});

If you have never heard about Promises just use your next day of work to learn them.

Share:
16,695

Related videos on Youtube

Alessandro Celeghin
Author by

Alessandro Celeghin

Updated on June 04, 2022

Comments

  • Alessandro Celeghin
    Alessandro Celeghin almost 2 years

    I am not able to test some features of my application because sometimes (very often) protractor test fails in the beforeEach function.

    Probably I am missing something important because the test fails randomly, I found some discussion about maximize the timeouts but it doesn't solve the problem.

    I see that the beforeEach doesn't get executed entirely when a test fails, only the first instruction is executed ( browser.get ) then the browser still on the same page all time.

    I am trying with allScriptsTimeout: 45000 this is some tests.

    describe('Rebus', function() {
      // mi posiziono nella lista ticket dopo ogni test e clicco su nuovo ticket
    
      beforeEach(function() {
    
        browser.get(Utils.baseUrl + '/tickets');
    
        browser.wait(function() {
          return element(by.id('newTicket')).isPresent();
        }, 5000);
        element(by.id('newTicket')).click();
    
    
    
        /**Ora passo dalla lista ticket a selezione blocco*/
        browser.wait(function() {
          return element(by.id('0')).isPresent();
        }, 5000);
    
        element(by.id('0')).click();
        element(by.id('newTicket')).click();
      });
    
      it('should buy ordinary ticket eurolevel 3', function() {
        // A questo punto dovrei essere arrivato al form del nuovo ticket
        selectArea('0');
        fillLicensePlate(5, 3);
        fillCountry();
        fillPassengers();
        setEntryDate(now);
        setExitDate(now.add(1, 'd'));
    
        // vai avanti al secondo step
        element(by.id('stepperNext')).click();
    
        browser.wait(function() {
          return element(by.id('daysOfStay')).isDisplayed();
        }, 5000);
    
        // Controllo che il prezzo sia corretto e controllo i giorni di permanenza
        element(by.id('daysOfStay'))
          .getText()
          .then(function(text) {
            expect(text).toContain('1');
          });
    
        element(by.id('amount'))
          .getText()
          .then(function(text) {
            expect(text).toContain('510', 'Errore nella tariffa');
          });
    
        browser.wait(function() {
          return element(by.id('save')).isDisplayed();
        }, 5000);
    
        // salvo il ticket
        element(by.id('save')).click();
    
        // Controllo che il prezzo sia corretto e controllo i giorni di permanenza
        browser.wait(function() {
          return element(by.name('price')).isPresent();
        }, 5000);
    
        element(by.name('price'))
          .getText()
          .then(function(text) {
            expect(text).toContain('510', 'Errore nella tariffa');
          });
    
        expect(element(by.name('addPay')).isPresent()).toBeTruthy(
          'Bottone non presente'
        );
      });
    
      it('should buy HOTEL ticket eurolevel €3', function() {
        // A questo punto dovrei essere arrivato al form del nuovo ticket
        selectArea('0');
        fillLicensePlate(5, 3);
        fillCountry();
        fillPassengers();
        setEntryDate(now);
        setExitDate(now.add(1, 'd'));
    
        // Campi opzionali
        setHotelField();
        setAgencyField();
    
        // vai avanti al secondo step
        element(by.id('stepperNext')).click();
    
        browser.wait(function() {
          return element(by.id('daysOfStay')).isDisplayed();
        }, 5000);
    
        // Controllo che il prezzo sia corretto e controllo i giorni di permanenza
        element(by.id('daysOfStay'))
          .getText()
          .then(function(text) {
            expect(text).toContain('1');
          });
    
        element(by.id('amount'))
          .getText()
          .then(function(text) {
            expect(text).toContain('210', 'Errore nella tariffa');
          });
    
        browser.wait(function() {
          return element(by.id('save')).isDisplayed();
        }, 5000);
    
        // salvo il ticket
        element(by.id('save')).click();
    
        // Controllo che il prezzo sia corretto e controllo i giorni di permanenza
        browser.wait(function() {
          return element(by.name('price')).isPresent();
        }, 5000);
    
        element(by.name('price'))
          .getText()
          .then(function(text) {
            expect(text).toContain('210', 'Errore nella tariffa');
          });
    
        expect(element(by.name('addPay')).isPresent()).toBeTruthy(
          'Bottone non presente'
        );
      });
    
  • Markus Ende
    Markus Ende almost 6 years
    Thanks for this hint. Angular CLI code scaffolding should really be improved, a flawed code like this should never be generated as a basic example..
  • Markus Ende
    Markus Ende almost 6 years
    As it seems, protractor does the waiting automatically using Web Driver Control Flow, see protractortest.org/#/async-await