New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using Capybara with headless chrome #1860

Closed
twalpole opened this Issue May 3, 2017 · 77 comments

Comments

Projects
None yet
@twalpole
Collaborator

twalpole commented May 3, 2017

There are currently 2 issues with using Capybara with headless chrome -

(Session info: headless chrome=60.0.3080.5)
(Driver info: chromedriver=2.29.461585

  1. Headless chrome appears not to support JS system modals ( alert, confirm, prompt)
    There is a workaround for this currently in testing

  2. Attempting to close a window raises a timeout error "failed to close window in 20 seconds" and doesn't close the window
    I can't think of any way to work around this issue, so window management won't really work until this is fixed in either chromedriver or chrome.

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole May 3, 2017

Collaborator

The workaround for JS system modals is PR #1859 which was merged into master - 12c1005

Collaborator

twalpole commented May 3, 2017

The workaround for JS system modals is PR #1859 which was merged into master - 12c1005

@jesperronn

This comment has been minimized.

Show comment
Hide comment
@jesperronn

jesperronn May 31, 2017

Could you please elaborate on how I set up and run with headless chrome?

I am curious to how you tested, and I'm eager to test myself

Could you please elaborate on how I set up and run with headless chrome?

I am curious to how you tested, and I'm eager to test myself

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole May 31, 2017

Collaborator

@jesperronn The setup Capybara uses for it's headless chrome tests is https://github.com/teamcapybara/capybara/blob/master/spec/selenium_spec_chrome.rb#L6

You should just need to pass args: ['headless'] as an option in your driver registration

Collaborator

twalpole commented May 31, 2017

@jesperronn The setup Capybara uses for it's headless chrome tests is https://github.com/teamcapybara/capybara/blob/master/spec/selenium_spec_chrome.rb#L6

You should just need to pass args: ['headless'] as an option in your driver registration

@gregsadetsky

This comment has been minimized.

Show comment
Hide comment
@gregsadetsky

gregsadetsky Jun 6, 2017

Hi,

I'm not involved in / don't use capybara (although I've heard great things) :-) but I did run into the same issues with headless Chrome while using Selenium using Python (alerts not being supported & driver.close() causing an issue)

Notes on how I resolved both:

  • I did implement the same approach as you did for alerts (#1859 - overriding window.alert to set a globally accessible variable and then checking if that variable had been set).

One difference is that we used a random variable name/value (in our single page app, setting a global "alert() has been called" variable could be a false positive as the 'true' value could be read a 2nd, 3rd, etc. time)

The second difference is that we ended up setting a cookie in the window.alert handler instead of setting a global variable -- the reason being, if you have an alert() call closely followed by a location.href change, the variable used to track if the alert happened or not will be lost; this won't happen with a cookie (we did use a random value for the cookie, for reasons explained above).

  • As for driver.close() causing "failed to close window in 20 seconds" errors, the solution was simpler: instead of using the 'stable' Chrome channel, we switched to the 'beta' channel. The current Linux version of Chrome Beta is 59.0.3071.83.

Cheers!

gregsadetsky commented Jun 6, 2017

Hi,

I'm not involved in / don't use capybara (although I've heard great things) :-) but I did run into the same issues with headless Chrome while using Selenium using Python (alerts not being supported & driver.close() causing an issue)

Notes on how I resolved both:

  • I did implement the same approach as you did for alerts (#1859 - overriding window.alert to set a globally accessible variable and then checking if that variable had been set).

One difference is that we used a random variable name/value (in our single page app, setting a global "alert() has been called" variable could be a false positive as the 'true' value could be read a 2nd, 3rd, etc. time)

The second difference is that we ended up setting a cookie in the window.alert handler instead of setting a global variable -- the reason being, if you have an alert() call closely followed by a location.href change, the variable used to track if the alert happened or not will be lost; this won't happen with a cookie (we did use a random value for the cookie, for reasons explained above).

  • As for driver.close() causing "failed to close window in 20 seconds" errors, the solution was simpler: instead of using the 'stable' Chrome channel, we switched to the 'beta' channel. The current Linux version of Chrome Beta is 59.0.3071.83.

Cheers!

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jun 6, 2017

Collaborator

@gregsadetsky Thanks for the info. The alert/prompt/confirm workaround was meant to be an easy solution until Chrome/chromedriver fixed the issue, however it looks like I will need to make it more robust since Chrome 59 has released with the issue still there.

Collaborator

twalpole commented Jun 6, 2017

@gregsadetsky Thanks for the info. The alert/prompt/confirm workaround was meant to be an easy solution until Chrome/chromedriver fixed the issue, however it looks like I will need to make it more robust since Chrome 59 has released with the issue still there.

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jun 6, 2017

Collaborator

@gregsadetsky Hmmm, I still see the window errors on MacOS with Chrome 59.0.3071.86 and chromedriver 2.29.461585 so it may be fixed in linux, but it's not fully fixed.

Collaborator

twalpole commented Jun 6, 2017

@gregsadetsky Hmmm, I still see the window errors on MacOS with Chrome 59.0.3071.86 and chromedriver 2.29.461585 so it may be fixed in linux, but it's not fully fixed.

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jun 6, 2017

Collaborator

@gregsadetsky and on linux (travis) we're seeing a different error now -

Selenium::WebDriver::Error::UnknownError:
unknown error: cannot get automation extension
from unknown error: page could not be found: chrome-extension://aapnijgdinlhnhlmodcfapnahmbfebeb/_generated_background_page.html
(Session info: headless chrome=59.0.3071.86)
(Driver info: chromedriver=2.29.461571 (8a88bbe0775e2a23afda0ceaf2ef7ee74e822cc5),platform=Linux 4.4.0-51-generic x86_64)

Any experience with that error?

Collaborator

twalpole commented Jun 6, 2017

@gregsadetsky and on linux (travis) we're seeing a different error now -

Selenium::WebDriver::Error::UnknownError:
unknown error: cannot get automation extension
from unknown error: page could not be found: chrome-extension://aapnijgdinlhnhlmodcfapnahmbfebeb/_generated_background_page.html
(Session info: headless chrome=59.0.3071.86)
(Driver info: chromedriver=2.29.461571 (8a88bbe0775e2a23afda0ceaf2ef7ee74e822cc5),platform=Linux 4.4.0-51-generic x86_64)

Any experience with that error?

@gregsadetsky

This comment has been minimized.

Show comment
Hide comment
@gregsadetsky

gregsadetsky Jun 6, 2017

Unfortunately, no. It seems like that version (59.0.3071.86) will be rolling out to the stable channel (we're successfully using 59.0.3071.83 on the beta channel). Ugh. :-)

Unfortunately, no. It seems like that version (59.0.3071.86) will be rolling out to the stable channel (we're successfully using 59.0.3071.83 on the beta channel). Ugh. :-)

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jun 6, 2017

Collaborator

@gregsadetsky "Ugh", yeah. Wrt your comments about random variable names, after taking a quick look at my implementation again, I don't think it applies to Capybara. I create a new "modal handler" instance every time the user tells us there is going to be an alert/prompt/confirm and then remove it from the queue when the status is checked so it's not really possible for the same status to be used multiple times. The issue with a page change is valid, but swapping to cookies could also have an issue if cookies are cleared during the page change (or the new url is a different sub/domain) so I think I'll stay with the small risk of a failure if a page change occurs, for now, and hope chrome/chromedriver fix the issue soon.

Collaborator

twalpole commented Jun 6, 2017

@gregsadetsky "Ugh", yeah. Wrt your comments about random variable names, after taking a quick look at my implementation again, I don't think it applies to Capybara. I create a new "modal handler" instance every time the user tells us there is going to be an alert/prompt/confirm and then remove it from the queue when the status is checked so it's not really possible for the same status to be used multiple times. The issue with a page change is valid, but swapping to cookies could also have an issue if cookies are cleared during the page change (or the new url is a different sub/domain) so I think I'll stay with the small risk of a failure if a page change occurs, for now, and hope chrome/chromedriver fix the issue soon.

@openscript

This comment has been minimized.

Show comment
Hide comment
@openscript

openscript Jun 8, 2017

Here is the new chromedriver 2.30. It doesn't have release notes yet.
https://chromedriver.storage.googleapis.com/index.html?path=2.30/

Here is the new chromedriver 2.30. It doesn't have release notes yet.
https://chromedriver.storage.googleapis.com/index.html?path=2.30/

@jeremy

This comment has been minimized.

Show comment
Hide comment
@jeremy

jeremy Jun 8, 2017

Note that window sizing and positioning do not work with headless as of chromedriver 2.30 + Chrome 59.

From this chromedriver issue:

As part of the work we're doing to make Headless Chrome work with ChromeDriver, we're replacing the ChromeDriver automation extension with DevTools commands to control the window size. This should make the extension unnecessary, so we won't have to worry about whitelists.

If you're doing something like:

driver.browser.manage.window.size = Selenium::WebDriver::Dimension.new(1400, 1400)

Then you'll get an error like:

Selenium::WebDriver::Error::UnknownError: unknown error: cannot get automation extension
from unknown error: page could not be found: chrome-extension://aapnijgdinlhnhlmodcfapnahmbfebeb/_generated_background_page.html
  (Session info: headless chrome=59.0.3071.86)
  (Driver info: chromedriver=2.30.477690 (c53f4ad87510ee97b5c3425a14c0e79780cdf262),platform=Mac OS X 10.13.0 x86_64)

Comment out the window size/position setting to work around it.

jeremy commented Jun 8, 2017

Note that window sizing and positioning do not work with headless as of chromedriver 2.30 + Chrome 59.

From this chromedriver issue:

As part of the work we're doing to make Headless Chrome work with ChromeDriver, we're replacing the ChromeDriver automation extension with DevTools commands to control the window size. This should make the extension unnecessary, so we won't have to worry about whitelists.

If you're doing something like:

driver.browser.manage.window.size = Selenium::WebDriver::Dimension.new(1400, 1400)

Then you'll get an error like:

Selenium::WebDriver::Error::UnknownError: unknown error: cannot get automation extension
from unknown error: page could not be found: chrome-extension://aapnijgdinlhnhlmodcfapnahmbfebeb/_generated_background_page.html
  (Session info: headless chrome=59.0.3071.86)
  (Driver info: chromedriver=2.30.477690 (c53f4ad87510ee97b5c3425a14c0e79780cdf262),platform=Mac OS X 10.13.0 x86_64)

Comment out the window size/position setting to work around it.

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jun 8, 2017

Collaborator

chromedriver 2.30 fixed the issues around window closing, but all content in extra windows opened is reported as not displayed by selenium, so multiple windows are still not really usable with headless.

Collaborator

twalpole commented Jun 8, 2017

chromedriver 2.30 fixed the issues around window closing, but all content in extra windows opened is reported as not displayed by selenium, so multiple windows are still not really usable with headless.

@nertzy

This comment has been minimized.

Show comment
Hide comment
@nertzy

nertzy Jun 12, 2017

chrome? && ((@processed_options[:desired_capabilities][:chrome_options] || {})['args'] || []).include?("headless")

This line makes a lot of assumptions about the hash structure of the Capabilities object.

I'm on a project where we have this driver defined:

Capybara.register_driver :chrome_headless do |app|
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOptions: {
      args: %w[ no-sandbox headless disable-gpu ]
    }
  )

  Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities)
end

And page.driver.headless_chrome? returns false because we have :chromeOptions instead of :chrome_options and we have :args instead of 'args'.

But Chrome does launch headlessly so it's clear that the browser launcher is being more lenient in its hash parsing.

nertzy commented Jun 12, 2017

chrome? && ((@processed_options[:desired_capabilities][:chrome_options] || {})['args'] || []).include?("headless")

This line makes a lot of assumptions about the hash structure of the Capabilities object.

I'm on a project where we have this driver defined:

Capybara.register_driver :chrome_headless do |app|
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOptions: {
      args: %w[ no-sandbox headless disable-gpu ]
    }
  )

  Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities)
end

And page.driver.headless_chrome? returns false because we have :chromeOptions instead of :chrome_options and we have :args instead of 'args'.

But Chrome does launch headlessly so it's clear that the browser launcher is being more lenient in its hash parsing.

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jun 12, 2017

Collaborator

@nertzy Yes it does, and if you'd like to propose a clean way of detecting it a PR would be appreciated. The fact that we even have to care whether it's headless or not is a hack at the moment, and hopefully modals and window interactions will actually be supported by Chrome in the near future, so we don't have to care.

Collaborator

twalpole commented Jun 12, 2017

@nertzy Yes it does, and if you'd like to propose a clean way of detecting it a PR would be appreciated. The fact that we even have to care whether it's headless or not is a hack at the moment, and hopefully modals and window interactions will actually be supported by Chrome in the near future, so we don't have to care.

@iggant

This comment has been minimized.

Show comment
Hide comment
@iggant

iggant Jun 16, 2017

  1. client authentication client addle to access dashboard with authentication
    Failure/Error: fill_in 'user[email]', with: client.user.email
    Selenium::WebDriver::Error::UnknownError:
    unknown error: an X display is required for keycode conversions, consider using Xvfb
    (Session info: headless chrome=59.0.3071.86)
    (Driver info: chromedriver=2.30.477691 (6ee44a7247c639c0703f291d320bdf05c1531b57),platform=Linux 4.9.24-coreos x86_64)
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/response.rb:69:in `assert_ok'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/response.rb:32:in `initialize'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/http/common.rb:83:in `new'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/http/common.rb:83:in `create_response'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/http/default.rb:107:in `request'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/http/common.rb:61:in `call'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/bridge.rb:170:in `execute'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/oss/bridge.rb:579:in `execute'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/oss/bridge.rb:372:in `send_keys_to_element'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/common/element.rb:156:in `send_keys'
     # /usr/local/bundle/gems/capybara-2.14.3/lib/capybara/selenium/node.rb:74:in `set'
     # /usr/local/bundle/gems/capybara-2.14.3/lib/capybara/node/element.rb:108:in `block in set'
     # /usr/local/bundle/gems/capybara-2.14.3/lib/capybara/node/base.rb:85:in `synchronize'
     # /usr/local/bundle/gems/capybara-2.14.3/lib/capybara/node/element.rb:106:in `set'
     # /usr/local/bundle/gems/capybara-2.14.3/lib/capybara/node/actions.rb:92:in `fill_in'
     # /usr/local/bundle/gems/capybara-2.14.3/lib/capybara/session.rb:784:in `block (2 levels) in <class:Session>'
     # /usr/local/bundle/gems/capybara-2.14.3/lib/capybara/dsl.rb:50:in `block (2 levels) in <module:DSL>'
     # ./spec/features/client_authentication_spec.rb:19:in `block (2 levels) in <top (required)>'

iggant commented Jun 16, 2017

  1. client authentication client addle to access dashboard with authentication
    Failure/Error: fill_in 'user[email]', with: client.user.email
    Selenium::WebDriver::Error::UnknownError:
    unknown error: an X display is required for keycode conversions, consider using Xvfb
    (Session info: headless chrome=59.0.3071.86)
    (Driver info: chromedriver=2.30.477691 (6ee44a7247c639c0703f291d320bdf05c1531b57),platform=Linux 4.9.24-coreos x86_64)
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/response.rb:69:in `assert_ok'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/response.rb:32:in `initialize'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/http/common.rb:83:in `new'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/http/common.rb:83:in `create_response'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/http/default.rb:107:in `request'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/http/common.rb:61:in `call'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/bridge.rb:170:in `execute'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/oss/bridge.rb:579:in `execute'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/remote/oss/bridge.rb:372:in `send_keys_to_element'
     # /usr/local/bundle/gems/selenium-webdriver-3.4.3/lib/selenium/webdriver/common/element.rb:156:in `send_keys'
     # /usr/local/bundle/gems/capybara-2.14.3/lib/capybara/selenium/node.rb:74:in `set'
     # /usr/local/bundle/gems/capybara-2.14.3/lib/capybara/node/element.rb:108:in `block in set'
     # /usr/local/bundle/gems/capybara-2.14.3/lib/capybara/node/base.rb:85:in `synchronize'
     # /usr/local/bundle/gems/capybara-2.14.3/lib/capybara/node/element.rb:106:in `set'
     # /usr/local/bundle/gems/capybara-2.14.3/lib/capybara/node/actions.rb:92:in `fill_in'
     # /usr/local/bundle/gems/capybara-2.14.3/lib/capybara/session.rb:784:in `block (2 levels) in <class:Session>'
     # /usr/local/bundle/gems/capybara-2.14.3/lib/capybara/dsl.rb:50:in `block (2 levels) in <module:DSL>'
     # ./spec/features/client_authentication_spec.rb:19:in `block (2 levels) in <top (required)>'
@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jun 16, 2017

Collaborator

@iggant That would be a Chrome issue, not a Capybara issue.

Collaborator

twalpole commented Jun 16, 2017

@iggant That would be a Chrome issue, not a Capybara issue.

@deivid-rodriguez

This comment has been minimized.

Show comment
Hide comment
@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jun 16, 2017

Collaborator

@deivid-rodriguez Exactly that one :)

Collaborator

twalpole commented Jun 16, 2017

@deivid-rodriguez Exactly that one :)

@frewsxcv

This comment has been minimized.

Show comment
Hide comment
@frewsxcv

frewsxcv Jun 27, 2017

This one, maybe: https://bugs.chromium.org/p/chromedriver/issues/detail?id=1772

Looks like this has been fixed and is just waiting for a new chromedriver release.

This one, maybe: https://bugs.chromium.org/p/chromedriver/issues/detail?id=1772

Looks like this has been fixed and is just waiting for a new chromedriver release.

@lucascaton

This comment has been minimized.

Show comment
Hide comment

lucascaton commented Jun 27, 2017

I'm able to run it and wrote a blog post about it:

How to run your feature specs using Capybara and Headless Chrome

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jun 27, 2017

Collaborator

@lucascaton You've fixed what? Without the next release of chromedriver (2.31) it's not possible to run without an X server installed on linux, anything to do with multiple windows or window resizing is still pretty broken until a future release of chrome and/or chromedriver, and we're still hacking around the lack of JS modal support.

Collaborator

twalpole commented Jun 27, 2017

@lucascaton You've fixed what? Without the next release of chromedriver (2.31) it's not possible to run without an X server installed on linux, anything to do with multiple windows or window resizing is still pretty broken until a future release of chrome and/or chromedriver, and we're still hacking around the lack of JS modal support.

@lucascaton

This comment has been minimized.

Show comment
Hide comment
@lucascaton

lucascaton Jun 27, 2017

@twalpole I've been using it with chromedriver 2.30 and works perfectly, even on Circle CI, running the same version 😄

@twalpole I've been using it with chromedriver 2.30 and works perfectly, even on Circle CI, running the same version 😄

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jun 27, 2017

Collaborator

@lucascaton Yes, because Circle CI installs an X server, your tests aren't resizing windows or opening multiple windows, and Capybara is hacking around the JS modals. So it's working perfectly for you because you're not using any of the currently broken parts. That's not fixing things, that's just avoiding the cracks :) Capybara has been running its own tests with headless chrome on travis for a few weeks now, and as long as we skip all the broken tests then it's perfect.

Collaborator

twalpole commented Jun 27, 2017

@lucascaton Yes, because Circle CI installs an X server, your tests aren't resizing windows or opening multiple windows, and Capybara is hacking around the JS modals. So it's working perfectly for you because you're not using any of the currently broken parts. That's not fixing things, that's just avoiding the cracks :) Capybara has been running its own tests with headless chrome on travis for a few weeks now, and as long as we skip all the broken tests then it's perfect.

@himankarbn

This comment has been minimized.

Show comment
Hide comment
@himankarbn

himankarbn Jun 29, 2017

We are using Chromedriver 2.30 and the only issue we are facing is the resizing. Since our test suite does lot of resizing ( desktop, mobile, tablet sizes ) in a single feature spec, we are currently blocked in using headless feature.
@jeremy @twalpole can you guys suggest how to use DevTools commands to control the window size during a test?

himankarbn commented Jun 29, 2017

We are using Chromedriver 2.30 and the only issue we are facing is the resizing. Since our test suite does lot of resizing ( desktop, mobile, tablet sizes ) in a single feature spec, we are currently blocked in using headless feature.
@jeremy @twalpole can you guys suggest how to use DevTools commands to control the window size during a test?

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jun 29, 2017

Collaborator

@himankarbn Since there is no connection to send random DevTools commands over I believe this isn't possible to do at the moment. Basically, it's a waiting game until chromedriver/chrome implement/fix support.

Collaborator

twalpole commented Jun 29, 2017

@himankarbn Since there is no connection to send random DevTools commands over I believe this isn't possible to do at the moment. Basically, it's a waiting game until chromedriver/chrome implement/fix support.

@egbert

This comment has been minimized.

Show comment
Hide comment
@egbert

egbert Jul 3, 2017

If you need to resize just once you can set a flag for the window size instead of resizing the window:

Capybara.register_driver :chrome_headless do |app|
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOptions: {
      args: %w[ no-sandbox headless disable-gpu window-size=1280,1024]
    }
  )

  Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities)
