GitHub Actions执行失败:忽略本地主机设置未生效问题排查
问题:GitHub Actions中运行RSpec测试时VCR的ignore_localhost设置未生效
错误信息
Run bundle exec rspec --tag type:feature Run options: include {:type="feature"} Capybara starting Puma... * Version 4.3.12 , codename: Mysterious Traveller * Min threads: 0, max threads: 4 * Listening on tcp://127.0.0.1:38995 ......................F Failures: 1) Log In can log into the application Got 0 failures and 2 other errors: 1.1) Failure/Error: visit new_user_session_path VCR::Errors::UnhandledHTTPRequestError: ================================================================================ An HTTP request has been made that VCR does not know how to handle: GET https://chromedriver.storage.googleapis.com/LATEST_RELEASE_106.0.5249 There is currently no cassette in use. There are a few ways you can configure VCR to handle this request: * If you're surprised VCR is raising this error and want insight about how VCR attempted to handle the request, you can use the debug_logger configuration option to log more details [1]. * If you want VCR to record this request and play it back during future test runs, you should wrap your test (or this portion of your test) in a `VCR.use_cassette` block [2]. * If you only want VCR to handle requests made while a cassette is in use, configure `allow_http_connections_when_no_cassette = true`. VCR will ignore this request since it is made when there is no cassette [3]. * If you want VCR to ignore this request (and others like it), you can set an `ignore_request` callback [4]. [1] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/configuration/debug-logging [2] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/getting-started [3] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/configuration/allow-http-connections-when-no-cassette [4] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/configuration/ignore-request ================================================================================ # ./spec/features/login_spec.rb:9:in `block (2 levels) in <top (required)>' # ./spec/rails_helper.rb:69:in `block (2 levels) in <top (required)>' # ./spec/support/configs/config_vcr.rb:38:in `block (2 levels) in <top (required)>' 1.2) Failure/Error: example.run VCR::Errors::UnhandledHTTPRequestError: ================================================================================ An HTTP request has been made that VCR does not know how to handle: GET https://chromedriver.storage.googleapis.com/LATEST_RELEASE_106.0.5249 There is currently no cassette in use. There are a few ways you can configure VCR to handle this request: * If you're surprised VCR is raising this error and want insight about how VCR attempted to handle the request, you can use the debug_logger configuration option to log more details [1]. * If you want VCR to record this request and play it back during future test runs, you should wrap your test (or this portion of your test) in a `VCR.use_cassette` block [2]. * If you only want VCR to handle requests made while a cassette is in use, configure `allow_http_connections_when_no_cassette = true`. VCR will ignore this request since it is made when there is no cassette [3]. * If you want VCR to ignore this request (and others like it), you can set an `ignore_request` callback [4]. [1] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/configuration/debug-logging [2] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/getting-started [3] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/configuration/allow-http-connections-when-no-cassette [4] https://www.relishapp.com/vcr/vcr/v/6-1-0/docs/configuration/ignore-request ================================================================================ # ./spec/rails_helper.rb:69:in `block (2 levels) in <top (required)>' # ./spec/support/configs/config_vcr.rb:38:in `block (2 levels) in <top (required)>' Finished in 1.36 seconds (files took 1.62 seconds to load) 23 examples, 1 failure Failed examples: rspec ./spec/features/login_spec.rb:17 # Log In can log into the application Stopped processing SimpleCov as a previous error not related to SimpleCov has been detected Coverage report generated for RSpec to /home/runner/work/ami-experience/ami-experience/tmp/coverage. 213 / 327 LOC (65.14%) covered. Error: Process completed with exit code 1.
测试用例代码
# frozen_string_literal: true require('rails_helper') RSpec.describe 'Log In', type: :feature do let(:user) { create(:admin_user) } before do visit new_user_session_path expect(page).to have_button('Access') fill_in 'user_email', with: user.email, wait: 10 fill_in 'user_password', with: user.password, wait: 10 click_button 'Access' end context 'can log into the application' do it { expect(page).to have_content('Success!') } end end
当前VCR配置
# frozen_string_literal: true VCR.configure do |c| c.ignore_localhost = true c.cassette_library_dir = 'spec/fixtures/vcr' c.hook_into(:webmock) c.default_cassette_options = { record: :new_episodes } c.allow_http_connections_when_no_cassette = false end
解决方案
核心原因
报错的请求是chromedriver自动检查最新版本的请求,目标域名是chromedriver.storage.googleapis.com,不属于localhost范围,所以ignore_localhost规则对它无效,需要单独配置忽略。
方案1:添加精准忽略规则(推荐)
修改VCR配置,增加一个ignore_request回调,匹配chromedriver的版本检查请求:
# frozen_string_literal: true VCR.configure do |c| c.ignore_localhost = true c.cassette_library_dir = 'spec/fixtures/vcr' c.hook_into(:webmock) c.default_cassette_options = { record: :new_episodes } c.allow_http_connections_when_no_cassette = false # 忽略chromedriver的版本检查请求 c.ignore_request do |request| request.uri.host == 'chromedriver.storage.googleapis.com' end end
方案2:允许无cassette时的HTTP连接(谨慎使用)
如果不想逐个添加忽略规则,可以临时开启allow_http_connections_when_no_cassette = true,但这样会让所有未被VCR捕获的请求直接发送,可能降低测试的隔离性:
# frozen_string_literal: true VCR.configure do |c| c.ignore_localhost = true c.cassette_library_dir = 'spec/fixtures/vcr' c.hook_into(:webmock) c.default_cassette_options = { record: :new_episodes } # 允许无cassette时发起HTTP请求 c.allow_http_connections_when_no_cassette = true end
额外优化(可选)
在GitHub Actions中预先安装指定版本的chromedriver,避免自动检查版本的请求。比如在workflow文件中添加:
- name: Install chromedriver run: | CHROMEDRIVER_VERSION=106.0.5249.61 wget -N https://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip -P ~/ unzip ~/chromedriver_linux64.zip -d ~/ rm ~/chromedriver_linux64.zip sudo mv -f ~/chromedriver /usr/local/bin/chromedriver sudo chmod +x /usr/local/bin/chromedriver
这样可以彻底避免触发版本检查请求,从根源解决问题。
内容的提问来源于stack exchange,提问作者Chris Hough
相关产品推荐
相关产品推荐

