heroku / heroku-buildpack-google-chrome

Run (headless) Google Chrome on Heroku
297 stars 363 forks source link

Chrome binary not detected #26

Open vincentwhales opened 7 years ago

vincentwhales commented 7 years ago

I am getting the following problem in my heroku app:

2017-08-01 20:54:22 ac744713-8102-4c83-81fc-b4be4786b925 selenium.webdriver.remote.remote_connection[4] DEBUG Finished Request
Traceback (most recent call last):
  File "manage.py", line 89, in <module>
    manager.run()
  File "/app/.heroku/python/lib/python2.7/site-packages/flask_script/__init__.py", line 412, in run
    result = self.handle(sys.argv[0], sys.argv[1:])
  File "/app/.heroku/python/lib/python2.7/site-packages/flask_script/__init__.py", line 383, in handle
    res = handle(*args, **config)
  File "/app/.heroku/python/lib/python2.7/site-packages/flask_script/commands.py", line 216, in __call__
    return self.run(*args, **kwargs)
  File "manage.py", line 83, in cron
    d.main()
  File "/app/blackbird/domain/cron.py", line 58, in main
    self.take_screenshots()
  File "/app/blackbird/domain/cron.py", line 208, in take_screenshots
    self.driver = webdriver.Chrome('chromedriver')
  File "/app/.heroku/python/lib/python2.7/site-packages/selenium/webdriver/chrome/webdriver.py", line 69, in __init__
    desired_capabilities=desired_capabilities)
  File "/app/.heroku/python/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 98, in __init__
    self.start_session(desired_capabilities, browser_profile)
  File "/app/.heroku/python/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 188, in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
  File "/app/.heroku/python/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 256, in execute
    self.error_handler.check_response(response)
  File "/app/.heroku/python/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: cannot find Chrome binary
  (Driver info: chromedriver=2.31.488763 (092de99f48a300323ecf8c2a4e2e7cab51de5ba8),platform=Linux 3.13.0-123-generic x86_64)

even though I have added the chrome driver and the google-chrome buildpacks:

enter image description here

Is there a step that I am missing to make my chrome binary available to my app?

frbry commented 7 years ago

What is the executable_path you're giving to Selenium driver? You should use the environment variables exported by the buildpack: https://github.com/heroku/heroku-buildpack-google-chrome#selenium

jamintz commented 7 years ago

Apologies for the basic question, I'm getting a similar issue (seeing Selenium::WebDriver::Error::WebDriverError: Unable to find the chromedriver executable when I try to run Selenium). My buildpacks are:

screen shot 2017-08-29 at 10 41 54 am

I see the instructions above for selenium but I'm not sure how to follow them, how do I "tell Selenium/chromedriver that the chrome binary is at /app/.apt/usr/bin/google-chrome"? The $GOOGLE_CHROME_BIN, and $GOOGLE_CHROME_SHIM variables don't seem to be set to anything initially, should they be? Thanks @frbry

frbry commented 7 years ago

$GOOGLE_CHROME_BIN and $GOOGLE_CHROME_SHIM are exported at the end of the buildpack's code. https://github.com/heroku/heroku-buildpack-google-chrome/blob/d93581e904e63fe232d8fd997bdfbe6b39fd5a39/bin/compile#L139-L150

I don't know what it'd look like in Ruby but in Python I have the following:

import os
from selenium import webdriver
# ...
chrome_exec_shim = os.environ.get("GOOGLE_CHROME_BIN", "chromedriver")
self.selenium = webdriver.Chrome(executable_path=chrome_exec_shim)
# ...
jamintz commented 7 years ago

It doesn't look like the buildpacks are setting the GOOGLE_CHROME_BIN and GOOGLE_CHROME_SHIM variables as they're both nil after compiling the buildpacks.

frbry commented 7 years ago

That's weird, I don't know what the reason would be. However, this is what I get from the shim env. variable currently: /app/.apt/usr/bin/google-chrome-stable. You can try hardcoding this but obviously you'll have to update your code if Heroku updates the buildpack.

By the way, would you mind letting me know if you can get this all to work? I'm currently trying to run Chrome and my Selenium tests but for some reason I get the error below: WebDriverException: Message: Service /app/.apt/usr/bin/google-chrome-stable unexpectedly exited. Status code was: 1

jamintz commented 7 years ago

Update, some progress but not all the way. I got the ENV variables to populate and am now trying

Selenium::WebDriver::Chrome.driver_path=ENV['GOOGLE_CHROME_BIN']
Watir::Browser.new :chrome, headless:true

