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

ChromeDriver requires a Chrome for Testing binary by default #30

Closed
diemol opened this issue Jul 19, 2023 · 32 comments
Closed

ChromeDriver requires a Chrome for Testing binary by default #30

diemol opened this issue Jul 19, 2023 · 32 comments
Assignees

Comments

@diemol
Copy link

diemol commented Jul 19, 2023

As we are starting to add support for Chrome for Testing in Selenium, we have noticed that when using ChromeDriver 115, it expects a Chrome for Testing binary, and it will only use the already installed regular Chrome if the location is passed through the goog:chromeOptions section.

Not sure if we missed that detail or if it needs to be documented.

Is it possible to have as default behavior in ChromeDriver to use the already installed "regular" Chrome binary? Almost every one using ChromeDriver right now follows that thought. Perhaps a new flag in ChromeDriver that does that.

Thanks!

@AutomatedTester
Copy link

@mathiasbynens could you look at this as a priority?

@mathiasbynens
Copy link
Member

Thanks for the report! We didn’t make any changes to ChromeDriver itself, just to the release process and where the ZIP files get uploaded. Could you elaborate which part of ChromeDriver “expects” a CfT binary?

@soulgalore
Copy link

soulgalore commented Jul 20, 2023

On Linux Chomedriver 115 finds Chrome (running default settings). When I test on a Mac (both arm/intel) Chromedriver 115 doesn't find Chrome 115. If I set the binary path to the Chrome binary it works. If I switch to Chromedriver 114 it works. I'm running without Chrome for Testing installed.

@mathiasbynens
Copy link
Member

It’s clear there is some kind of issue, but it cannot be because of any new logic in ChromeDriver to find the Chrome binary, because we made no changes to that code. We certainly don’t “require” the use of CfT for the Chrome binaries. The issue must be related to the way we package up the ChromeDriver binaries as distributed via CfT infra. Here’s a comparison.

ChromeDriver 114 (old download location):

$ unzip -l chromedriver_mac_arm64.zip
Archive:  chromedriver_mac_arm64.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
 15363648  05-27-2023 02:39   chromedriver
   272909  05-27-2023 02:39   LICENSE.chromedriver
---------                     -------
 15636557                     2 files

ChromeDriver 115 (new download location):

$ unzip -l chromedriver-mac-arm64.zip
Archive:  chromedriver-mac-arm64.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
   239464  07-15-2023 02:29   chromedriver-mac-arm64/LICENSE.chromedriver
 15661456  07-15-2023 02:29   chromedriver-mac-arm64/chromedriver
---------                     -------
 15900920                     2 files

The main difference is that the chromedriver binary is no longer in the root of the ZIP file; it now lives within a subdirectory.

@mathiasbynens
Copy link
Member

@thiagowfx, https://chromium-review.googlesource.com/c/chromium/src/+/4101520 added Chrome for Testing to the list of known browser locations on Windows. Given the above, do we need something similar for macOS?

@thiagowfx
Copy link
Contributor

Looking into the history of https://source.chromium.org/chromium/chromium/src/+/main:chrome/test/chromedriver/chrome/chrome_finder.cc;bpv=1;bpt=0, nothing has significantly changed recently (last change was on Jan 23rd this year).

It seems the current workaround is to manually provide the browser path, and the issue is with the defaults, the system Chrome browser is not being properly detected, correct?

@diemol
Copy link
Author

diemol commented Jul 20, 2023

Exactly, the defaults seems to not work anymore on macOS at least.

@thiagowfx
Copy link
Contributor

We figured out what the issue is. Will try to send a fix shortly.

