4

I've got a page which displays modal box from UI Bootstrap. My protractor test then clicks a button in the modal which closes it, the test then clicks another button on the page.

The problem is that there is nothing waiting until the modal actually disappears so quite often is tries to click the button on the page but fails because the modal backdrop is still covering the page.

Currently my code to close the modal looks like this:

@When /^I click button in modal with class "([^"]*)"$/, (className, callback) ->
    element(By.css '.modal-dialog').
        element(By.css 'button.' + className).
        click().
        then(callback)

Any idea how to wait until the modal disappears before triggering the callback?

amphetamachine
  • 27,620
  • 12
  • 60
  • 72
tomphp
  • 307
  • 1
  • 4
  • 10
  • I had a very similar issue that seemed to be related to the ui bootstrap modal using css transitions, and protractor didn't seem to be able to clearly tell when elements within the modal were truly available or not, including whether or when they had left the page. Disabling the css transitions helped significantly with test stability: http://stackoverflow.com/a/32264842/446030 – JcT Aug 28 '15 at 07:29

1 Answers1

5

A dirty trick, but it works for me : do an explicit call to waitForAngular() and remove fade class on Bootstrap modal. This will wait for your Protractor instructions (example : a click on a button to display the modal) and remove undesirable fade effect.

browser.waitForAngular();
browser.executeScript("$('.modal').removeClass('fade');");
ersefuril
  • 809
  • 9
  • 16
  • Your users aren't going to enter javascript, so why is this ok for your tests? – Jacob Brewer Aug 22 '16 at 20:53
  • I don't get it, what do you mean ? The question from this post was about solving a Protractor issue, not about user entering javascript. – ersefuril Aug 23 '16 at 14:26
  • A good E2E test should only interact with your page like as a user would. Your user will not be able to remove the fade class from a modal. You would be better off waiting for the fade to be removed by the application itself. Personally I'm ok with a test waiting indefinately for the 'fade' to remove and fail by timeout, because a user would also wait a while then give up. – Jacob Brewer Sep 16 '16 at 16:04
  • Before I read the comment by @ersefuril, I attempted using a promise like `EC.stalenessOf(buttonOnTheModal)`, which didn't work. When I replaced that with `browser.waitForAngular()`, *without* the `executeScript` call, my test worked like expected. – david-err Dec 10 '16 at 20:04