end

egbert commented Jul 3, 2017

If you need to resize just once you can set a flag for the window size instead of resizing the window:

Capybara.register_driver :chrome_headless do |app|
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOptions: {
      args: %w[ no-sandbox headless disable-gpu window-size=1280,1024]
    }
  )

  Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities)
end
@rilian

This comment has been minimized.

Show comment
Hide comment
@rilian

rilian Jul 4, 2017

we have sacrificed alerts functionality by disabling them with the following code, that is injected during tests:

window.alert = function() { return true; }
window.confirm = function() { return true; }

for everything else headless chrome works well.

rilian commented Jul 4, 2017

we have sacrificed alerts functionality by disabling them with the following code, that is injected during tests:

window.alert = function() { return true; }
window.confirm = function() { return true; }

for everything else headless chrome works well.

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jul 4, 2017

Collaborator

@rilian Alert functionality should be working with the latest Capybara and headless chrome - if it's not please let us know exactly what you're doing that doesn't work.

Collaborator

twalpole commented Jul 4, 2017

@rilian Alert functionality should be working with the latest Capybara and headless chrome - if it's not please let us know exactly what you're doing that doesn't work.

@himankarbn

This comment has been minimized.

Show comment
Hide comment
@himankarbn

himankarbn Jul 5, 2017

