Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Close Modal with Capybara

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

like image 395
steel Avatar asked Oct 15 '14 03:10

steel


2 Answers

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.

like image 148
Matt Metzger Avatar answered Nov 14 '22 02:11

Matt Metzger


This worked for me:

page.evaluate_script("$('#ModalID').modal('hide')")
like image 28
Wojtek Kostański Avatar answered Nov 14 '22 00:11

Wojtek Kostański