我的测试中有带Capybara和Chrome Headless的RSpec。对于某些页面,我加载其他java脚本所依赖的外部JS文件。
我想让我的测试独立于这个外部JS调用,例如,当我离线时,它们不会工作,并引发JS错误。更改生产代码(例如,测试环境,然后加载或不加载文件或执行脚本(感觉非常糟糕,因此这不是一种选择。
因此,我考虑在每次访问页面时都在浏览器中注入某种嘲讽脚本。问题是,像page.evaluate_script
或page.execute_script
这样的方法只在加载页面时运行脚本。此时,生产JS代码已经抛出了一个错误。
我四处寻找解决方案,但我没有找到chrome headless加载文件或在每次加载页面时执行脚本的选项。
我的设置目前看起来像这个
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进行打包。
那么,有没有一种方法可以用capybara将模拟JS文件加载到chrome headless中?=
Capybara和selenium都不直接支持这一点,但Chrome通过其DevTools协议Page.addScriptToEvaluateOnNewDocument
命令支持。如果您正在运行最新的selenium网络驱动程序和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)
我可以建议使用类似webmock的东西来存根对外部js的调用,并以这种方式返回合理的mock,而不是通过web驱动程序注入mock js脚本。这避免了需要使用Chrome的私有方法,这种方法将来可能会更改,也可以用于存根其他类型的外部资源。