How to use Selenium chromedriver without being forced to update?

Matthew Sanders picture Matthew Sanders · Oct 27, 2016 · Viewed 7.9k times · Source

I have been developing a browser automation application in nwjs/node.js that uses a data driven DSL of instructions.

I decided to use the npm packages for chromedriver and selenium webdriver via the following dependencies in my package.json:

  "dependencies": {
    "selenium-webdriver": "~3.0.0-beta-2",
    "chromedriver": "~2.23.1"
  }

Everything has been going really well until recently the application stopped working at the point of simply launching the chromedriver:

var webdriver = require("selenium-webdriver");
var driver = new webdriver.Builder().forBrowser('chrome').build();

The following is the error when running in the terminal on my Macbook:

/Users/matthewsanders/test1/node_modules/selenium-webdriver/lib/promise.js:654
    throw error;
    ^

SessionNotCreatedError: session not created exception
from unknown error: Runtime.evaluate missing 'wasThrown'
  (Session info: chrome=54.0.2840.71)
  (Driver info: chromedriver=2.23.409710 (0c4084804897ac45b5ff65a690ec6583b97225c0),platform=Mac OS X 10.11.5 x86_64)
    at WebDriverError (/Users/matthewsanders/test1/node_modules/selenium-webdriver/lib/error.js:27:5)
    at SessionNotCreatedError (/Users/matthewsanders/test1/node_modules/selenium-webdriver/lib/error.js:214:5)
    at Object.checkLegacyResponse (/Users/matthewsanders/test1/node_modules/selenium-webdriver/lib/error.js:505:15)
    at parseHttpResponse (/Users/matthewsanders/test1/node_modules/selenium-webdriver/lib/http.js:396:13)
    at doSend.then.response (/Users/matthewsanders/test1/node_modules/selenium-webdriver/lib/http.js:328:11)
    at process._tickCallback (internal/process/next_tick.js:103:7)
From: Task: WebDriver.createSession()
    at Function.createSession (/Users/matthewsanders/test1/node_modules/selenium-webdriver/lib/webdriver.js:366:24)
    at Driver (/Users/matthewsanders/test1/node_modules/selenium-webdriver/chrome.js:804:38)
    at Builder.build (/Users/matthewsanders/test1/node_modules/selenium-webdriver/index.js:546:16)
    at Object.<anonymous> (/Users/matthewsanders/test1/index.js:4:59)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.runMain (module.js:590:10)
From: Task: WebDriver.navigate().to(http://www.google.com)
    at Driver.schedule (/Users/matthewsanders/test1/node_modules/selenium-webdriver/lib/webdriver.js:414:17)
    at Navigation.to (/Users/matthewsanders/test1/node_modules/selenium-webdriver/lib/webdriver.js:1042:25)
    at Driver.get (/Users/matthewsanders/test1/node_modules/selenium-webdriver/lib/webdriver.js:832:28)
    at Object.<anonymous> (/Users/matthewsanders/test1/index.js:6:8)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.runMain (module.js:590:10)

I tested against several test applications I had made at the time as well to make sure it wasn't an issue I had introduced in the project.

I then tried to use 'firefox' in the forBrowser method after downloading the geckodriver and this worked perfectly.

It would appear as though some sort of auto update of the chromedriver has broken my project. I had noticed several other questions on stackoverflow related to similar errors, although none of them included the Runtime.evaluate missing 'wasThrown' error, that seem to suggest my theory is probably correct.

I COULD just go ahead and switch to geckodriver, but I'm not sure if I will run into a similar issue down the road.

I guess the real question here is...

How can I disable auto updates to keep this application running as a stand alone project?

Again this is not intended as a constantly up to date test suite, but rather a browser automation application driven by a custom language. It operates as both an automated solution via a hosted node.js instance or as an operator driven gui application running with nwjs.

EDIT:

So far I have found a promising approach. If I get it working to my liking I will add an answer.

The Selenium Documentation has information on how to customize the chromedriver options. I have downloaded a version of Chromium and used this logic to hook it up:

var chrome = require("selenium-webdriver/chrome");
var service = new chrome.ServiceBuilder().build();

var options = new chrome.Options();
options.setChromeBinaryPath("PATH/TO/MY/CHROMIUM");

var driver = new chrome.Driver(options, service);

Note: on mac you must provide a path the the actual executable inside the app package ex: 'Chromium.app/Contents/MacOS/Chromium'.

So far I am using Chromium not Chrome and the version is still not correct, but I did verify it was different than what I am running without setting the path. In theory I should be able to run Chrome the same way if I could reliably freeze the auto update process while still packaging the application stand alone. I may just resort to using Chromium if that doesn't work.

Answer

Levon picture Levon · Oct 6, 2017

Another solution, very close to what @Matthew Sanders suggested is to use Chromium with the following setup

var webdriver = require("selenium-webdriver");
var chrome = require("selenium-webdriver/chrome");

var options = new chrome.Options().setChromeBinaryPath("/usr/bin/chromium-browser")
// options.headless()
var driver = new webdriver.Builder()
    .forBrowser('chrome')
    .setChromeOptions(options)
    .build();