Thanks @egbert! We use shared examples and each of our feature spec executes on desktop, mobile, tablet etc views. The above solution on setting the window size is not much helpful for us.

himankarbn commented Jul 5, 2017

Thanks @egbert! We use shared examples and each of our feature spec executes on desktop, mobile, tablet etc views. The above solution on setting the window size is not much helpful for us.

@profsmallpine

This comment has been minimized.

Show comment
Hide comment
@profsmallpine

profsmallpine Jul 6, 2017

I tried moving from phantomjs to headless chrome today. There were a couple minor issues, but I am experiencing an issue where calling find('input#example').set('test') will sometimes work correctly. It also ends up setting the input as tes or te. Is anyone else experiencing this issue?

I tried moving from phantomjs to headless chrome today. There were a couple minor issues, but I am experiencing an issue where calling find('input#example').set('test') will sometimes work correctly. It also ends up setting the input as tes or te. Is anyone else experiencing this issue?

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jul 6, 2017

Collaborator

@profsmallpine That kind of behavior is usually caused by JS behavior initializing and taking the focus while the keystrokes are being sent, or JS attached to the specific input not handling the speed keystrokes are sent at. You would need to wait for whatever JS initialization is happening to complete before sending the text, or fix/improve the JS attached to the input

Collaborator