but this still results in

Selenium::WebDriver::Error::WebDriverError: unable to connect to chromedriver 127.0.0.1:9517

(with or without the headless:true argument)

frbry commented 7 years ago

@jamintz I finally managed to fix it!

You need to give WebDriver the path for the chromedriver which is installed by the chromedriver buildpack. And you need to pass the chrome executable (which is found in $GOOGLE_CHROME_SHIM) as an option to WebDriver.

However, this still caused an error mentioned here: https://github.com/heroku/heroku-buildpack-xvfb-google-chrome/issues/7. As mentioned, there's a fork of the official buildpack which installs a package that solves the issue. I had to use that buildpack instead as you can see below.

buildpacks in app.json:

"buildpacks": [
        {
          "url": "https://github.com/piotras/heroku-buildpack-gettext.git"
        },
        {
          "url": "https://github.com/kevinsawicki/heroku-buildpack-xvfb-google-chrome.git"
        },
        {
          "url": "heroku/python"
        }
]

Python code:

from selenium.webdriver.chrome.options import Options as ChromeOptions
chrome_bin = os.environ.get('GOOGLE_CHROME_SHIM', None)
opts = ChromeOptions()
opts.binary_location = chrome_bin
self.selenium = webdriver.Chrome(executable_path="chromedriver", chrome_options=opts)

Note: chromedriver buildpack is not included in my example as I install it using by pip install chromedriver_installer so that it works in local development as well.

I hope this helps.

ronen651 commented 6 years ago

@frbry I face the same problem I hard code those param GOOGLE_CHROME_BIN = /app/.apt/opt/google/chrome/chrome GOOGLE_CHROME_SHIM = /app/.apt/usr/bin/google-chrome-stableand I dont know were do I need to put the python code you mention can you please explain how to do it? thanks

frbry commented 6 years ago

@ronen651 I have it in my TestCase's setUp() so selenium is initialized properly before my test cases are run.

ronen651 commented 6 years ago

Thanks!, I use it take a snapshot in production , do you have an Idea where can I put that code?

frbry commented 6 years ago

The code above needs to run before you can use selenium to do anything. So you can put it right before your snapshot routine.

ronen651 commented 6 years ago

@frbry Thanks it works!!!!, I was searaching for a solotion more than a week- you make my day:) I paste my code if it will help some one that want to use it in a function without the 'this' frbry - please let me know if the code is correct as I am new to django pyhton and dont want to misslead someone else with the example.

`

chrome_bin = os.environ.get('GOOGLE_CHROME_SHIM', None)

opts = ChromeOptions()

opts.binary_location = chrome_bin

driver = webdriver.Chrome(executable_path="chromedriver", chrome_options=opts)

webdriver.Chrome(DRIVER)

driver.get(url)

`

BertramShell commented 6 years ago

@frbry Hello thanks for your help; however, this doesn't work like a path executable_path="chromedriver". What should I do when I installed chromedriver_installer.

rleon14 commented 6 years ago

not solved yet. i already tried all of method.

rolme commented 6 years ago

Any update on this? I am getting this error:

