2

I have a series of tests, which close down modals and check to make sure the modal has disappeared. These are initially checked in Chrome, where they intermittently fail. Here is one such example (I have taken a similar approach elsewhere):

'use strict';
describe('Modal', function() {
    var page;

    beforeEach(function() {
    browser.get('/#/components');
    page = require('./modal');
    page.ermAddErrorBtn.click();
    page.ermAddErrorBtn.click();
    page.ermAddInfoBtn.click();
    });

    it('should close the modal on clicking the modals cross icon', function () {
    page.ermAlertBox.click().then(function() { //this just opens the modal
        browser.wait(protractor.ExpectedConditions.presenceOf(page.ermModalEl), 30000, 'Modal never appeared');
        browser.executeScript("$('.erm-modal').removeClass('fade');");
        page.ermModalCloseBtn.click().then(function () {
            browser.wait(protractor.ExpectedConditions.stalenessOf(page.ermModalEl), 30000, 'Modal never disappeared');
            expect(page.ermModalEl.isPresent()).toBe(false);
        });
    });
});
});

Intermittently the modal times out and never closes (which gives the Modal never disappeared message). Later on in our build pipeline, this also gets checked using PhantomJS. I have tried multiple versions of the code above and one or the other (Chrome/PhantomJS) has problems.

I suspect it might be some kind of mis-timing issue, where it's trying to close something that doesn't yet exist.

MDalt
  • 1,681
  • 2
  • 24
  • 46
  • Are you sure the close click worked? It could be the close button isn't completely/correctly hooked up when it gets clicked, and thus doesn't do anything. – P.T. Nov 12 '15 at 20:20

1 Answers1

2

It would be a shot in the dark anyway, but here are things to try:

  • wait for the close button to become clickable before clicking the button:

    var EC = protractor.ExpectedConditions;
    page.ermAlertBox.click().then(function() { //this just opens the modal
        browser.wait(EC.presenceOf(page.ermModalEl), 30000, 'Modal never appeared');
        browser.executeScript("$('.erm-modal').removeClass('fade');");
    
        browser.wait(EC.elementToBeClickable(page.ermModalCloseBtn), 30000, 'Close button has not become clickable');
        page.ermModalCloseBtn.click().then(function () {
             browser.wait(EC.stalenessOf(page.ermModalEl), 30000, 'Modal never disappeared');
             expect(page.ermModalEl.isPresent()).toBe(false);
         });
    });
    
  • move to the close button and then click:

    browser.actions().mouseMove(page.ermModalCloseBtn).click().perform().then(function () {
         browser.wait(EC.stalenessOf(page.ermModalEl), 30000, 'Modal never disappeared');
         expect(page.ermModalEl.isPresent()).toBe(false);
     });
    
  • check for invisibility instead of staleness:

    browser.wait(EC.invisibilityOf(page.ermModalEl), 30000, 'Modal never disappeared');
    
  • introduce an artificial delay just after the popup is opened:

    var EC = protractor.ExpectedConditions;
    page.ermAlertBox.click().then(function() { //this just opens the modal
        browser.sleep(1000);
    
        browser.wait(EC.presenceOf(page.ermModalEl), 30000, 'Modal never appeared');
        browser.executeScript("$('.erm-modal').removeClass('fade');");
    
        page.ermModalCloseBtn.click().then(function () {
             browser.wait(EC.stalenessOf(page.ermModalEl), 30000, 'Modal never disappeared');
             expect(page.ermModalEl.isPresent()).toBe(false);
         });
    });
    
  • turn off the synchronization and turn it on again (if this is an angular app under test):

    var EC = protractor.ExpectedConditions;
    browser.ignoreSynchronization = true;
    
    page.ermAlertBox.click().then(function() { //this just opens the modal
        browser.wait(EC.presenceOf(page.ermModalEl), 30000, 'Modal never appeared');
        browser.executeScript("$('.erm-modal').removeClass('fade');");
    
        page.ermModalCloseBtn.click().then(function () {
             browser.wait(EC.stalenessOf(page.ermModalEl), 30000, 'Modal never disappeared');
             expect(page.ermModalEl.isPresent()).toBe(false);
    
             browser.ignoreSynchronization = false;
         });
    });
    
  • disable all animations: see How to disable animations in protractor for angular js application

  • don't really use PhantomJS for end-to-end testing (50% less problems in your case)

Or, you may try combining the suggestions.

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195