twalpole commented Jul 6, 2017

@profsmallpine That kind of behavior is usually caused by JS behavior initializing and taking the focus while the keystrokes are being sent, or JS attached to the specific input not handling the speed keystrokes are sent at. You would need to wait for whatever JS initialization is happening to complete before sending the text, or fix/improve the JS attached to the input

@profsmallpine

This comment has been minimized.

Show comment
Hide comment
@profsmallpine

profsmallpine Jul 6, 2017

@twalpole That makes sense, thanks for the feedback! I will add that after getting about 50% flaky tests, I have not seen any failed tests for this reason after updating capybara from 2.14.2 -> 2.14.4.

@twalpole That makes sense, thanks for the feedback! I will add that after getting about 50% flaky tests, I have not seen any failed tests for this reason after updating capybara from 2.14.2 -> 2.14.4.

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jul 6, 2017

Collaborator

@profsmallpine hmm -- nothing different between those 2 releases that should affect this, did you update anything else at the same time?

Collaborator

twalpole commented Jul 6, 2017

@profsmallpine hmm -- nothing different between those 2 releases that should affect this, did you update anything else at the same time?

@profsmallpine

This comment has been minimized.

Show comment
Hide comment
@profsmallpine

profsmallpine Jul 6, 2017

@twalpole The only change that I made was the capybara update in the commit where things seemed to get fixed, but it appears that I spoke too soon, still seeing the same flakiness, but only with chrome headless, phantomjs didn't experience this same issue.

@twalpole The only change that I made was the capybara update in the commit where things seemed to get fixed, but it appears that I spoke too soon, still seeing the same flakiness, but only with chrome headless, phantomjs didn't experience this same issue.

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jul 6, 2017

Collaborator

@profsmallpine The timing differences between phantomjs and chrome headless are going to be huge, so it's very possible that you have some JS behaviors attaching later under chrome and stealing focus. You can test that by just sleeping for a couple seconds before filling in the field in a test that is flaky. If that makes the flakiness stop then you'll need to figure out what visible change occurs on the page that you can check for before starting to fill it in, or fix the JS so it doesn't change the focus. Note, if that is the cause then it could/would affect a user that starts filling in the page immediately too, which would be a pretty bad UI.

Collaborator

twalpole commented Jul 6, 2017

