Skip to content
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

[3.7.0] Doesn't work with chromium on Linux #38

Closed
boris-petrov opened this issue Mar 21, 2019 · 28 comments
Closed

[3.7.0] Doesn't work with chromium on Linux #38

boris-petrov opened this issue Mar 21, 2019 · 28 comments
Assignees

Comments

@boris-petrov
Copy link

I guess the issue is here. This checks for google-chrome while I, for example, use chromium. The code should be made to handle that scenario.

Errno::ENOENT:
  No such file or directory - google-chrome
# ./features/build/tmp/jrubyExec/gems/webdrivers-3.7.0/lib/webdrivers/chromedriver.rb:82:in `chrome_on_linux'
# ./features/build/tmp/jrubyExec/gems/webdrivers-3.7.0/lib/webdrivers/chromedriver.rb:64:in `chrome_version'
# ./features/build/tmp/jrubyExec/gems/webdrivers-3.7.0/lib/webdrivers/chromedriver.rb:55:in `release_version'
# ./features/build/tmp/jrubyExec/gems/webdrivers-3.7.0/lib/webdrivers/chromedriver.rb:19:in `latest_version'
# ./features/build/tmp/jrubyExec/gems/webdrivers-3.7.0/lib/webdrivers/common.rb:37:in `desired_version'
# ./features/build/tmp/jrubyExec/gems/webdrivers-3.7.0/lib/webdrivers/common.rb:16:in `update'
# ./features/build/tmp/jrubyExec/gems/webdrivers-3.7.0/lib/webdrivers/selenium.rb:7:in `driver_path'
# ./features/build/tmp/jrubyExec/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/chrome/driver.rb:39:in `initialize'
# ./features/build/tmp/jrubyExec/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/driver.rb:44:in `for'
# ./features/build/tmp/jrubyExec/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver.rb:86:in `for'
# ./features/build/tmp/jrubyExec/gems/capybara-3.15.0/lib/capybara/selenium/driver.rb:32:in `browser'
# ./features/build/tmp/jrubyExec/gems/capybara-3.15.0/lib/capybara/selenium/driver.rb:139:in `current_window_handle'
# ./features/build/tmp/jrubyExec/gems/capybara-3.15.0/lib/capybara/session.rb:438:in `current_window'
# ./features/spec_helper.rb:89:in `block in <main>'
@kapoorlakshya
Copy link
Collaborator

kapoorlakshya commented Mar 21, 2019

Hi @boris-petrov, thanks for reporting this. I'll try to add support for chromium as soon as I can. Hopefully this weekend.

@kapoorlakshya
Copy link
Collaborator

I'll need to discuss this with @titusfortner before implementing it, but I think a flag like this would fit your use case:

Webdrivers::Chromedriver.use_chromium = true

The other option is to check for what is installed and use it to retrieve the version. However, that won't work well if you have both google-chrome and chromium-browser installed because whatever is checked for first will always be used.

@boris-petrov
Copy link
Author

Well, the best user-experience would be to check for google-chrome and chromium (note there is no -browser on the executable name) and if there is only one of them, use it. If they are both there (very rarely probably), only then use some configuration option which could be Webdrivers::Chromedriver.chrome_executable = 'chromium' or something.

@titusfortner
Copy link
Owner

Ah, I knew I overlooked something. We should be pulling from Chrome.path https://github.com/SeleniumHQ/selenium/blob/master/rb/lib/selenium/webdriver/chrome.rb

Users can have multiple installations of chrome, and that's the best place to specify.

We should also probably be using the same code as selenium for locating the default path rather than specifying it.

@kapoorlakshya
Copy link
Collaborator

@boris-petrov Which distro and version of Chromium are you using? I checked on CentOS 7.6 and Ubuntu 14.04, and the installed executable is named chromium-browser for me. Just curious what's causing the difference here.

@titusfortner That makes sense. So if I understand correctly, this would be the ideal approach then:

  1. Check Selenium::WebDriver::Chrome.path. Use if path is not nil.
  2. If it is nil, check for Google Chrome.
  3. If Google Chrome is not installed, check for Chromium.
  4. Error -> Google Chrome or Chromium not found.

