Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

run selenium with chrome driver on heroku: `cannot find Chrome binary`

I'm a noob as it comes to linux setup (and heroku), so apologies if this question is basic.

I want to run selenium webkit (in ruby) on Heroku. I face a difficulty that my script cannot find Chrome binary file.

I actually got chrome to work by itself:

~ $ chromedriver
Starting ChromeDriver 2.22.397932 (282ed7cf89cf0053b6542e0d0f039d4123bbb6ad) on port 9515
Only local connections are allowed.

chromedriver being a file that I copied from /app/vendor/bundle/bin/chromedriver, just to make it easier for now. chromedriver file there exists because I installed chromedriver-helper gem. The gem was supposed to make the binary file available for ruby processes but didn't.

I've also tried setting path explicitly, e.g. Selenium::WebDriver::Chrome.driver_path = 'chromedriver' in my ruby code, with the aforementioned file located in the root category.

It all works perfectly locally (with or without the driver_path)

What can be the cause? I've read this SO thread from years ago, but it seems outdated to me. Any ideas would be greatly appreciated!

error trace:

~ $ ruby bin/run.rb
/app/vendor/bundle/ruby/2.2.0/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/response.rb:70:in `assert_ok': unknown error: cannot find Chrome binary (Selenium::WebDriver::Error::UnknownError)
  (Driver info: chromedriver=2.22.397932 (282ed7cf89cf0053b6542e0d0f039d4123bbb6ad),platform=Linux 3.13.0-91-generic x86_64)
    from /app/vendor/bundle/ruby/2.2.0/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/response.rb:34:in `initialize'
    from /app/vendor/bundle/ruby/2.2.0/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/http/common.rb:78:in `new'
    from /app/vendor/bundle/ruby/2.2.0/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/http/common.rb:78:in `create_response'
    from /app/vendor/bundle/ruby/2.2.0/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/http/default.rb:90:in `request'
    from /app/vendor/bundle/ruby/2.2.0/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/http/common.rb:59:in `call'
    from /app/vendor/bundle/ruby/2.2.0/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/bridge.rb:649:in `raw_execute'
    from /app/vendor/bundle/ruby/2.2.0/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/bridge.rb:123:in `create_session'
    from /app/vendor/bundle/ruby/2.2.0/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/remote/bridge.rb:87:in `initialize'
    from /app/vendor/bundle/ruby/2.2.0/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/chrome/bridge.rb:48:in `initialize'
    from /app/vendor/bundle/ruby/2.2.0/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/common/driver.rb:64:in `new'
    from /app/vendor/bundle/ruby/2.2.0/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver/common/driver.rb:64:in `for'
    from /app/vendor/bundle/ruby/2.2.0/gems/selenium-webdriver-2.53.4/lib/selenium/webdriver.rb:84:in `for'
    from /app/lib/mealpass_orderer.rb:12:in `initialize'
    from /app/lib/mealpass_orderer.rb:8:in `new'
    from /app/lib/mealpass_orderer.rb:8:in `run'
    from bin/run.rb:3:in `<main>'

UPDATE:

I tried the same with AWS EC2 server (launched instance, cloned git repo, installed all dependencies). The same happens there as well. That is, able to execute chromedriver from terminal, but seeing same error when run the script.

like image 256
Petr Gazarov Avatar asked Jul 08 '16 04:07

Petr Gazarov


People also ask

Where should I put the Chrome driver in Selenium?

Now we need to move ChromeDriver somewhere that Python and Selenium will be able to find it (a.k.a. in your PATH ). The easiest place to put it is in C:\Windows . So move it there!

Where is my Chrome binary located?

What is the exact path to the chrome binary on your PC? If you are working on Windows 10, it would be C:\Program Files (x86)\Google\Chrome\Application\chrome.exe . As as yours? You can explicity specify the location of chrome.exe by Project > Settings > Execution > Default > WebUI > Chrome.

Does ChromeDriver need to match Chrome version?

ChromeDriver is only compatible with Chrome version 12.0. 712.0 or newer. If you need to test an older version of Chrome, use Selenium RC and a Selenium-backed WebDriver instance.


2 Answers

ChromeDriver is just a driver for Chrome. It needs the actual Chrome browser installed on the same machine to actually work.

Heroku doesn't have Chrome installed on its dynos by default. You need to use a buildpack that installs Chrome. For example:

https://github.com/dwayhs/heroku-buildpack-chrome

You can see how it fetches Chrome:

https://github.com/dwayhs/heroku-buildpack-chrome/blob/master/bin/compile#L36-38

like image 89
Ilya Vassilevsky Avatar answered Oct 04 '22 16:10

Ilya Vassilevsky


ANSWER

YOUR_PATH = 'whatever/your/path/is' # to your bin dir
CURRENT_DIR = File.expand_path(File.dirname(__FILE__))
CHROMEDRIVER_FN = File.join(CURRENT_DIR, YOUR_PATH, "bin/chromedriver")
# —OR—
#CHROMEDRIVER_FN = File.join(File.absolute_path('..', CURRENT_DIR), YOUR_PATH, "bin/chromedriver")
Selenium::WebDriver::Chrome.driver_path = CHROMEDRIVER_FN

CONTEXT

The example below shows my setup for Selenium Chromedriver in a recent Ruby project.

1) The file structure:

ruby_app/
├── Gemfile
├── Gemfile.lock
├── History.txt
├── Manifest.txt
├── README.md
├── Rakefile
├── bin
│   └── chromedriver
├── doc
├── lib
│   └── ruby_app.rb
└── test
    ├── test_files
    │   ├── test_config.yml
    │   └── uris_array_dump.yml
    ├── test_ruby_app.rb
    ├── test_google.rb
    ├── test_helper.rb
    └── test_output

2) In test/test_helper.rb:

TEST_DIR = File.expand_path(File.dirname(__FILE__))
TEST_FILES = File.join(TEST_DIR, "test_files")
TEST_OUTPUT = File.join(TEST_DIR, "test_output")
CHROMEDRIVER_FN = File.join(File.absolute_path('..', TEST_DIR), "bin", "chromedriver")

The above code uses File.absolute_path, see: http://ruby-doc.org/core-2.3.1/File.html#method-c-absolute_path

Converts a pathname to an absolute pathname. Relative paths are referenced from the current working directory of the process unless dir_string is given, in which case it will be used as the starting point.


3) In test/test_google.rb:

Selenium::WebDriver::Chrome.driver_path = CHROMEDRIVER_FN
like image 31
SoAwesomeMan Avatar answered Oct 04 '22 16:10

SoAwesomeMan