使用 Docker 打开带有 Rails 功能规范的 Chrome

amr*_*ree 5 selenium ruby-on-rails selenium-chromedriver docker

我不知道在 Docker 中运行 Rails 的非无头功能规范时如何使功能规范发挥作用。我可以打开 Chrome,但我得到了ERR_EMPTY_RESPONSE (基本上,它是空白的)

完整源代码可在以下位置获取:https://github.com/amree/blog-example

命令:

# chromedriver on the host
chromedriver --whitelisted-ips

# build the image
docker build -t blog_base --progress=plain --secret id=bundle_credentials,src=.env.development .

# run the test
docker compose run --rm web bundle exec rspec spec/features/user_creates_post_spec.rb
Run Code Online (Sandbox Code Playgroud)
# chromedriver on the host
chromedriver --whitelisted-ips

# build the image
docker build -t blog_base --progress=plain --secret id=bundle_credentials,src=.env.development .

# run the test
docker compose run --rm web bundle exec rspec spec/features/user_creates_post_spec.rb
Run Code Online (Sandbox Code Playgroud)
# Dockerfile
FROM ruby:2.6.3

RUN apt-get update \
  && apt-get install -y --no-install-recommends \
    curl \
    build-essential \
    libpq-dev \
  && curl -sL https://deb.nodesource.com/setup_16.x | bash - \
  && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
  && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
  && apt-get install -y nodejs \
  && rm -rf /var/lib/apt/lists/*

WORKDIR /app

RUN gem install rails:6.1.4.4 bundler:2.3.4
COPY Gemfile* /app
COPY bundle_install.sh .
RUN --mount=type=secret,id=bundle_credentials ./bundle_install.sh

RUN npm install -g yarn
COPY package.json /app
COPY yarn.lock /app
RUN yarn install

ADD . /app

EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
Run Code Online (Sandbox Code Playgroud)
# spec/support/capybara.rb
require "capybara/rspec"
require "selenium-webdriver"

Capybara.server = :puma, { Silent: false }

# Setup rspec
RSpec.configure do |config|
  config.before(:each, type: :system, js: true) do
    Capybara.server_host =  "0.0.0.0"
    Capybara.server_port = "31337"
    Capybara.app_host    = "http://127.0.0.1:31337"


    driven_by :selenium, using: :chrome, options: {
      browser: :remote,
      # Couldn't use http://host.docker.internal:9515 for some reason, so, I just
      # use my current wifi IP here
      url: "http://192.168.1.244:9515",
      desired_capabilities: :chrome
    }
  end
end
Run Code Online (Sandbox Code Playgroud)

错误:

2022-01-11 16:04:14 WARN Selenium [DEPRECATION] [:desired_capabilities] :desired_capabilities as a parameter for driver initialization is deprecated. Use :capabilities with an Array value of capabilities/options if necessary instead.
2022-01-11 16:04:14 WARN Selenium [DEPRECATION] [:browser_options] :options as a parameter for driver initialization is deprecated. Use :capabilities with an Array of value capabilities/options if necessary instead.
Capybara starting Puma...
* Version 5.5.2 , codename: Zawgyi
* Min threads: 0, max threads: 4
* Listening on http://0.0.0.0:31337
F

Failures:

  1) User creates post successfully
     Failure/Error: visit posts_path

     Selenium::WebDriver::Error::UnknownError:
       unknown error: net::ERR_CONNECTION_REFUSED
         (Session info: chrome=97.0.4692.71)

     [Screenshot Image]: /app/tmp/screenshots/failures_r_spec_example_groups_user_creates_post_successfully_168.png


     # 0   chromedriver                        0x000000010bcefe69 chromedriver + 5160553
     # 1   chromedriver                        0x000000010bc7a593 chromedriver + 4679059
     # 2   chromedriver                        0x000000010b82e2c8 chromedriver + 172744
     # 3   chromedriver                        0x000000010b8281b7 chromedriver + 147895
Run Code Online (Sandbox Code Playgroud)

错误

Noa*_*ead 0

启动 Chrome 时,不要将其指向本地地址,127.0.0.1因为 Docker 使用自己的 IP 启动容器(除非明确指定)。

您有两个选择:

  1. 在容器中运行应用程序并使用主机名

将启动 URL 设置为 Docker 容器的主机名。

该值将为http://chrome:31337,其中chrome是 Docker Compose 文件中使用的容器名称。

  1. 允许 docker 容器访问主机端口。(如果您在 docker 外部运行应用程序)

为此,将以下行添加到selenium容器中

extra_hosts:
- "host.docker.internal:host-gateway"
Run Code Online (Sandbox Code Playgroud)

然后将值设置为http://host.docker.internal:31337