@profsmallpine The timing differences between phantomjs and chrome headless are going to be huge, so it's very possible that you have some JS behaviors attaching later under chrome and stealing focus. You can test that by just sleeping for a couple seconds before filling in the field in a test that is flaky. If that makes the flakiness stop then you'll need to figure out what visible change occurs on the page that you can check for before starting to fill it in, or fix the JS so it doesn't change the focus. Note, if that is the cause then it could/would affect a user that starts filling in the page immediately too, which would be a pretty bad UI.

@h-parekh

This comment has been minimized.

Show comment
Hide comment
@h-parekh

h-parekh Jul 7, 2017

@profsmallpine I'm using a 'sleep injector' that injects sleep into some of the Capybara actions. This way I don't need to have sleep statements in the scenario.

h-parekh commented Jul 7, 2017

@profsmallpine I'm using a 'sleep injector' that injects sleep into some of the Capybara actions. This way I don't need to have sleep statements in the scenario.

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jul 7, 2017

Collaborator

@h-parekh Seleniums matchers and finders already have built-in waiting/retrying behavior so your overrides of wrap_matches?, has_selector?, and has_no_selector? are no different than just increasing the value of Capybara.default_max_wait_time or passing a large :wait option to the individual calls, so they're completely unneeded.

Your fill_in does make a change by waiting an extra 2 seconds after every fill_in but (if really needed) would be much better implemented as a module that gets prepended so you're not completely overwriting the existing method, something like (untested code but should be close)

module CapybaraSleepAdder
  def fill_in(*args)
     super.tap { sleep(2) }
  end
end
Capybara::Node::Actions.prepend(CapybaraSleepAdder)
Collaborator

twalpole commented Jul 7, 2017

@h-parekh Seleniums matchers and finders already have built-in waiting/retrying behavior so your overrides of wrap_matches?, has_selector?, and has_no_selector? are no different than just increasing the value of Capybara.default_max_wait_time or passing a large :wait option to the individual calls, so they're completely unneeded.

Your fill_in does make a change by waiting an extra 2 seconds after every fill_in but (if really needed) would be much better implemented as a module that gets prepended so you're not completely overwriting the existing method, something like (untested code but should be close)

module CapybaraSleepAdder
  def fill_in(*args)
     super.tap { sleep(2) }
  end
end
Capybara::Node::Actions.prepend(CapybaraSleepAdder)
@maschwenk

This comment has been minimized.

Show comment
Hide comment
@maschwenk

maschwenk Jul 26, 2017

Same issue with Chrome Head-more (?) Chrome Non-Headless (?)

maschwenk commented Jul 26, 2017

Same issue with Chrome Head-more (?) Chrome Non-Headless (?)

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jul 26, 2017

Collaborator

Ok -- sounds like a deficiency with either selenium or chromedriver, the webdriver spec only specifically mentions mouseover, and only in relation to option elements, so not sure whether they're supposed to be outputting a mouseenter (I would assume they should but the spec doesn't say) - You may be able to trigger the behavior through execute_script but since it happens with both Headless and Headed - it's not really this issue.

Collaborator

twalpole commented Jul 26, 2017

Ok -- sounds like a deficiency with either selenium or chromedriver, the webdriver spec only specifically mentions mouseover, and only in relation to option elements, so not sure whether they're supposed to be outputting a mouseenter (I would assume they should but the spec doesn't say) - You may be able to trigger the behavior through execute_script but since it happens with both Headless and Headed - it's not really this issue.

@fusionx1

This comment has been minimized.

Show comment
Hide comment
@fusionx1

fusionx1 Jul 27, 2017

Hi Guys I just would like to know to know if it's possible to use the chrome browser session while I'm running my headless chrome. I just wanna skip login process and rely on the browser session. Thanks in advance,

Hi Guys I just would like to know to know if it's possible to use the chrome browser session while I'm running my headless chrome. I just wanna skip login process and rely on the browser session. Thanks in advance,

@mooikos

This comment has been minimized.

Show comment
Hide comment
@mooikos

mooikos Jul 27, 2017

@twalpole
As an example this code can work on non-headless driver but not working on headless driver :

page.visit('https://www.google.com/recaptcha/api2/demo')
page.within_frame(page.find('#recaptcha-demo iframe')) do
  page.find('.recaptcha-checkbox-checkmark').click
end

I tried to find documentation regarding this output (that comes after successfully clicking on the non-headless version) :

exit
=> Obsolete #<Capybara::Node::Element>#<Capybara::Node::Element:0x3fd7b39b06c0>
(pry) output error: #<NoMethodError: undefined method `[]=' for nil:NilClass>