I am okay with skipping check 3 and including a note in the README for Chromium users.

@boris-petrov
Copy link
Author

@kapoorlakshya - Arch Linux, latest Chromium - 73.0.3683.86. The executable is /usr/bin/chromium.

@kapoorlakshya
Copy link
Collaborator

@boris-petrov Thanks! I'm glad it won't be a problem as Titus's recommendation will allow us to work around this difference :)

@kapoorlakshya
Copy link
Collaborator

Released v3.7.1. Please let me know if you run into any other issues.

@boris-petrov
Copy link
Author

@kapoorlakshya - well, 3.7.1 still doesn't work for me. :) Selenium.WebDriver::Chrome.path is nil in my case and the fallback for google-chrome obviously doesn't work. Is Selenium.WebDriver::Chrome.path supposed to be set automatically or is it something that I should set?

@kapoorlakshya
Copy link
Collaborator

kapoorlakshya commented Mar 27, 2019

@boris-petrov You should set Selenium.WebDriver::Chrome.path = '/usr/bin/chromium' in your case. This will always override the default Google Chrome path.

EDIT: Wrap path in single quotes.

@boris-petrov
Copy link
Author

@kapoorlakshya - I see, but why does Capybara/Selenium work even without this? How does it find the correct Chrome to use and why can't webdrivers do the same?

@kapoorlakshya
Copy link
Collaborator

@boris-petrov From what I know, this is where Selenium looks for the Chrome binary:

  1. OS specific default install locations as mentioned here.
  2. Selenium.WebDriver::Chrome.path for non-standard locations.
  3. Selenium::WebDriver::Chrome::Options.binary also for non-standard locations as mentioned here.

webdrivers offers options 1 and 2. I'm not sure if Capybara has their own implementation or if they rely on Selenium to figure it out. You could ask @twalpole.

P.S. If you're curious how Chrome itself does it, you can read through the code here.

@boris-petrov
Copy link
Author

@kapoorlakshya Thanks for the answer. I will use Selenium.WebDriver::Chrome.path, that's fine, I'm just wondering how Capybara with Selenium finds my Chromium without this option. Obviously there is some other mechanism somewhere. Anyway, thanks!

@twalpole
Copy link
Collaborator

twalpole commented Mar 27, 2019

Capybara doesn't do any location of the executable - that is all done by selenium unless you've overridden it in your capybara driver registration.

@boris-petrov
Copy link
Author

@kapoorlakshya, @twalpole - the funny thing is that we have nothing in our configuration and our setup works fine on my machine (Arch Linux, chromium binary) and on our CI (Ubuntu, chromium-browser binary). This is with webdrivers 3.6.0. 3.7.0+ doesn't work by default, I have to configure it specifically for each machine (which is mildly annoying). My guess would be, given that Capybara doesn't do anything special, that chromedriver knows how to find the correct browser. So my idea was that webdrivers could delegate to it the job, or if there is no command-line/API for that, copy-paste the logic? As otherwise many people like me will have to provide options in their own code for specifying the executable on different platforms...

@titusfortner
Copy link
Owner

I think Issue #45 is what we probably need to implement for it to do what you want.

@RyanTG
Copy link

RyanTG commented Apr 8, 2019

Could anyone hold my hand and tell me where exactly Selenium.WebDriver::Chrome.path = /usr/bin/chromium should be added? I keep getting syntax errors - this isn't my bread and butter. (we're currently using chromedriver-helper still, but I wanted to see if switching to webdrivers will magically fix a capybara/headless issue I'm experiencing on my linux box).

https://github.com/RyanTG/pbm/blob/master/spec/spec_helper.rb

and when using webdrivers, should I remove require 'selenium/webdriver' from spec_helper?

@kapoorlakshya
Copy link
Collaborator

kapoorlakshya commented Apr 8, 2019

@RyanTG Please share the exact error.

Selenium::WebDriver::Chrome.path = /usr/bin/chromium should be set before you initialize the browser. And you do not need to require selenium-webdriver in your project. Requiring this gem already does it for you.

Please note that it's selenium-webdriver with a hyphen and not selenium/webdriver.