irb(main):002:0> ENV['GOOGLE_CHROME_SHIM']
=> "/app/.apt/usr/bin/google-chrome-stable"
irb(main):003:0> Selenium::WebDriver::Chrome.driver_path = ENV['GOOGLE_CHROME_SHIM']
=> "/app/.apt/usr/bin/google-chrome-stable"
irb(main):004:0> browser = Watir::Browser.new :chrome, headless: true
Traceback (most recent call last):
        2: from (irb):4
        1: from (irb):4:in `new'
Selenium::WebDriver::Error::WebDriverError (unable to connect to chromedriver 127.0.0.1:9516)
fcschmidt commented 6 years ago

In python this solution solved my problem.

CHROMEDRIVER_PATH = "/app/.chromedriver/bin/chromedriver"

chrome_bin = os.environ.get('GOOGLE_CHROME_BIN', "chromedriver")
options = webdriver.ChromeOptions()
options.binary_location = chrome_bin
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
options.add_argument('headless')
options.add_argument('window-size=1200x600')
driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, chrome_options=options)
dalyr95 commented 6 years ago

For those who come across this and are using node, here's how I got it to work. Install the two chrome buildpacks as above...

Then

I add to my Procfile (not sure if needed) just in case web: /app/.apt/usr/bin/google-chrome-stable & node ./app/index.js

jing0703 commented 5 years ago

I still got the following error when trying to deploy my flask app with selenium to Heroku:

2018-09-29T02:08:08.510162+00:00 app[web.1]: driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, chrome_options=options) 2018-09-29T02:08:08.510167+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/chrome/webdriver.py", line 73, in init 2018-09-29T02:08:08.510169+00:00 app[web.1]: self.service.start() 2018-09-29T02:08:08.510170+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/common/service.py", line 98, in start 2018-09-29T02:08:08.510172+00:00 app[web.1]: self.assert_process_still_running() 2018-09-29T02:08:08.510181+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/common/service.py", line 111, in assert_process_still_running 2018-09-29T02:08:08.510183+00:00 app[web.1]: % (self.path, return_code) 2018-09-29T02:08:08.510185+00:00 app[web.1]: selenium.common.exceptions.WebDriverException: Message: Service /app/.chromedriver/bin/chromedriver unexpectedly exited. Status code was: 127

This is my setting: CHROMEDRIVER_PATH = "/app/.chromedriver/bin/chromedriver" chrome_bin = os.environ.get('GOOGLE_CHROME_SHIM', None) options = ChromeOptions() options.binary_location = chrome_bin options.add_argument('--disable-gpu') options.add_argument("--no-sandbox") options.add_argument('headless') options.add_argument('window-size=1200x600') driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, chrome_options=options)

I also added buildbacks: "https://github.com/heroku/heroku-buildpack-google-chrome", "https://github.com/notvad/heroku-buildpack-selenium", "https://github.com/heroku/heroku-buildpack-chromedriver"

I don't know why selenium exited with status code 127, could you help me with it? Thank you very much!

haseebehsan commented 5 years ago

I still got the following error when trying to deploy my flask app with selenium to Heroku:

2018-09-29T02:08:08.510162+00:00 app[web.1]: driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, chrome_options=options) 2018-09-29T02:08:08.510167+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/chrome/webdriver.py", line 73, in init 2018-09-29T02:08:08.510169+00:00 app[web.1]: self.service.start() 2018-09-29T02:08:08.510170+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/common/service.py", line 98, in start 2018-09-29T02:08:08.510172+00:00 app[web.1]: self.assert_process_still_running() 2018-09-29T02:08:08.510181+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/common/service.py", line 111, in assert_process_still_running 2018-09-29T02:08:08.510183+00:00 app[web.1]: % (self.path, return_code) 2018-09-29T02:08:08.510185+00:00 app[web.1]: selenium.common.exceptions.WebDriverException: Message: Service /app/.chromedriver/bin/chromedriver unexpectedly exited. Status code was: 127

This is my setting: CHROMEDRIVER_PATH = "/app/.chromedriver/bin/chromedriver" chrome_bin = os.environ.get('GOOGLE_CHROME_SHIM', None) options = ChromeOptions() options.binary_location = chrome_bin options.add_argument('--disable-gpu') options.add_argument("--no-sandbox") options.add_argument('headless') options.add_argument('window-size=1200x600') driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, chrome_options=options)

I also added buildbacks: "https://github.com/heroku/heroku-buildpack-google-chrome", "https://github.com/notvad/heroku-buildpack-selenium", "https://github.com/heroku/heroku-buildpack-chromedriver"

I don't know why selenium exited with status code 127, could you help me with it? Thank you very much!

have you go tit solved yet? if yes how?

jing0703 commented 5 years ago

No. I even tried to use developer version of chrome, but it still give me error. Finally I deployed it by using PhantomJS. Here is an example code:
from selenium import webdriver driver = webdriver.PhantomJS() url1 = "https://www.jpl.nasa.gov/spaceimages/?search=&category=Mars" driver.get(url1)

For deploying to Heroku, you need to have other settings. This post may help you with it: http://isaacjohnwesley.tumblr.com/post/57439869677/setting-up-phantomjs-in-heroku-for-your-python-app

frbry commented 5 years ago

This is what you do as of March 2019:

For the Heroku cedar-14 stack; make sure you have https://github.com/heroku/heroku-buildpack-xvfb-google-chrome buildpack added to your app. If you are using Heroku Pipelines, make sure it's at least added to the base app (e.g. dev or staging) where the app gets built.

import chromedriver_binary # Importing this exports chrome path to $PATH, below code will fail without this import
from selenium import webdriver

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')

driver = webdriver.Chrome(chrome_options=chrome_options)
franzejr commented 5 years ago

My app is also not finding the chrome binary...

To get chrome running, I'm doing everything according to the specifications:

chrome_bin = ENV.fetch('GOOGLE_CHROME_SHIM', nil)

chrome_opts = chrome_bin ? { 'chromeOptions' => { 'binary' => chrome_bin } } : {}

Capybara.register_driver :chrome do |app|
  Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    desired_capabilities: Selenium::WebDriver::Remote::Capabilities.chrome(chrome_opts)
  )
end

Capybara.javascript_driver = :chrome

I'm running my app on heroku-18, then error I got is:

StandardError:
Failed to find Chrome binary or its version.

Running the CI with the option --no-cache:

heroku ci:debug --no-cache --app <MyApp>

I have the GOOGLE_CHROME_SHIM set up. But then when I try to execute chrome:

~ $ echo $GOOGLE_CHROME_SHIM
/app/.apt/usr/bin/google-chrome-stable
~ $ /app/.apt/usr/bin/google-chrome-stable
/app/.apt/opt/google/chrome/chrome: symbol lookup error: /app/.apt/usr/lib/x86_64-linux-gnu/libatk-1.0.so.0: undefined symbol: g_log_structured_standard

What I am doing wrong here? Any thoughts?

ryanwmartin commented 4 years ago

I am still running into this error with Rails 6.0.2.2. After following the instruction in the Readme and several alternate approaches, all of which failed, I would welcome any advice but wanted to flag that this isn't resolved.

kopchickm commented 3 years ago

Not sure if this'll help, but I was finally able to get my tests working by setting ::Selenium::WebDriver::Chrome.path to the GOOGLE_CHROME_SHIM environment variable. Here's my code below:

require "selenium/webdriver"

chrome_bin = ENV.fetch("GOOGLE_CHROME_SHIM", nil)

Capybara.register_driver :headless_chrome do |app|
  options = ::Selenium::WebDriver::Chrome::Options.new
  options.headless!
  options.add_argument "--window-size=1680,1050"
  if chrome_bin
    ::Selenium::WebDriver::Chrome.path = chrome_bin
  end

  Capybara::Selenium::Driver.new app,
                                 browser: :chrome,
                                 options: options
end

Capybara.javascript_driver = :headless_chrome
iraritchiemeek commented 3 years ago

Had the same issue with a ruby build, @kopchickm's answer fixed it for me. Maybe the readme should be updated?

ClayShentrup commented 3 years ago

@kopchickm thanks! I just used this and it worked.

if ENV.key?('GOOGLE_CHROME_SHIM') # Heroku CI
  Selenium::WebDriver::Chrome.path = ENV.fetch('GOOGLE_CHROME_SHIM')
  Capybara.javascript_driver = :selenium_chrome_headless
else
agad495 commented 1 year ago

I still got the following error when trying to deploy my flask app with selenium to Heroku:

2018-09-29T02:08:08.510162+00:00 app[web.1]: driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, chrome_options=options) 2018-09-29T02:08:08.510167+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/chrome/webdriver.py", line 73, in init 2018-09-29T02:08:08.510169+00:00 app[web.1]: self.service.start() 2018-09-29T02:08:08.510170+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/common/service.py", line 98, in start 2018-09-29T02:08:08.510172+00:00 app[web.1]: self.assert_process_still_running() 2018-09-29T02:08:08.510181+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/common/service.py", line 111, in assert_process_still_running 2018-09-29T02:08:08.510183+00:00 app[web.1]: % (self.path, return_code) 2018-09-29T02:08:08.510185+00:00 app[web.1]: selenium.common.exceptions.WebDriverException: Message: Service /app/.chromedriver/bin/chromedriver unexpectedly exited. Status code was: 127

This is my setting: CHROMEDRIVER_PATH = "/app/.chromedriver/bin/chromedriver" chrome_bin = os.environ.get('GOOGLE_CHROME_SHIM', None) options = ChromeOptions() options.binary_location = chrome_bin options.add_argument('--disable-gpu') options.add_argument("--no-sandbox") options.add_argument('headless') options.add_argument('window-size=1200x600') driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, chrome_options=options)

I also added buildbacks: "https://github.com/heroku/heroku-buildpack-google-chrome", "https://github.com/notvad/heroku-buildpack-selenium", "https://github.com/heroku/heroku-buildpack-chromedriver"

I don't know why selenium exited with status code 127, could you help me with it? Thank you very much!

Has anyone found a solution to this using Chrome?

siddharthmittal97 commented 11 months ago

Hello All,

I am using WebdriverIo with NodeJs Framework. My entire code is working fine in local system. Scripts are running fine. But When I am running in Heroku I am getting error as

npx wdio run wdio.conf.js --spec ./features/test.feature Execution of 1 workers started at 2023-10-12T08:18:31.996Z [0-0] RUNNING in chrome - /features/test.feature [0-0] 2023-10-12T08:18:34.162Z ERROR webdriver: Request failed with status 500 due to unknown error: unknown error: no chrome binary at /app/.apt/opt/google/chrome/google-chrome

I have added following build back after reading from community & blogs

capabilities: [{

  // maxInstances can get overwritten per capability. So if you have an in-house Selenium
  // grid with only 5 firefox instances available you can make sure that not more than
  // 5 instances get started at a time.
  maxInstances: 5,
  //
  browserName: 'chrome',
  acceptInsecureCerts: true,
  "goog:chromeOptions": {
    binary: process.env.GOOGLE_CHROME_BIN,
      prefs: {
        credentials_enable_service: false,
        "profile.password_manager_enabled": false,
      },
      args: [
        '--headless',
        //"--disk-cache-dir=" + __dirname + "/.cache",
        "--disable-dev-shm-usage",
        "--no-sandbox",
        "disable-notifications",
        //"disable-infobars",
       "--window-size=1028,768",
      ],
      excludeSwitches: ["enable-automation"],
      useAutomationExtension: false,
    },
  // If outputDir is provided WebdriverIO can capture driver session logs
  // it is possible to configure which logTypes to include/exclude.
  // excludeDriverLogs: ['*'], // pass '*' to exclude all driver session logs
  // excludeDriverLogs: ['bugreport', 'server'],

}],

I am using WebdriverIo with NodeJs Framework. My entire code is working fine in local system. Scripts are running fine. But When I am running in Heroku I am getting error as

npx wdio run wdio.conf.js --spec ./features/test.feature Execution of 1 workers started at 2023-10-12T08:18:31.996Z [0-0] RUNNING in chrome - /features/test.feature [0-0] 2023-10-12T08:18:34.162Z ERROR webdriver: Request failed with status 500 due to unknown error: unknown error: no chrome binary at /app/.apt/opt/google/chrome/google-chrome

I have added following build back after reading from community & blogs

capabilities: [{

  // maxInstances can get overwritten per capability. So if you have an in-house Selenium
  // grid with only 5 firefox instances available you can make sure that not more than
  // 5 instances get started at a time.
  maxInstances: 5,
  //
  browserName: 'chrome',
  acceptInsecureCerts: true,
  "goog:chromeOptions": {
    binary: process.env.GOOGLE_CHROME_BIN,
      prefs: {
        credentials_enable_service: false,
        "profile.password_manager_enabled": false,
      },
      args: [
        '--headless',
        //"--disk-cache-dir=" + __dirname + "/.cache",
        "--disable-dev-shm-usage",
        "--no-sandbox",
        "disable-notifications",
        //"disable-infobars",
       "--window-size=1028,768",
      ],
      excludeSwitches: ["enable-automation"],
      useAutomationExtension: false,
    },
  // If outputDir is provided WebdriverIO can capture driver session logs
  // it is possible to configure which logTypes to include/exclude.
  // excludeDriverLogs: ['*'], // pass '*' to exclude all driver session logs
  // excludeDriverLogs: ['bugreport', 'server'],

}],

Let me share package.json snapshot

{ "name": "testing", "version": "1.0.0", "description": "test", "main": "index.js", "scripts": { "test": "npx wdio run wdio.conf.js --spec ./features/test.feature", "wdio": "wdio run ./wdio.conf.js" }, "author": "test", "license": "ISC", "devDependencies": { "@wdio/local-runner": "^7.25.4", "@wdio/spec-reporter": "^8.11.2", "chromedriver": "~117.0.3", "wdio-chromedriver-service": "^8.1.1" }, "dependencies": { "@wdio/cli": "^7.25.4", "@wdio/cucumber-framework": "^7.25.4", "cucumber-html-reporter": "^5.5.0", "fs-extra": "^11.1.1", "puppeteer": "^21.3.8", "wdio-cucumberjs-json-reporter": "^4.4.3" } }

Warm Request to please help & provide the solution respected team

Same I have posted on stack over flow as well https://stackoverflow.com/questions/77278932/heroku-request-failed-with-status-500-due-to-unknown-error-unknown-error-no