Why can't Capybara find an element with selenium_chrome_headless but it can with selenium_chrome?

Viewed 154

I have a very simple integration test

visit root_path
click_link 'Sign In' # <--

which works with

Capybara.default_driver = :selenium_chrome

but fails with

Capybara::ElementNotFound: Unable to find visible link "Sign In"

when using

Capybara.default_driver = :selenium_chrome_headless # headless fails

And that is with

Capybara.default_max_wait_time = 10

And I have also tried

click_link 'Sign In', wait: 30

and

sleep 10
click_link 'Sign In'

version details

At the time of this writing I have the latest versions of capybara and selenium-webdriver:

-bash> gem list | grep capybara
capybara (3.34.0, 3.18.0)

-bash> gem list | grep selenium
selenium-webdriver (3.142.7, 3.142.0)
1 Answers

The default "headless" viewport is narrower than the "head" one, so the 'Sign In' link you're trying to click may be hidden beneath a "hamburger menu icon":

enter image description here

Thus, first click the burger:

visit root_path
find('#burger').click if Capybara.current_driver == :selenium_chrome_headless
click_link 'Sign In'

I figured this out by capturing a screenshot prior to trying to click the 'Sign In' link:

visit root_path
save_and_open_screenshot
click_link 'Sign In'

As an alternative, rather than check current_driver, you could instead check the window width as compared to the width at which the burger appears:

find('#burger').click if page.current_window.size[0] < 900
Related