@boris-petrov
Copy link
Author

@RyanTG - it should be Selenium::WebDriver::Chrome.path, not Selenium.WebDriver::Chrome.path. That's the syntax error you're getting.

@kapoorlakshya
Copy link
Collaborator

@boris-petrov Good catch!

@RyanTG
Copy link

RyanTG commented Apr 8, 2019

Thanks!

The error is

An error occurred while loading ./spec/controllers/application_controller_spec.rb.
Failure/Error: require 'spec_helper'

SyntaxError:
  /home/rgratzer/Documents/pinball/pbm/spec/spec_helper.rb:32: unknown regexp option - b
# ./spec/controllers/application_controller_spec.rb:1:in `require'
# ./spec/controllers/application_controller_spec.rb:1:in `<top (required)>'

Line 32 is where the I'm trying to set the path. I've tried putting it in lots of places in spec_helper.

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'factory_bot_rails'
require 'rspec/rails'
require 'capybara/rspec'
require 'simplecov'
require 'coveralls'
require 'rack_session_access/capybara'
require 'rspec/retry'
require 'webdrivers'
# require 'selenium/webdriver'

include Sprockets::Rails::Helper

SimpleCov.start
Coveralls.wear!

# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

RSpec.configure do |config|
  config.verbose_retry = true
  config.display_try_failure_messages = true

  config.around :each, :js do |ex|
    ex.run_with_retry retry: 3
  end

   Selenium::WebDriver::Chrome.path = /usr/bin/chromium      

  Capybara.register_driver :chrome do |app|
    Capybara::Selenium::Driver.new(app, browser: :chrome)
  end

  Capybara.register_driver :headless_chrome do |app|
    capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
      chromeOptions: { args: %w[headless disable-gpu window-size=2000,1000] }
    )

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

  Capybara.javascript_driver = :selenium_chrome_headless
...

@kapoorlakshya
Copy link
Collaborator

/usr/bin/chromium should be wrapped in single quotes, like this:

Selenium::WebDriver::Chrome.path = '/usr/bin/chromium'

@RyanTG
Copy link

RyanTG commented Apr 8, 2019

Oh jeez. I really should have been pasting from the readme, and not #38 (comment)

Works now - thanks for your help! And this confirmed that the tests that are failing on headless in linux, but not chrome in linux and not headless or chrome on mac are still failing even after switching to webdrivers (which was a long shot, but I'm grasping at straws here).

@kapoorlakshya
Copy link
Collaborator

Oops... updated my comment. Good luck with your test!

@twalpole
Copy link
Collaborator

twalpole commented Apr 9, 2019

@RyanTG It was unlikely switching from chromedriver-helper to webdrivers would fix any issue -- it all ends up running the same things. For issues with headless in linux have you tried adding the --disable-dev-shm-usage flag to Chrome?

@RyanTG
Copy link

RyanTG commented Apr 9, 2019

I hadn't. But I tried it just now, and it didn't improve my situation. Thanks for that tip, though.

My test involves clicking a button that expands a div to load a select. Then choosing an item from the select. With save_and_open_page it appears that some of the js isn't present, and thus the select isn't loading. Increasing sleep didn't fix it. I struggle to troubleshoot this, because I'm not sure which things could be contributing (postgresql, ruby, chromium, etc). Like, could downgrading chromium help?

@twalpole
Copy link
Collaborator

twalpole commented Apr 9, 2019

@RyanTG It's highly unlikely to have anything to do with Postgresql or ruby itself. Assuming you're running current versions of chromium It's going to be something to do with a setting for the browser - for instance you're only setting a window size in headless mode -- try setting headless and headful to the same window size and see if the problem goes away/exists on both, or why are you disabling the GPU (that's only needed on windows). Also use save_and_open_screenshot to see what's actually being rendered. Anyway this is getting off-topic for the webdrivers gem - if you can provide access to a simple example that shows the issue file an issue over on the Capybara project and I'll take a look.

@titusfortner
Copy link
Owner

Another option if you're on Linux is to use the headless gem instead of the browser's headless mode

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

No branches or pull requests

5 participants