Close Modal with Capybara
Asked Answered
F

2

6

I have a modal that closes when its overlay div is clicked. The overlay extends over the entire page but underneath the modal itself. I want to close this modal in my tests, and it's important that it closes when the overlay is clicked.

# modal, simplified
<div class="modal-container" id="modal">
  <div class="overlay"></div>
  <div class="content">Content</div>
</div>

When the modal closes, its style tag reads "display: none"

# modal, closed
<div class="modal-container" id="modal" style="display:none;">
  <div class="overlay"></div>
  <div class="content">Content</div>
</div>

I have not been able to close this modal in Capybara. I have tried:

1. page.execute_script("$('.overlay').trigger('click')")
2. page.evaluate_script("$('.overlay').trigger('click')")
3. find('.overlay').trigger('click')
4. page.driver.click(10, 10)

Options 1 and 2 both work when I run them in the browser console, but not in my tests.

When I pry in my test, I find this:

find('.overlay')
=> #<Capybara::Element tag="div">
page.has_content?("modal content")
=> true
find('.overlay').trigger('click')
=> "click"
find('.overlay')
Capybara::ElementNotFound: Unable to find css ".overlay"
page.has_content?("modal content")
=> true

Sleeping hasn't helped, either:

sleep(3)
page.evaluate_script("$('.overlay').trigger('click')")
sleep(3)
display = page.execute_script("document.getElementById('modal').style.display")

expect( display ).to eq("none")

Any thoughts?

RSpec 2, Capybara, Poltergeist 1.5.1

Fission answered 15/10, 2014 at 3:54 Comment(0)
T
3

The most likely problem is that when you're manually doing this in pry, you're slow enough that the overlay's click event has been added by the time you click it, hence it causes the modal to disappear. Your tests are probably executing fast enough that the overlay is getting clicked before the click event is added.

You're either going to need to add an explicit sleep(n) before clicking it (not the best solution) or find some way of programmatically determining when the page is ready for the overlay to be clicked.

Teratoid answered 15/10, 2014 at 14:16 Comment(1)
Thanks, @Matt. I tried sleeping for 3 seconds before executing and 3 seconds after, before checking, and even that hasn't helped this work. I've updated my question with that attempt, though.Fission
C
2

This worked for me:

page.evaluate_script("$('#ModalID').modal('hide')")
Chinch answered 20/10, 2017 at 10:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.