"Refused to connect" 使用 ChromeDriver、Capybara 和 Docker Compose
"Refused to connect" using ChromeDriver, Capybara & Docker Compose
我正在尝试从 PhantomJS 迁移到 Headless Chrome,但 运行 遇到了一些麻烦。对于本地测试,我正在使用 Docker Compose 启动所有相关服务并 运行ning。为了提供 Google Chrome,我使用了一个将它和 Chrome 驱动程序捆绑在一起的映像,同时在端口 4444
上提供它。然后我 link 它到我的应用程序容器,如下所示在这个简化的 docker-compose.yml
文件中:
web:
image: web/chrome-headless
command: [js-specs]
stdin_open: true
tty: true
environment:
- RACK_ENV=test
- RAILS_ENV=test
links:
- "chromedriver:chromedriver"
chromedriver:
image: robcherry/docker-chromedriver:latest
ports:
- "4444"
cap_add:
- SYS_ADMIN
environment:
CHROMEDRIVER_WHITELISTED_IPS: ""
然后,我有一个 spec/spec_helper.rb
文件来引导测试环境和相关工具。我定义了 :headless_chrome
驱动程序并将其指向 Chrome 驱动程序的本地绑定; http://chromedriver:4444
。我很确定以下是正确的:
Capybara.javascript_driver = :headless_chrome
Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome)
end
Capybara.register_driver :headless_chrome do |app|
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
chromeOptions: { args: %w[headless disable-gpu window-size=1440,900] },
)
Capybara::Selenium::Driver.new app,
browser: :chrome,
url: "http://chromedriver:4444/",
desired_capabilities: capabilities
end
我们也使用 VCR,但我已将其配置为忽略与 ChromeDriver:
使用的端口的任何连接
VCR.configure do |c|
c.cassette_library_dir = 'spec/vcr_cassettes'
c.default_cassette_options = { record: :new_episodes }
c.ignore_localhost = true
c.allow_http_connections_when_no_cassette = false
c.configure_rspec_metadata!
c.ignore_hosts 'codeclimate.com'
c.hook_into :webmock, :excon
c.ignore_request do |request|
URI(request.uri).port == 4444
end
end
我使用 Docker Compose 启动服务,这会触发测试 运行ner。命令几乎是这样的:
$ bundle exec rspec --format progress --profile --tag 'broken' --tag 'js' --tag '~quarantined'
等了一会儿,我遇到了第一个失败的测试:
1) Beta parents code redemption: redeeming a code on the dashboard when the parent has reached the code redemption limit does not display an error message for cart codes
Failure/Error: fill_in "code", with: "BOOK-CODE"
Capybara::ElementNotFound:
Unable to find field "code"
# ./spec/features/beta_parents_code_redemption_spec.rb:104:in `block (4 levels) in <top (required)>'
所有规格都有相同的错误。因此,我 shell 进入容器以 运行 手动测试并捕获它正在测试的 HTML 。我将其保存在本地并在我的浏览器中打开它,以显示以下 Chrome 错误页面。似乎 ChromeDriver 没有评估规范的 HTML 因为它无法访问它,所以它尝试 运行 针对此错误页面的测试。
根据以上信息,我做错了什么?我感谢所有的帮助,因为远离 PhantomJS 会解决 so 许多让我们头疼的问题。
非常感谢您。如果您需要更多信息,请告诉我。
您遇到的问题是,默认情况下,Capybara 启动绑定到 127.0.0.1
的 AUT,然后告诉驱动程序从相同的浏览器请求。但是,在您的情况下,127.0.0.1 不是应用 运行 所在的位置(从浏览器的角度来看),因为它与浏览器位于不同的容器中。要解决此问题,您需要将 Capybara.server_host
设置为 "web" 容器的任何外部接口(可从 "chromedriver" 容器访问)。这将导致 Capybara 将 AUT 绑定到该接口并告诉驱动程序让浏览器向它发出请求。
在您的情况下,这可能意味着您可以指定 'web'
Capybara.server_host = 'web'
我正在尝试从 PhantomJS 迁移到 Headless Chrome,但 运行 遇到了一些麻烦。对于本地测试,我正在使用 Docker Compose 启动所有相关服务并 运行ning。为了提供 Google Chrome,我使用了一个将它和 Chrome 驱动程序捆绑在一起的映像,同时在端口 4444
上提供它。然后我 link 它到我的应用程序容器,如下所示在这个简化的 docker-compose.yml
文件中:
web:
image: web/chrome-headless
command: [js-specs]
stdin_open: true
tty: true
environment:
- RACK_ENV=test
- RAILS_ENV=test
links:
- "chromedriver:chromedriver"
chromedriver:
image: robcherry/docker-chromedriver:latest
ports:
- "4444"
cap_add:
- SYS_ADMIN
environment:
CHROMEDRIVER_WHITELISTED_IPS: ""
然后,我有一个 spec/spec_helper.rb
文件来引导测试环境和相关工具。我定义了 :headless_chrome
驱动程序并将其指向 Chrome 驱动程序的本地绑定; http://chromedriver:4444
。我很确定以下是正确的:
Capybara.javascript_driver = :headless_chrome
Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome)
end
Capybara.register_driver :headless_chrome do |app|
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
chromeOptions: { args: %w[headless disable-gpu window-size=1440,900] },
)
Capybara::Selenium::Driver.new app,
browser: :chrome,
url: "http://chromedriver:4444/",
desired_capabilities: capabilities
end
我们也使用 VCR,但我已将其配置为忽略与 ChromeDriver:
使用的端口的任何连接VCR.configure do |c|
c.cassette_library_dir = 'spec/vcr_cassettes'
c.default_cassette_options = { record: :new_episodes }
c.ignore_localhost = true
c.allow_http_connections_when_no_cassette = false
c.configure_rspec_metadata!
c.ignore_hosts 'codeclimate.com'
c.hook_into :webmock, :excon
c.ignore_request do |request|
URI(request.uri).port == 4444
end
end
我使用 Docker Compose 启动服务,这会触发测试 运行ner。命令几乎是这样的:
$ bundle exec rspec --format progress --profile --tag 'broken' --tag 'js' --tag '~quarantined'
等了一会儿,我遇到了第一个失败的测试:
1) Beta parents code redemption: redeeming a code on the dashboard when the parent has reached the code redemption limit does not display an error message for cart codes
Failure/Error: fill_in "code", with: "BOOK-CODE"
Capybara::ElementNotFound:
Unable to find field "code"
# ./spec/features/beta_parents_code_redemption_spec.rb:104:in `block (4 levels) in <top (required)>'
所有规格都有相同的错误。因此,我 shell 进入容器以 运行 手动测试并捕获它正在测试的 HTML 。我将其保存在本地并在我的浏览器中打开它,以显示以下 Chrome 错误页面。似乎 ChromeDriver 没有评估规范的 HTML 因为它无法访问它,所以它尝试 运行 针对此错误页面的测试。
根据以上信息,我做错了什么?我感谢所有的帮助,因为远离 PhantomJS 会解决 so 许多让我们头疼的问题。
非常感谢您。如果您需要更多信息,请告诉我。
您遇到的问题是,默认情况下,Capybara 启动绑定到 127.0.0.1
的 AUT,然后告诉驱动程序从相同的浏览器请求。但是,在您的情况下,127.0.0.1 不是应用 运行 所在的位置(从浏览器的角度来看),因为它与浏览器位于不同的容器中。要解决此问题,您需要将 Capybara.server_host
设置为 "web" 容器的任何外部接口(可从 "chromedriver" 容器访问)。这将导致 Capybara 将 AUT 绑定到该接口并告诉驱动程序让浏览器向它发出请求。
在您的情况下,这可能意味着您可以指定 'web'
Capybara.server_host = 'web'