There is no mention regarding "Obsolete" :(

mooikos commented Jul 27, 2017

@twalpole
As an example this code can work on non-headless driver but not working on headless driver :

page.visit('https://www.google.com/recaptcha/api2/demo')
page.within_frame(page.find('#recaptcha-demo iframe')) do
  page.find('.recaptcha-checkbox-checkmark').click
end

I tried to find documentation regarding this output (that comes after successfully clicking on the non-headless version) :

exit
=> Obsolete #<Capybara::Node::Element>#<Capybara::Node::Element:0x3fd7b39b06c0>
(pry) output error: #<NoMethodError: undefined method `[]=' for nil:NilClass>

There is no mention regarding "Obsolete" :(

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jul 27, 2017

Collaborator

@fusionx1 Please don't hijaack this thread with howto questions. These issues are for bugs in Capybara and sometimes its related drivers. Howto questions should be asked on the mailing list, gitter, or stackoverflow

Collaborator

twalpole commented Jul 27, 2017

@fusionx1 Please don't hijaack this thread with howto questions. These issues are for bugs in Capybara and sometimes its related drivers. Howto questions should be asked on the mailing list, gitter, or stackoverflow

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jul 27, 2017

Collaborator

@Maxxillo "Obsolete #Capybara::Node::Element" is output when attempting to print the details of a node that is no longer accessible in the page/frame. It is not necessarily an error if you expected the element to disappear. For instance, if you are manually running page.find('.recaptcha-checkbox-checkmark').click, click returns the '.recaptcha-checkbox-checkmark' element. If the click actually removes the element from the page then the returned element would be obsolete. In a running program that wouldn't matter, but when running in pry/irb it attempts to print the returned element, which results in "Obsolete #Capybara::Node::Element" because the element is gone.

This question is pretty off-topic for this thread, so if you think you have found an actual issue please create a new one, if you just have more questions about how things work please ask on the mailing list, gitter, or stackoverflow and post enough info for people to be able to attempt to replicate your problem/question.

Collaborator

twalpole commented Jul 27, 2017

@Maxxillo "Obsolete #Capybara::Node::Element" is output when attempting to print the details of a node that is no longer accessible in the page/frame. It is not necessarily an error if you expected the element to disappear. For instance, if you are manually running page.find('.recaptcha-checkbox-checkmark').click, click returns the '.recaptcha-checkbox-checkmark' element. If the click actually removes the element from the page then the returned element would be obsolete. In a running program that wouldn't matter, but when running in pry/irb it attempts to print the returned element, which results in "Obsolete #Capybara::Node::Element" because the element is gone.

This question is pretty off-topic for this thread, so if you think you have found an actual issue please create a new one, if you just have more questions about how things work please ask on the mailing list, gitter, or stackoverflow and post enough info for people to be able to attempt to replicate your problem/question.

@teamcapybara teamcapybara deleted a comment from mooikos Jul 27, 2017

@maschwenk

This comment has been minimized.

Show comment
Hide comment
@maschwenk

maschwenk Jul 31, 2017

@twalpole I can confirm that changing the event from onMouseEnter to onMouseOver, it works. Do you think it makes sense to raise that issue anywhere, if so, where?

@twalpole I can confirm that changing the event from onMouseEnter to onMouseOver, it works. Do you think it makes sense to raise that issue anywhere, if so, where?

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Jul 31, 2017

Collaborator

@maschwenk Sure - if it works with gackodriver then it should definitely be reported to chromedriver. If it doesn’t work with geckodriver either then maybe selenium and chromedriver

Collaborator

twalpole commented Jul 31, 2017

@maschwenk Sure - if it works with gackodriver then it should definitely be reported to chromedriver. If it doesn’t work with geckodriver either then maybe selenium and chromedriver

@maschwenk

This comment has been minimized.

Show comment
Hide comment
@maschwenk

maschwenk Aug 1, 2017

@twalpole works in geckodriver, will report to chromedriver

@twalpole works in geckodriver, will report to chromedriver

@bbuchalter

This comment has been minimized.

Show comment
Hide comment
@bbuchalter

bbuchalter Aug 14, 2017

@rilian Alert functionality should be working with the latest Capybara and headless chrome - if it's not please let us know exactly what you're doing that doesn't work.

accept_alert works as expected in Chrome headed, but Capybara::ModalNotFound is raised in headless. Versions:

capybara 2.15.1
Google Chrome 59.0.3071.115
ChromeDriver 2.31.488763 (092de99f48a300323ecf8c2a4e2e7cab51de5ba8)

Will try upgrading to Chrome 60...

@rilian Alert functionality should be working with the latest Capybara and headless chrome - if it's not please let us know exactly what you're doing that doesn't work.

accept_alert works as expected in Chrome headed, but Capybara::ModalNotFound is raised in headless. Versions:

capybara 2.15.1
Google Chrome 59.0.3071.115
ChromeDriver 2.31.488763 (092de99f48a300323ecf8c2a4e2e7cab51de5ba8)

Will try upgrading to Chrome 60...

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Aug 14, 2017

Collaborator

@bbuchalter What version of seleniuv-webdriver are you using (make sure a recent one) and what are you specifying in your register driver block? Also show the code you're using with accept_alert - you have to be passing the block that triggers the system modal.

Collaborator

twalpole commented Aug 14, 2017

@bbuchalter What version of seleniuv-webdriver are you using (make sure a recent one) and what are you specifying in your register driver block? Also show the code you're using with accept_alert - you have to be passing the block that triggers the system modal.

@bbuchalter

This comment has been minimized.

Show comment
Hide comment
@bbuchalter

bbuchalter Aug 14, 2017

@twalpole

What version of seleniuv-webdriver are you using (make sure a recent one)

selenium-webdriver (3.4.4)

and what are you specifying in your register driver block?

chrome_options = [
  "window-size=#{REQUEST_SPEC_BROWSER_WIDTH},#{REQUEST_SPEC_BROWSER_HEIGHT}"
]
if ENV['HEADLESS']
  chrome_options += [
    "headless",
    "disable-gpu",
  ]
end
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
  chromeOptions: { args: chrome_options }
)
Capybara.register_driver :chrome do |app|
  Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    desired_capabilities: capabilities
  )
end
Capybara.javascript_driver = :chrome

Will update selenium-webdriver and try again...

bbuchalter commented Aug 14, 2017

@twalpole

What version of seleniuv-webdriver are you using (make sure a recent one)

selenium-webdriver (3.4.4)

and what are you specifying in your register driver block?

chrome_options = [
  "window-size=#{REQUEST_SPEC_BROWSER_WIDTH},#{REQUEST_SPEC_BROWSER_HEIGHT}"
]
if ENV['HEADLESS']
  chrome_options += [
    "headless",
    "disable-gpu",
  ]
end
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
  chromeOptions: { args: chrome_options }
)
Capybara.register_driver :chrome do |app|
  Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    desired_capabilities: capabilities
  )
end
Capybara.javascript_driver = :chrome

Will update selenium-webdriver and try again...

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Aug 14, 2017

Collaborator

@bbuchalter and the code that calls accept_alert ?

Collaborator

twalpole commented Aug 14, 2017

@bbuchalter and the code that calls accept_alert ?

@bbuchalter

This comment has been minimized.

Show comment
Hide comment
@bbuchalter

bbuchalter Aug 14, 2017

OK, after upgrading all the things (versions below), I now get failures for both headed and headless versions, but different errors.

Headed Chrome alert error


          Selenium::WebDriver::Error::UnhandledAlertError:
            unexpected alert open: {Alert text : Are you sure?}
              (Session info: chrome=60.0.3112.101)
              (Driver info: chromedriver=2.31.488774 (7e15618d1bf16df8bf0ecf2914ed1964a387ba0b),platform=Mac OS X 10.12.6 x86_64)

Headless Chrome alert error

     Failure/Error: accept_alert

     LocalJumpError:
       no block given (yield)

I know the docs for accept_alert say it accepts a block, but click_on "OK" just results in Capybara::ElementNotFound: Unable to find visible link or button "OK", which makes sense since this is a system dialog, not an element.

Versions

ruby 2.2.7p470 (2017-03-28 revision 58194) [x86_64-linux]
node: v8.1.2
yarn: 0.24.6
Google Chrome 60.0.3112.101 
ChromeDriver 2.31.488763 (092de99f48a300323ecf8c2a4e2e7cab51de5ba8)
selenium-webdriver (3.5.0)
capybara (2.15.1)

OK, after upgrading all the things (versions below), I now get failures for both headed and headless versions, but different errors.

