はじめに
Rspecでdrag&dropのテストのやり方についてまとめておきます。
結論
1.Google Chromeをサーバーにインストール
2.selenium_chrome_headlessを使用する設定を行う
3.drag_toメソッドを使用する
これにより、テストを行うことができました。
環境構築から、テスト実行まで
今回実行できるか確認した手順です。
DockerでRuby on Railsの環境構築を行うためのステップ【Rails 6対応】@kodai_0122
(https://qiita.com/kodai_0122/items/795438d738386c2c1966) を参考にさせていただき、テスト環境の構築を行います。
詳しくは、上記のリンクの記事にまとまってますので、ご確認ください。
$ mkdir spec_test_app
$ cd spec_test_app
Dockerfile
FROM ruby:2.6.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
########################################################################
# yarnパッケージ管理ツールをインストール
RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
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 update && apt-get install -y yarn
# Node.jsをインストール
RUN curl -sL https://deb.nodesource.com/setup_7.x | bash - && \
apt-get install nodejs
#######################################################################
# 1.Google Chromeをサーバーにインストール
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add && \
echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | tee /etc/apt/sources.list.d/google-chrome.list && \
apt-get update && \
apt-get install -y google-chrome-stable
RUN mkdir /spec_test_app
WORKDIR /spec_test_app
COPY Gemfile /spec_test_app/Gemfile
COPY Gemfile.lock /spec_test_app/Gemfile.lock
RUN bundle install
COPY . /spec_test_app
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 6'
Gemfile.lock
# 空
entrypoint.sh
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /spec_test_app/tmp/pids/server.pid
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
docker-compose.yml
version: '3'
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/spec_test_app
ports:
- "3000:3000"
depends_on:
- db
アプリケーション作成
$ docker-compose run web rails new . --force --no-deps --database=postgresql --skip-bundle
Gemfile
# 追加
gem 'rspec-rails'
$ docker-compose run web bundle install
$ docker-compose build
config/database.yml
default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
password:
pool: 5
development:
<<: *default
database: spec_test_app_development
test:
<<: *default
database: spec_test_app
コンテナ立ち上げ
$ docker-compose up
$ docker-compose run web bundle exec rails webpacker:install
DB作成
$ docker-compose run web rake db:create
コントローラー作成
$ docker-compose run web bundle exec rails g controller users index
specファイル作成
$ docker-compose run web bundle exec rails generate rspec:install
$ docker-compose run web bundle exec rails generate rspec:feature users
viewファイル編集
/users/index.html.erb
<ul>
<li draggable="true" ondragstart="dragStarted(event)" ondragover="draggingOver(event)" ondrop="dropped(event)">鈴木さん</li>
<li draggable="true" ondragstart="dragStarted(event)" ondragover="draggingOver(event)" ondrop="dropped(event)">高橋さん</li>
<li draggable="true" ondragstart="dragStarted(event)" ondragover="draggingOver(event)" ondrop="dropped(event)">田中さん</li>
<li draggable="true" ondragstart="dragStarted(event)" ondragover="draggingOver(event)" ondrop="dropped(event)">小林さん</li>
<li draggable="true" ondragstart="dragStarted(event)" ondragover="draggingOver(event)" ondrop="dropped(event)">伊藤さん</li>
</ul>
<script>
function dragStarted(evt) {
source = evt.target;
evt.dataTransfer.setData("text/plain", evt.target.innerHTML);
evt.dataTransfer.effectAllowed = "move";
}
function draggingOver(evt) {
evt.preventDefault();
evt.dataTransfer.dropEffect = "move";
}
function dropped(evt) {
evt.preventDefault();
evt.stopPropagation();
source.innerHTML = evt.target.innerHTML;
evt.target.innerHTML = evt.dataTransfer.getData("text/plain");
}
</script>
テスト関連ファイル編集
spec/rails_helper.rb
# 2.selenium_chrome_headlessを使用する設定を行う
Capybara.javascript_driver = :selenium_chrome_headless
Capybara.register_driver :selenium_chrome_headless do |app|
options = ::Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
options.add_argument('--no-sandbox')
Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end
spec/features/users_spec.rb
# 追加
scenario 'ドラッグ&ドロップのテスト', js: true do
visit users_index_path
first_user = all('li')[0]
second_user = all('li')[1]
# 3.drag_toメソッドを使用する
all('li')[0].drag_to all('li')[1]
expect(all('li')[1].text).to eq '鈴木さん'
end
テスト実行
$ docker-compose run web bundle exec bundle exec rspec spec/features/users_spec.rb
1 example, 0 failures
まとめ
drag&dropのテストを行うことができました!
より良い方法等などありましたらご教授ください。