我在测试中使用了带有Capybara和Chrome Headless的RSpec。对于某些页面,我加载了其他JavaScript所依赖的外部JS文件。
我想使测试独立于此外部JS调用,例如当我离线时,它们将无法工作并引发JS错误。更改生产代码(例如测试环境,然后加载或不加载文件或执行脚本)感觉非常丑陋,因此这不是一个选择。
因此,我正在考虑在每次页面访问时向浏览器注入某种模拟脚本。问题是,page.evaluate_script
或page.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中?=
答案 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的私有方法,该方法将来可能会发生变化,也可以用于存储其他种类的外部资源。