1

我一直在 nwjs/node.js 中开发一个浏览器自动化应用程序,它使用数据驱动的DSL指令。

我决定通过我的 package.json 中的以下依赖项为 chromedriver 和 selenium webdriver 使用 npm 包:

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

一切都很顺利,直到最近应用程序在启动 chromedriver 时停止工作:

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

以下是在我的 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)

我还针对我当时制作的几个测试应用程序进行了测试,以确保这不是我在项目中引入的问题。

forBrowser然后,我在下载geckodriver后尝试在该方法中使用“firefox”,效果很好。

看起来好像 chromedriver 的某种自动更新破坏了我的项目。我注意到有关 stackoverflow 的其他几个与类似错误相关的问题,尽管没有一个包含该Runtime.evaluate missing 'wasThrown'错误,这似乎表明我的理论可能是正确的。

我可以继续切换到geckodriver,但我不确定我是否会遇到类似的问题。

我想这里真正的问题是......

如何禁用自动更新以保持此应用程序作为独立项目运行?

同样,这不是作为一个不断更新的测试套件,而是一个由自定义语言驱动的浏览器自动化应用程序。它既可以通过托管的 node.js 实例作为自动化解决方案运行,也可以作为使用 nwjs 运行的操作员驱动的 gui 应用程序运行。

编辑:

到目前为止,我已经找到了一个很有前途的方法。如果我让它按我的喜好工作,我会添加一个答案。

Selenium 文档包含有关如何自定义 chromedriver 选项的信息。我已经下载了一个Chromium版本并使用这个逻辑来连接它:

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);

注意:在 Mac 上,您必须提供应用程序包中实际可执行文件的路径,例如:“Chromium.app/Contents/MacOS/Chromium”。

到目前为止,我使用的是 Chromium 而不是 Chrome,版本仍然不正确,但我确实验证了它与我在没有设置路径的情况下运行的不同。从理论上讲,如果我能够可靠地冻结自动更新过程,同时仍然独立打包应用程序,我应该能够以相同的方式运行 Chrome。如果这不起作用,我可能会求助于使用 Chromium。

4

4 回答 4

2

另一个非常接近@Matthew Sanders 建议的解决方案是将Chromium与以下设置一起使用

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();
于 2017-10-06T10:57:10.137 回答
0

您可以将 docker 与 selenium hub 一起使用来设置一个独立于您安装的浏览器的隔离环境。集线器有不同的浏览器,但正如您之前使用的 chrome,我会推荐以下内容:

https://hub.docker.com/r/selenium/standalone-chrome/

安装 docker 后,可以使用以下命令启动服务器

docker run -d -p 4444:4444 selenium/standalone-chrome:latest

然后,您可以通过端口 4444 连接到它。

当一切启动并运行时,只需在代码中告诉它,确保您的 webdriver 使用远程 selenium 集线器:

var webdriver = require("selenium-webdriver");
var driver = new webdriver.Builder()
    .forBrowser('chrome')
    .usingServer('http://localhost:4444/wd/hub')
    .build();

编辑:

正如@sircapsalot 指出的那样,您可以通过自己构建图像来指定您的版本https://github.com/SeleniumHQ/docker-selenium/wiki/Building-your-own-images#specify-chromedriver-and-chrome-versions

于 2016-10-27T19:04:15.543 回答
0

我能够通过使用Chromium来解决我的问题,但是,我进行了测试以确保它也可以与 Chrome 一起使用。Chrome 的问题在于您无法轻松找到较旧的版本,并且它们可以(并且确实)更改您禁用更新版本的自动更新的方式。有一些建议可以在 Chrome 中禁用自动更新,其中一些建议比其他建议更有效。

我决定按照网站上的指南下载以前版本的 Chromium(在这种情况下,它使用版本 44 作为示例):

  1. 最后一次在http://googlechromereleases.blogspot.com/search/label/Stable%20updates 中查找“44”。被提及。
  2. 在位置查找中循环该版本历史记录(“44.0.2403.157”)
  3. 在这种情况下,它返回一个基本位置“330231”。这是 44 版本分支的提交,早在 2015 年 5 月。*
  4. 打开持续构建存档
  5. 点击您的平台(Linux/Mac/Win)
  6. 将“330231”粘贴到顶部的过滤器字段中,然后等待所有结果到 XHR 中。

注意:有时数字不匹配,您必须滚动列表到您看到的下一个最低匹配项。我不得不回去几场比赛才能找到适合我情况的工作副本。

一旦你有了一个二进制文件,这里就是使用它的 javascript 逻辑(更多信息可以在Selenium Docs中找到):

// get the webdriver for future operations
var webdriver = require("selenium-webdriver");
// configure the chromedriver
var chrome = require("selenium-webdriver/chrome");
// here I get the path of chromedriver to avoid using path variables
var path = new require("chromedriver").path;
var service = new chrome.ServiceBuilder(path).build();

var options = new chrome.Options();
// Note: on mac you need to reach in the .app folder
options.setChromeBinaryPath("Chromium.app/Contents/MacOS/Chromium");

var driver = new chrome.Driver(options, service);
于 2016-10-28T19:51:17.410 回答
0

如何在不强制更新的情况下使用 Selenium chromedriver?

简单的答案:

禁用自动浏览器更新。

通过让自动更新发生,您可能会遇到带有 Chromedriver 的不同版本的 Chrome。Firefox 和 Geckodriver 也会发生同样的情况。

最好有一个更可控的升级过程。当您准备好更新时,手动更新到最新的 chrome 和 chromedriver 版本。

于 2016-10-27T18:18:35.723 回答