将 JS 文件注入水豚 chrome headless
Inject JS file into capybara chrome headless
我的测试中有 RSpec 水豚和 Chrome 无头。对于某些页面,我加载了其他 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 headless with capybara?=
Capybara 和 selenium 都不直接支持此功能,但是 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)
我可以建议使用 webmock 之类的东西来存根对外部 js 的调用,而不是通过网络驱动程序注入模拟 js 脚本,return 以这种方式进行合理的模拟。这避免了需要使用Chrome的私有方法,以后可能会改变,也可以用来存根其他种类的外部资源。
我的测试中有 RSpec 水豚和 Chrome 无头。对于某些页面,我加载了其他 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 headless with capybara?=
Capybara 和 selenium 都不直接支持此功能,但是 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)
我可以建议使用 webmock 之类的东西来存根对外部 js 的调用,而不是通过网络驱动程序注入模拟 js 脚本,return 以这种方式进行合理的模拟。这避免了需要使用Chrome的私有方法,以后可能会改变,也可以用来存根其他种类的外部资源。