Headed Chrome alert error


          Selenium::WebDriver::Error::UnhandledAlertError:
            unexpected alert open: {Alert text : Are you sure?}
              (Session info: chrome=60.0.3112.101)
              (Driver info: chromedriver=2.31.488774 (7e15618d1bf16df8bf0ecf2914ed1964a387ba0b),platform=Mac OS X 10.12.6 x86_64)

Headless Chrome alert error

     Failure/Error: accept_alert

     LocalJumpError:
       no block given (yield)

I know the docs for accept_alert say it accepts a block, but click_on "OK" just results in Capybara::ElementNotFound: Unable to find visible link or button "OK", which makes sense since this is a system dialog, not an element.

Versions

ruby 2.2.7p470 (2017-03-28 revision 58194) [x86_64-linux]
node: v8.1.2
yarn: 0.24.6
Google Chrome 60.0.3112.101 
ChromeDriver 2.31.488763 (092de99f48a300323ecf8c2a4e2e7cab51de5ba8)
selenium-webdriver (3.5.0)
capybara (2.15.1)
@bbuchalter

This comment has been minimized.

Show comment
Hide comment
@bbuchalter

bbuchalter Aug 14, 2017

:facepalm:

I failed to understand the way the block is supposed to work:

accept_alert do
  find(".delete").click # thing that triggers alert
end

My apologies. Things working as expected now.

:facepalm:

I failed to understand the way the block is supposed to work:

accept_alert do
  find(".delete").click # thing that triggers alert
end

My apologies. Things working as expected now.

@NoHesHere

This comment has been minimized.

Show comment
Hide comment
@NoHesHere

NoHesHere Aug 23, 2017

So I am having another, yet similar issue. For me, in headless mode, it appears that js alerts are not even being rendered. If I run the code:

accept_confirm do
  element.click()
end

In headed chrome, it passes, because the modal is rendered. In headless, it fails with Capybara::ModalNotFound:, and if I run it in headless without any code to accept the alert, it fails waiting for the next element.

Has anyone else had the same problem, or have any ideas?

Version Info:

capybara: 2.15.1
selenium-webdriver: 3.5.1
ChromeDriver: 2.31

So I am having another, yet similar issue. For me, in headless mode, it appears that js alerts are not even being rendered. If I run the code:

accept_confirm do
  element.click()
end

In headed chrome, it passes, because the modal is rendered. In headless, it fails with Capybara::ModalNotFound:, and if I run it in headless without any code to accept the alert, it fails waiting for the next element.

Has anyone else had the same problem, or have any ideas?

Version Info:

capybara: 2.15.1
selenium-webdriver: 3.5.1
ChromeDriver: 2.31
@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Aug 23, 2017

Collaborator

@NoHesHere Chrome in headless mode doesn't support system modals, so Capybara has to patch in some code to handle them. Unfortunately there is no nice way to detect that Chrome is in fact running in headless mode through selenium so we have to inspect the driver config to determine when we need to patch window.alert/confirm/prompt. The downside to this is there are many ways to configure selenium so it runs chrome headless, if you're specifying it in a way we don't detect then the patching doesn't occur. Look at https://github.com/teamcapybara/capybara/blob/master/lib/capybara/selenium/driver.rb#L322 and see whether the way you're configuring selenium would match that.

Collaborator

twalpole commented Aug 23, 2017

@NoHesHere Chrome in headless mode doesn't support system modals, so Capybara has to patch in some code to handle them. Unfortunately there is no nice way to detect that Chrome is in fact running in headless mode through selenium so we have to inspect the driver config to determine when we need to patch window.alert/confirm/prompt. The downside to this is there are many ways to configure selenium so it runs chrome headless, if you're specifying it in a way we don't detect then the patching doesn't occur. Look at https://github.com/teamcapybara/capybara/blob/master/lib/capybara/selenium/driver.rb#L322 and see whether the way you're configuring selenium would match that.

@NoHesHere

This comment has been minimized.

Show comment
Hide comment
@NoHesHere

NoHesHere Aug 23, 2017

@twalpole You are correct, we were not tripping the conditional. For anyone else with the same issue, we had defined our chromeOptions like this:

"chromeOptions" => { 'args' => %w{headless disable-popup-blocking no-sandbox disable-gpu window-size=1400,900} }

Changing it to:

chromeOptions: { 'args' => %w{headless disable-popup-blocking no-sandbox disable-gpu window-size=1400,900} }

fixed the issue for us.

@twalpole You are correct, we were not tripping the conditional. For anyone else with the same issue, we had defined our chromeOptions like this:

"chromeOptions" => { 'args' => %w{headless disable-popup-blocking no-sandbox disable-gpu window-size=1400,900} }

Changing it to:

chromeOptions: { 'args' => %w{headless disable-popup-blocking no-sandbox disable-gpu window-size=1400,900} }

fixed the issue for us.

@betorina

This comment has been minimized.

Show comment
Hide comment
@betorina

betorina Sep 9, 2017

Found out that rails 5.1 can use headless chrome with a one liner:
Rails System Testing

require "test_helper"

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  driven_by :selenium, using: :chrome, screen_size: [1400, 900], options: { args: %w[headless disable-gpu] }
end

Gives only a 'small' deprecation warning ('args' vs 'add_argument').

betorina commented Sep 9, 2017

Found out that rails 5.1 can use headless chrome with a one liner:
Rails System Testing

require "test_helper"

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  driven_by :selenium, using: :chrome, screen_size: [1400, 900], options: { args: %w[headless disable-gpu] }
end

Gives only a 'small' deprecation warning ('args' vs 'add_argument').

@rachel-carvalho

This comment has been minimized.

Show comment
Hide comment
@rachel-carvalho

rachel-carvalho Sep 12, 2017

I still get the error Unable to find modal dialog (Capybara::ModalNotFound) when I try to accept_alert.

Version info:

capybara: 2.15.1
selenium-webdriver: 3.5.2
ChromeDriver: 2.32

rachel-carvalho commented Sep 12, 2017

I still get the error Unable to find modal dialog (Capybara::ModalNotFound) when I try to accept_alert.

Version info:

capybara: 2.15.1
selenium-webdriver: 3.5.2
ChromeDriver: 2.32
@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Sep 12, 2017

Collaborator

@rachel-carvalho Then you’re either using it incorrectly or you’re running into the same issue @NoHesHere had a couple of posts up

Collaborator

twalpole commented Sep 12, 2017

@rachel-carvalho Then you’re either using it incorrectly or you’re running into the same issue @NoHesHere had a couple of posts up

@twalpole twalpole closed this Sep 14, 2017

@Petercopter

This comment has been minimized.

Show comment
Hide comment
@Petercopter

Petercopter Sep 26, 2017

