0

I'm writing e2e tests for a large angular 4 project. I wrote a helper function to close a modal dialog if it exists. Previous operations might have automatically closed the dialog, based on conditional data, so I can't assume that a dialog is up.

function closeModal() {
    Util.logInfo('closing');
    $('.modal-backdrop').isPresent().then(exists => {
        if (exists) {
            < HANDLE CLOSING DIALOG HERE >
        }
    });
    Util.logInfo('closed outer');
}

This code works fine, but what I'm seeing is that when the modal is up, checking for the existence of the modal always takes 10 seconds. I've rewritten this block using element, element.all, .length, count(), isPresent, checking for elements on the dialog, and probably a few other ways I can't remember. No matter what I try, every time it takes a full 10 seconds for the promise to resolve when '.modal-backdrop' doesn't exist. If it does exist this code including my logic executes in about 0.2 seconds.

Modal not up:

13:06:47:431 -  ** closing
13:06:57:451 -  ** closed outer

Modal Up:

13:06:57:563 -  ** closing
13:06:57:705 -    -> action: waiting for NOT presence of element up to 5000ms
13:06:57:718 -  ** closed outer

This block gets called a lot, and probably 20% of the time it doesn't need to be closed (but I still need to call it just in case to prevent false failures), and it's adding about 30-40 seconds to each test run.

Is there anyway to speed this up, or at least temporarily change the timeout needed while in this block?

Mordred
  • 3,734
  • 3
  • 36
  • 55

1 Answers1

1

I think you are set implicitWaits in your code. I have answered similar question before, read it to understand how implicitWaits works - How does implicit wait of Protractor interact with explicit wait?

But in your case, this might help:

function closeModal() {
    Util.logInfo('closing');
    browser.manage().timeouts().implicitlyWait(0)
    $('.modal-backdrop').isPresent().then(exists => {
        if (exists) {
            < HANDLE CLOSING DIALOG HERE >
        }
    });
    // Setting back your implicit value here, i think it is 10 seconds?
    browser.manage().timeouts().implicitlyWait(10000)
    Util.logInfo('closed outer');
}

Idea is to disable implicit waits before looking for element that might not be present, and then restore it back. Notice that we are not waiting at all for presence of your modal window. It might appear with little delay, and isPresent will be passed already - so consider small wait as an option:

function closeModal() {
    browser.manage().timeouts().implicitlyWait(0)
    let modalPresent = protractor.ExpectedConditions.presenceOf($('.modal-backdrop')) 
    browser.wait(modalPresent, 1000).then(()=> {
        <handle modal is present state here>
        }, err=> {
        // Just skipping, if modal not present. This prevents promise to be rejected
    })
    // Setting back your implicit value here, i think it is 10 seconds?
    browser.manage().timeouts().implicitlyWait(10000)
}
Xotabu4
  • 3,063
  • 17
  • 29
  • 1
    That was exactly the issue. I disabled the implicit wait around the `isPresent()` and now it works flawlessly. – Mordred Aug 23 '17 at 19:45