将JS文件注入到无头的水豚Chrome

时间:2018-07-25 10:02:47

标签: ruby selenium capybara selenium-chromedriver google-chrome-headless

我在测试中使用了带有Capybara和Chrome Headless的RSpec。对于某些页面,我加载了其他JavaScript所依赖的外部JS文件。

我想使测试独立于此外部JS调用,例如当我离线时,它们将无法工作并引发JS错误。更改生产代码(例如测试环境,然后加载或不加载文件或执行脚本)感觉非常丑陋,因此这不是一个选择。

因此,我正在考虑在每次页面访问时向浏览器注入某种模拟脚本。问题是,page.evaluate_scriptpage.execute_script之类的方法仅在页面加载时运行脚本。至此,生产JS代码已经抛出错误。

我一直在寻找解决方案,但是我没有找到chrome无头选项来加载文件或在每次页面加载时执行脚本。

我的设置当前看起来像这样

Capybara.register_driver :chrome_headless do |app|
  options = Selenium::WebDriver::Chrome::Options.new
  options.add_argument("no-sandbox")
  options.add_argument("headless")
  options.add_argument("disable-gpu")
  options.add_argument("window-size=1400,1400")

  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    acceptInsecureCerts: true
  )

  Capybara::Selenium::Driver.new(
    app, browser: :chrome, options: options, desired_capabilities: capabilities
  )
end
Capybara.javascript_driver = :chrome_headless

我还尝试构建扩展并将其与

一起使用
options.add_extension("spec/support/chrome_extension_test_helper/chrome_extension_test_helper.crx")

,但似乎未加载该扩展名(我在扩展名中添加了console.error("foobar"),但未显示任何内容。因此也许不允许使用自签名扩展名吗?此外,我想在每次更改某些东西时,都无需在Chrome中打包它。

那么,有没有办法使用水豚将模拟JS文件加载到无头的chrome中?=

2 个答案:

答案 0 :(得分:4)

水豚和硒均不直接支持此功能,但是Chrome通过其DevTools协议Page.addScriptToEvaluateOnNewDocument命令支持。如果您运行的是最新的selenium-webdriver和chromedriver,则可以利用此功能,但不能保证它永远运行,因为它涉及在selenium驱动程序上调用私有方法bridge

params = {
  cmd: 'Page.addScriptToEvaluateOnNewDocument',
  params: {
    source: '<The JS you want run before scripts on every page load>'
  }
}
page.driver.browser.send(:bridge).send_command(params)

答案 1 :(得分:0)

我建议不要使用Webmock之类的方法来通过Web驱动程序注入模拟js脚本,以对外部js的调用进行存根,并以这种方式返回明智的模拟。这样可以避免使用Chrome的私有方法,该方法将来可能会发生变化,也可以用于存储其他种类的外部资源。