4
votes

The app I'm testing has some elements hidden initially. They will display via CSS when hovering over a separate element:

.thread_options{
  display: none;
}
.btn_thread_options:hover .thread_options{
  display: inline;
}

When you hover over the .btn_thread_options element, some links are displayed that I want Capybara to click on. Attempting to click these without doing anything using click_link "Send Response" gives me the error:

Failure/Error: click_link("Send Response")
Selenium::WebDriver::Error::ElementNotVisibleError:
  Element is not currently visible and so may not be interacted with

Trying to use other ways of clicking it like

page.execute_script("$('.btn_thread_options').trigger('mouseover')")

Doesn't work either (same result).

Nor does clicking the item first to try to force it to be moused over:

page.find(".btn_thread_options").click

Is there any way to get this to work correctly?

3
Do you need display: none? Or would setting the opacity to 0 suffice? If not, make a step that removes that calls jquery show() on it before the click, and hide() after. - Gazler
I don't think opacity: 0 would really work since the hidden elements will submit the form and I don't want people to accidentally click on what appears to be whitespace, and end up submitting something they didn't mean to. My work-around for now is to hide/show with jquery on mouseover and mouseout, as you mention... but it'd be nice if I could just keep it in the css :p - nzifnab

3 Answers

6
votes

This has been added to Capybara:

find(:css, "#menu").hover
3
votes

You could try displaying the element directly rather than mousing over.

page.execute_script("$('.thread_options').css('display','inline')")

Maybe also investigate the setting of ignore_hidden_elements. It defaults to false, but perhaps you have it set to true.

Or instead of display none, set the margin to a large negative value.

/* Move the element off the screen */
.thread_options{
  margin: -9999px 0 -9999px 0;
}
/* Set the desired display margins
.btn_thread_options:hover .thread_options{
  margin: 10px 0 10px 0;
}
1
votes

I found a way to simulate "mouse hover" using Capybara + the Selenium driver. This code is working for me:

module Capybara
  module Node
    class Element
      def hover
        @session.driver.browser.action.move_to(self.native).perform
      end
    end
  end
end