How to work around selenium chrome missing clicks to elements which are just barely visible

Chromedriver (or selenium-webdriver?) will not reliably scroll elements into view before clicking them, and actually not click the element because of that.

We've seen this happen for elements which are just barely in the viewport (e.g. the upper 2px of a 40px button). Our assumption is that the element is considered visible (i.e. Capybara::Selenium::ChromeNode#visible? returns true for such elements) but the Selenium driver wants to actually click the center of the element which is outside of the viewport.

We don't know who exactly is at fault here. We've seen this (or a similar issue) in the past and while it seems like it was gone for a few versions, at least the current version of Chrome and Chromedriver (both 117.0.5938.92) are affected.

If you can't wait for an official fix, here is a monkey-patch for Capybara::Node::Element#click that will use the Element#scrollIntoViewIfNeeded JavaScript function before clicking any element:

Capybara::Node::Element.prepend(Module.new do
  def click(*keys, **options)
    execute_script('this?.scrollIntoViewIfNeeded()') if driver.is_a?(Capybara::Selenium::Driver)
    super
  end
end)

It's not great, but works well for us.
The performance impact of doing that seems to be negligible.

Arne Hartherz 7 months ago