PRODUCT_STRING is set to "Chrome for Testing" for CfT builds (whereas it's typically "Chromium" or "Chrome" otherwise). M115 chromedriver uses such a setting, as it's built via the same process as CfT is built.

However, that is hard-coded in chrome_finder.cc for both Windows and macOS. Linux does not have that issue.

@thiagowfx thiagowfx self-assigned this Jul 20, 2023
@thiagowfx
Copy link
Contributor

thiagowfx commented Jul 20, 2023

Shifting issue to the Chromium bug tracker: https://bugs.chromium.org/p/chromium/issues/detail?id=1466427. Will keep this one open (e.g. maybe to figure out cherry-picking and/or patching M115), but refer to the other one from now on for the underlying issue.

@diemol
Copy link
Author

diemol commented Jul 20, 2023

Thank you for checking, @thiagowfx!

@thiagowfx
Copy link
Contributor

thiagowfx commented Jul 20, 2023

The issue affects macOS only.

Here's the current list of workarounds:

  1. Use Chrome for Testing.
  2. Manually provide a Chrome browser path (flag) to the chromedriver executable.
  3. Create a symlink (disclaimer: not tested, may need sudo):
ln -s "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" "/Applications/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing"
  1. Patch https://chromium-review.googlesource.com/c/chromium/src/+/4701575 and build chromedriver manually.

@bonigarcia
Copy link

As a workaround for Selenium (and macOS), we need to specify the Chrome binary path as follows (this is Java, although the equivalence in other binding languages will do the trick as well):

ChromeOptions options = new ChromeOptions();
options.setBinary("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome");
WebDriver driver = new ChromeDriver(options);

@thiagowfx
Copy link
Contributor

The fix has been landed. We're currently looking into the feasibility of releasing a backmerge for M115.

@wimleers
Copy link

Why is this not widely announced? At the very least at https://twitter.com/ChromeDevTools?

This is extremely disruptive, especially due to:

  1. Chrome's auto-update behavior
  2. the very unhelpful error message: unknown error: cannot find Chrome binary — which doesn't say where it's looking, or how to configure a different location 😳

@dbarbuzzi
Copy link

Create a symlink (disclaimer: not tested, may need sudo):

The symlink works for me, but with caveats:

  1. You do need sudo
  2. The listed command requires you to first symlink the .app folders properly otherwise the link target’s folder doesn’t exist yet.

Commands I used:

sudo ln -s "/Applications/Google Chrome.app" "/Applications/Google Chrome for Testing.app"
sudo ln -s "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" "/Applications/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing"

@thiagowfx
Copy link
Contributor

Thanks for testing, Domenic.

x-posting for visibility (https://bugs.chromium.org/p/chromium/issues/detail?id=1466427#c27):

From @mathiasbynens:

The patches have been backmerged, but no release containing them has been made yet. We hope to get a release out by the end of next week. Thank you for your patience.

@thiagowfx
Copy link
Contributor

the very unhelpful error message

This is a reasonable point. Feel free to file a bug at https://crbug.com/new.

@radar
Copy link

radar commented Jul 28, 2023

What worked for me was downloading "Google Chrome for Testing" and copying it over to my /Applications directory. Because of Mac's gatekeeper, it won't work by default. So I needed to run:

sudo xattr -cr '/Applications/Google Chrome for Testing.app'

Then Chromedriver was able to find this.

@mathiasbynens
Copy link
Member

What worked for me was downloading "Google Chrome for Testing" and copying it over to my /Applications directory. Because of Mac's gatekeeper, it won't work by default. So I needed to run:

sudo xattr -cr '/Applications/Google Chrome for Testing.app'

Then Chromedriver was able to find this.

FWIW, the Gatekeeper thing is documented here: https://github.com/GoogleChromeLabs/chrome-for-testing#macos-says-the-app-is-damaged-what-now We recommend using @puppeteer/browsers to install Chrome for Testing + ChromeDriver, or building your own automated scripts on top of our JSON API endpoints.

@wimleers
Copy link

wimleers commented Aug 1, 2023

the very unhelpful error message

This is a reasonable point. Feel free to file a bug at https://crbug.com/new.

I tried. But I can't. It requires a Google account, which I don't have. 😅 Could you please file one on my behalf? 🙏

@thiagowfx
Copy link
Contributor

Filed https://bugs.chromium.org/p/chromium/issues/detail?id=1469612

@mathiasbynens
Copy link
Member

Chrome for Testing 115.0.5790.170 is out now and should include the backported fix. Please try it out and let us know if this resolves the issues.

@mdmintz
Copy link

mdmintz commented Aug 3, 2023

@mathiasbynens It's working for me now. Thank you for the fix!

@TheTrio
Copy link

TheTrio commented Aug 4, 2023

so how do I get this fix now? Is updating Chrome all that's required? Thanks

@mathiasbynens
Copy link
Member

so how do I get this fix now? Is updating Chrome all that's required? Thanks

Update to the latest ChromeDriver 115.0.5790.170 (or more recent).

BeniRupp added a commit to BeniRupp/node-chromedriver that referenced this issue Aug 7, 2023
Use latest chromedriver version that fixes a bug in the chrome binary resolution and solves the error:

An error occurred while creating a new ChromeDriver session: [WebDriverError] unknown error: cannot find Chrome binary

See: GoogleChromeLabs/chrome-for-testing#30

and: https://bugs.chromium.org/p/chromium/issues/detail?id=1466427
giggio pushed a commit to giggio/node-chromedriver that referenced this issue Aug 7, 2023
Use latest chromedriver version that fixes a bug in the chrome binary resolution and solves the error:

An error occurred while creating a new ChromeDriver session: [WebDriverError] unknown error: cannot find Chrome binary

See: GoogleChromeLabs/chrome-for-testing#30

and: https://bugs.chromium.org/p/chromium/issues/detail?id=1466427
@debidatta650
Copy link

I am not able to use it by using python. Can anyone please share a sample code in python, how to use the new version?
Thanks in advance!!

@ryanbuckner
Copy link

I am not able to use it by using python. Can anyone please share a sample code in python, how to use the new version? Thanks in advance!!

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
from selenium.webdriver.common.keys import Keys
import credentials


boolSuccess = False
strSuccessMsg = ""
strData = 'initial'
ATTUrl = 'https://www.paygonline.com/websc/home.html'
prodChromePath = '/Library/Application Support/Perceptive Automation/Python3-includes/chromedriver'

##################################

#get creds
plancreds = credentials.getdataplancreds('user')
usr = plancreds['usr']
pwd = plancreds['password']
##################################


driver = webdriver.Chrome(executable_path='/Library/Application Support/Perceptive Automation/Python3-includes/chromedriver')

#indigo.server.log("checking data. stand by...")
try:                  
	driver.get(ATTUrl);
	time.sleep(5)  # Let the user actually see something
except:
	indigo.server.log(u"Unable launch webdriver. Check the version of the chromedriver", type="ATT Data Plan")
	driver.close()
	exit()

try:
	# Login
	login_box = driver.find_element_by_name('phoneNumber')
	login_box.send_keys(usr)

	# Login
	pwd_box = driver.find_element_by_name('password')
	pwd_box.send_keys(pwd)
	pwd_box.send_keys(Keys.ENTER)
except:
	indigo.server.log(u"Unable log into ATT", type="ATT Data Plan")
	driver.close()
	exit()

@kazi-rashedul-haque
Copy link

kazi-rashedul-haque commented Aug 18, 2023

I have the following to handle chrome driver, but I do not seem to make them work :(
Could someone be kind enough to help me pinpoint the issue?

The following is in my build.gradle file:

String webDriverDir = "$projectDir/webdriver"
String chromeVersion = '116.0.5845.96'

tasks.register('downloadChromeDriverZip', Download) {
    if (OperatingSystem.current().isMacOsX()) {
        src "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/${chromeVersion}/mac-x64/chrome-mac-x64.zip"
    } else if (OperatingSystem.current().isLinux()) {
        src "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/${chromeVersion}/linux64/chrome-linux64.zip"
    } else {
        src "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/${chromeVersion}/win32/chrome-win32.zip"
    }
    dest new File(webDriverDir, "/chrome/chromedriver-${chromeVersion}.zip")
    quiet true
    overwrite true
    onlyIfNewer true
    compress false
    onlyIf {
        !dest.exists()
    }
}

tasks.register('downloadAndUnzipChromeDriver', Copy) {
    dependsOn downloadChromeDriverZip
    from zipTree(downloadChromeDriverZip.dest)
    into new File(webDriverDir, "/chrome/${chromeVersion}")
}

if (project.hasProperty('chrome')) {
    dependsOn downloadAndUnzipChromeDriver
    systemProperties([
            'webdriver.chrome.driver': "${downloadAndUnzipChromeDriver.destinationDir}/chrome-mac-x64/Google Chrome for Testing.app/Contents/Frameworks/Google Chrome for Testing Framework.framework/Versions/${chromeVersion}/Google Chrome for Testing Framework",
            'fluentlenium.webDriver' : 'chrome'
    ])
}

The following is in my SupportedWebDriver class which my manager has setup:

protected ChromeOptions chromeOptions(Device device) {
    ChromeOptions chromeOptions = new ChromeOptions();
    if (device.isMobile()) {
        Map<String, Object> deviceMetrics = new HashMap<>();
        deviceMetrics.put("width", device.getScreenSize().width);
        deviceMetrics.put("height", device.getScreenSize().height);
        deviceMetrics.put("pixelRatio", device.getPixelRatio());

        Map<String, Object> mobileEmulation = new HashMap<>();
        mobileEmulation.put("deviceMetrics", deviceMetrics);
        mobileEmulation.put("userAgent", device.getUserAgent());
        chromeOptions.setExperimentalOption("mobileEmulation", mobileEmulation);
    }

    chromeOptions.setBinary("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome");
    chromeOptions.addArguments("--remote-allow-origins=*");
    chromeOptions.addArguments("window-size=" + device.getScreenSize().width + "," + device.getScreenSize().height);

    return chromeOptions;
}

@titusfortner
Copy link

@ryanbuckner @debidatta650 @kazi-rashedul-haque

If you upgrade to Selenium 4.11+ (and delete any existing drivers on the system), then Selenium will manage the drivers and the Chrome version for you without you needing to do anything.

If you want a specific version of Chrome, set it on the options class

chromeOptions.setBrowserVersion("115")

You don't have to set the driver location or the browser location, Selenium does it all!

@kazi-rashedul-haque
Copy link

Thanks @titusfortner

I was able to launch the Google Chrome for Testing browser but my test case is not running.
It is showing the following error:

org.openqa.selenium.WebDriverException: Browser failed to start, test [ viewCampaignChallengeStatementShouldSucceed ] execution interrupted.
Caused by: [ Timed out waiting for [http://localhost:15497/status] to be available after 20004 ms]

Any idea what might be the solution?
Thanks.

@titusfortner
Copy link

@kazi-rashedul-haque
First turn on logging to see if it explains what is happening: https://www.selenium.dev/documentation/webdriver/troubleshooting/logging/

If it does not explain it, open a ticket with Selenium (https://github.com/SeleniumHQ/selenium/issues) and include the logging output

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

No branches or pull requests