@rachel-carvalho @NoHesHere
I have the same problem, can't auto-accept alerts in headless mode. It works in 'headful' mode, but when you switch to headless, it no longer works.

This works:

Capybara.default_driver = :selenium_chrome

This doesn't

Capybara.default_driver = :selenium_chrome_headless

@rachel-carvalho @NoHesHere
I have the same problem, can't auto-accept alerts in headless mode. It works in 'headful' mode, but when you switch to headless, it no longer works.

This works:

Capybara.default_driver = :selenium_chrome

This doesn't

Capybara.default_driver = :selenium_chrome_headless
@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Sep 26, 2017

Collaborator

@Petercopter auto-accepting alerts shouldn't work -- the fact that is does in some drivers/setups is technically a bug - you should be specifying to accept or dismiss system modals. Assuming by "auto-accept" that you mean without using code like

accept_alert do
  click_button "button that opens alert"
end

If that's not what you mean then please provide an example of the code that is failing for you and the exact error message returned.

Collaborator

twalpole commented Sep 26, 2017

@Petercopter auto-accepting alerts shouldn't work -- the fact that is does in some drivers/setups is technically a bug - you should be specifying to accept or dismiss system modals. Assuming by "auto-accept" that you mean without using code like

accept_alert do
  click_button "button that opens alert"
end

If that's not what you mean then please provide an example of the code that is failing for you and the exact error message returned.

@Petercopter

This comment has been minimized.

Show comment
Hide comment
@Petercopter

Petercopter Sep 26, 2017

@twapole sorry for the confusion. I meant using the workaround code to auto accept the confirmations in the meantime, while we wait for chrome to work with the dialogs. I'm busy converting from poltergeist to headless chrome, I was just trying to work past the alert problem for now.

Nothing to see here, carry on! 😀

@twapole sorry for the confusion. I meant using the workaround code to auto accept the confirmations in the meantime, while we wait for chrome to work with the dialogs. I'm busy converting from poltergeist to headless chrome, I was just trying to work past the alert problem for now.

Nothing to see here, carry on! 😀

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Sep 26, 2017

Collaborator

@Petercopter - using the default :selenium_chrome_headless it should work correctly with code like

accept_alert do
  click_button "button that opens alert"
end

is that working for you? If not, please post your code so I can try and figure out why - we don't like having things not work when using the Capybara provided defaults :). If you've modified the :selenium_chrome_headless registration then it's possible Capybara isn't detecting that it's headless (due to the specific way you have specified headless) and isn't patching the JS alert/confirm/prompt methods as needed.

Collaborator

twalpole commented Sep 26, 2017

@Petercopter - using the default :selenium_chrome_headless it should work correctly with code like

accept_alert do
  click_button "button that opens alert"
end

is that working for you? If not, please post your code so I can try and figure out why - we don't like having things not work when using the Capybara provided defaults :). If you've modified the :selenium_chrome_headless registration then it's possible Capybara isn't detecting that it's headless (due to the specific way you have specified headless) and isn't patching the JS alert/confirm/prompt methods as needed.

@Petercopter

This comment has been minimized.

Show comment
Hide comment
@Petercopter

Petercopter Sep 27, 2017

@twalpole Alright, I feel ridiculous. It turns out that we were not using the Capybara accept_alert, instead we were using the driver's version, page.accept_confirm.

I've changed to using accept_alert in our test suite, and now I am onto the next adventure. Thank you so much for poking at the issue! 🌮 🍺

@twalpole Alright, I feel ridiculous. It turns out that we were not using the Capybara accept_alert, instead we were using the driver's version, page.accept_confirm.

I've changed to using accept_alert in our test suite, and now I am onto the next adventure. Thank you so much for poking at the issue! 🌮 🍺

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Sep 27, 2017

Collaborator

@Petercopter No problem, glad it's working (just to note - if it is actually a confirm modal as opposed to an alert you should use Capybaras accept_confirm instead of accept_alert - There's really no difference when using Selenium but could be in other drivers)

Collaborator

twalpole commented Sep 27, 2017

@Petercopter No problem, glad it's working (just to note - if it is actually a confirm modal as opposed to an alert you should use Capybaras accept_confirm instead of accept_alert - There's really no difference when using Selenium but could be in other drivers)

@rachel-carvalho

This comment has been minimized.

Show comment
Hide comment
@rachel-carvalho

rachel-carvalho Sep 29, 2017

I figured what the problem was, thanks @Petercopter! My tests were like so:

click button 'Will confirm'
accept_alert

And that was working with :selenium_chrome and firefox before that. It seems that using accept_alert or accept_confirm doesn't make much of a difference, but I changed it to accept_confirm anyway because it's the right type of dialog.

But obviously my problem was that the action that was causing the confirm to appear happened before accepting, but not within a block. Anyway, now it's all working 🎉

I figured what the problem was, thanks @Petercopter! My tests were like so:

click button 'Will confirm'
accept_alert

And that was working with :selenium_chrome and firefox before that. It seems that using accept_alert or accept_confirm doesn't make much of a difference, but I changed it to accept_confirm anyway because it's the right type of dialog.

But obviously my problem was that the action that was causing the confirm to appear happened before accepting, but not within a block. Anyway, now it's all working 🎉

@jdelStrother

This comment has been minimized.

Show comment
Hide comment
@jdelStrother

jdelStrother Sep 30, 2017

Contributor
Contributor

jdelStrother commented Sep 30, 2017

@twalpole

This comment has been minimized.

Show comment
Hide comment
@twalpole

twalpole Sep 30, 2017

Collaborator

@jdelStrother It's already in master - ec4d32f - it has been a while since a release so I'll see if I can get to one this weekend, just need to decide if it can be 2.15.2 or needs to be 2.16

Collaborator

twalpole commented Sep 30, 2017

@jdelStrother It's already in master - ec4d32f - it has been a while since a release so I'll see if I can get to one this weekend, just need to decide if it can be 2.15.2 or needs to be 2.16

@RKushnir

This comment has been minimized.

Show comment
Hide comment
@RKushnir

RKushnir Dec 21, 2017

@maschwenk Have you managed to figure out why hover wasn't working? Seems like the question got lost in this thread. For me it's working in regular chrome, but not in headless.

@maschwenk Have you managed to figure out why hover wasn't working? Seems like the question got lost in this thread. For me it's working in regular chrome, but not in headless.

@RKushnir

This comment has been minimized.

Show comment
Hide comment
@RKushnir

RKushnir Dec 21, 2017

I figured you need to click anything on the page before hovering. Maybe, otherwise the window is not active.

I figured you need to click anything on the page before hovering. Maybe, otherwise the window is not active.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment