LoginSignup
5
3

More than 1 year has passed since last update.

【CircleCI2.0】JavaScript に対応するように設定

Last updated at Posted at 2021-01-16

はじめに

CircleCI で JavaScript を扱えるように設定しました。
今まで問題なく動作していた CircleCI のテストでしたが、あることをしてから通らなくなったので対処方法を記していきます。

今までの設定ファイルはこちらです。

目次

  • 環境

  • 問題

  • 原因

    • RSpecでjs: trueを使用
    • 今回 ローカル環境CircleCI環境 をあわせるために行った変更
  • 解決策

    • spec/support/capybara.rb
      • 変更前
      • 変更後
    • spec/rails_helper.rb
    • Dockerfile
    • .circleci/config.yml
    • .circleci/config.yml 全体
    • config/database.yml.ci
  • まとめ

  • おわりに

  • 参考文献

環境

  • Ruby: 2.6.6
  • Bundler: 2.0.2
  • MySQL: 8.0
  • CircleCI: 2.0
  • yarnでjQuery( JavaScript )を使用。( ※ gemとyarnでの使用方法の違いでテストの結果に影響でることが考えられるため。 )

問題

SocketError: 
Failed to open TCP connection to chrome:4444 
(getaddrinfo: No address associated with hostname)
# chrome:4444へのTCP接続のオープンに失敗
SocketError: getaddrinfo: No address associated with hostname
# ホスト名に関連付けられたアドレスはありません

原因

RSpecでjs: trueを使用

RSpecで JavaScriptのテストを実装 したところローカル環境で通っていたテストがCircleCIの自動テストでは通りませんでした。
結論として、ローカル環境とCircleCIの環境の差異が原因かと思います。
ローカルではchromeコンテナを立ち上げて System Spec を通していましたが、 CircleCI の設定ファイル でも設定が必要なのでエラーが起きていました。

今回ローカル環境とCircleCI環境をあわせるために行った変更

  • chromeコンテナ から Dockerfileで chrome を追加するようにしたこと
  • Chrome使用時のURLを指定していたので削除したこと
  • CircleCI の設定ファイルChrome の追加background で使用するようにしたこと

解決策

spec/support/capybara.rb

大幅に変更したように見えますが、url を指定していないというのがポイントです。

変更前
require 'capybara/rspec'
require 'selenium-webdriver'

module CapybaraSupport
  Capybara.javascript_driver = :selenium_chrome_headless
  Capybara.default_driver    = :selenium_chrome_headless
  Capybara.register_driver :selenium_chrome_headless do |app|
    url = 'http://chrome:4444/wd/hub'
    caps = ::Selenium::WebDriver::Remote::Capabilities.chrome(
      'goog:chromeOptions' => {
        'args' => [
          'no-sandbox',
          'headless',
          'disable-gpu',
          'window-size=1680,1050'
        ]
      }
    )
    Capybara::Selenium::Driver.new(app, browser: :chrome, url: url, desired_capabilities: caps)
  end
変更後
require 'capybara/rspec'
require 'selenium-webdriver'

Capybara.register_driver :selenium_chrome_headless do |app|
  options = ::Selenium::WebDriver::Chrome::Options.new

  options.add_argument('--headless')
  options.add_argument('--no-sandbox')
  options.add_argument('--disable-dev-shm-usage')
  options.add_argument('--window-size=1400,1400')

  driver = Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end

Capybara.javascript_driver = :selenium_chrome_headless

spec/rails_helper.rb

RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :rack_test
  end

  config.before(:each, type: :system, js: true) do
    driven_by :selenium_chrome_headless
  end
end

Dockerfile

ローカル環境のテストで Chrome を使用したいので DockerfileChromeの追加 をしています。
この記述を RUN mkdir /myapp の前に書きました。

RUN apt-get update && apt-get install -y unzip && \
    CHROME_DRIVER_VERSION=`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE` && \
    wget -N http://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip -P ~/ && \
    unzip ~/chromedriver_linux64.zip -d ~/ && \
    rm ~/chromedriver_linux64.zip && \
    chown root:root ~/chromedriver && \
    chmod 755 ~/chromedriver && \
    mv ~/chromedriver /usr/bin/chromedriver && \
    sh -c 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -' && \
    sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' && \
    apt-get update && apt-get install -y google-chrome-stable

# ルート直下にmyappという名前で作業ディレクトリを作成(コンテナ内のアプリケーションディレクトリ)
RUN mkdir /myapp
WORKDIR /myapp

.circleci/config.yml

CircleCIの設定ファイル。Chromeを追加 することで ローカル環境との差異 をなくすようにしました。

    steps:
      - run:
          name: Chrome Driver Install
          command: |
            curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
            echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
            sudo apt-get update && sudo apt-get install -y unzip
            wget -N http://chromedriver.storage.googleapis.com/87.0.4280.88/chromedriver_linux64.zip -P ~/
            unzip ~/chromedriver_linux64.zip -d ~/
            rm ~/chromedriver_linux64.zip
            sudo chown root:root ~/chromedriver
            sudo chmod 755 ~/chromedriver
            sudo mv ~/chromedriver /usr/bin/chromedriver
            sh -c 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -'
            sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
            sudo apt-get update && sudo apt-get install -y google-chrome-stable
          background: true

2021/11/25追記

@tomoya128 さんからのコメントよりこの部分は以下のように記述できるとお聞きしました。

    steps:
      - run:
          command: chromedriver
          background: true

また、Ruby 2.5 以上を使用している場合は、webdrivers(gem) を利用すると簡単に設定できるようです。
試してみてはどうでしょうか。

.circleci/config.yml 全体

RSpecを動かすところで no_output_timeout: 15m と記述しています。
こちらはなくともテストには直接関係ないので削除しても大丈夫です。

なにも設定しなければ標準で10分の制限時間があり、それを過ぎるとタイムアウトエラーになってしまうので念の為付けております。テストの数とかにもよると思いますが、実際にはほんの数分で終わるので不要です。

version: 2

jobs:
  build:
    docker:
      - image: circleci/ruby:2.6.6-node-browsers
        environment:
          - BUNDLER_VERSION: 2.0.2
          - RAILS_ENV: 'test'
      - image: circleci/mysql:8.0
        command: [--default-authentication-plugin=mysql_native_password]
        environment:
          - MYSQL_USER: root
          - MYSQL_DB: ci_test
          - MYSQL_ROOT_HOST: "127.0.0.1"

    working_directory: ~/myapp

    steps:
      - run:
          name: Chrome Driver Install
          command: |
            curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
            echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
            sudo apt-get update && sudo apt-get install -y unzip
            wget -N http://chromedriver.storage.googleapis.com/87.0.4280.88/chromedriver_linux64.zip -P ~/
            unzip ~/chromedriver_linux64.zip -d ~/
            rm ~/chromedriver_linux64.zip
            sudo chown root:root ~/chromedriver
            sudo chmod 755 ~/chromedriver
            sudo mv ~/chromedriver /usr/bin/chromedriver
            sh -c 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -'
            sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
            sudo apt-get update && sudo apt-get install -y google-chrome-stable
          background: true

      - checkout

      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            - v1-dependencies-

      - run:
          name: install dependencies
          command: |
            gem install bundler -v 2.0.2
            bundle install --jobs=4 --retry=3 --path vendor/bundle

      - save_cache:
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}
          paths:
            - ./vendor/bundle

      - run: mv config/database.yml.ci config/database.yml
      - run: yarn install
      - run: bundle exec rake db:create
      - run: bundle exec rake db:schema:load

      - run:
          name: run tests
          command: |
            mkdir /tmp/test-results
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
              circleci tests split --split-by=timings)"
            bundle exec rspec \
              --format RspecJunitFormatter \
              --out /tmp/test-results/rspec.xml \
              --format progress \
              $TEST_FILES
          no_output_timeout: 15m

      - store_test_results:
          path: /tmp/test-results
      - store_artifacts:
          path: /tmp/test-results
          destination: test-results

config/database.yml.ci

test:
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: 'root'
  port: 3306
  host: '127.0.0.1'
  database: ci_test

まとめ

  • DockerfileCircleCIの設定ファイルChromeを追加
  • ローカルで通用してもCircleCI上で失敗することがある。
  • ありがたいことに記事(情報)がたくさんあるので、その中で自分がどの問題に直面しているのかを理解することが大事。

おわりに

前回の記事に変更前の CircleCIの設定ファイル があります。(厳密に言えば少しリファクタなどしています)
JavaScript適用前 ですが、 CircleCI についてまとめていますのでよろしければご覧ください。

参考文献

5
3
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3