6
votes

I have an e2e protractor test in my angular application. I've just run the exact same test several times in a row and it passed about 5% of the time, failing with the error in the screenshot below.

The Test:

it('should open the cart with the cart button in the header', () => {
    page.navigateTo('/calendar/day/(dmy:27-9-2018)');

    page.cartButton().click();

    expect(element(by.css('h2.cart-header')).isPresent()).toBe(true);
});

The chrome instance launched by protractor pauses shows that the button was clicked and the h2 element is present (see image at bottom).

What I have tried

  1. I have replaced the data in this component with mock data to eliminate async operations
  2. I have animations disabled
  3. I attempted to make this an async function: ... header', async () => { ...
  4. I have tried await(ing) the element: expect(await element(by.css('h2.cart...
  5. I have tried to browser.sleep(1000)
  6. I have tried a variety of assertions like .toBe(true), .toEqual(true), and .toBeTruthy()

What is causing this error, and how can I resolve it?

The error message: enter image description here

The element is present in the browser launched by protractor enter image description here

3
I have the same issue, did you figure this out? - Dev
I opened an issue on GitHub about this issue github.com/angular/protractor/issues/5151 - Dev
I did not, I ended up switching to cyress.io instead of protractor. - Nate May
Woooah Cypress is awesome! Thanks so much for sharing! Are you happy with it ? - Dev

3 Answers

0
votes

You can use Jasmine Callbacks to assert asynchronous behavior. Jasmine test provides additional parameter as callback argument. Once you are done with the assertions you can invoke the callback API.

Example:

it('should have a button element present', function(done) {
browser.get('http://juliemr.github.io/protractor-demo/');

var gobtn = element(by.id('gobutton'));

gobtn.isPresent().then( (result) => {
 expect(result).toBe(true);    
 done();
 });    
});    
-1
votes

Please use browser.ignoreSynchronization = true;

-1
votes

isPresent() returns promise that you need to resolve. Yes, use async() function + await to resolve it easily More of that, use ExpectedConditions module like that:

let cart = await element(by.css('h2.cart-header'))
await browser.wait(ExpectedConditions.visibilityOf(cart), 5000, "Cart is not visible even in 5 seconds!")