曖昧検索
assert_equal 1, page.all('a', text: /Edit/i).count
クリック
find("input[value$='Create Category']").click
# 最初の要素
find("a", text: /◯/i, match: :first).click
チェックボックス
Capybara.execute_script(
"window.scrollTo(
#{(target = find('label', text: text = '公開設定')).native.location.x},
#{target.native.location.y-300}
);"
)
check text
パスチェック
assert_equal category_menu_url(@public_category, @public_menu, locale: 'ja'), current_url
カウンティング
- 正規表現を使うことで
EDIT
,Edit
,edit
など大文字小文字を区別せずにテキストとタグで検索をかける
assert_equal 0, page.all('a', text: /Edit/i).count
assert_selector "h1.test", text: "This is Test Text!", count: 1
待機
// 5秒間停止
sleep(5)
スクロール
絶対位置でスクロール(推奨)
Capybara.execute_script(
"window.scrollTo(
#{(target = find('label', text: text = '公開設定')).native.location.x},
#{target.native.location.y-100}
);"
)
相対位置でスクロール(非推奨)
Capybara.execute_script(
"window.scrollBy(
#{(target = find('label', text: text = '公開設定')).native.location.x},
#{target.native.location.y-100}
);"
)
クラスの付与/削除
Capybara.execute_script("document.getElementById('header').classList.add('d-none')")
スクリーンショット
def take_full_page_screenshot(path)
width = Capybara.page.execute_script("return Math.max(document.body.scrollWidth, document.body.offsetWidth, document.documentElement.clientWidth, document.documentElement.scrollWidth, document.documentElement.offsetWidth);")
height = Capybara.page.execute_script("return Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);")
window = Capybara.current_session.driver.browser.manage.window
window.resize_to(width+100, height+100)
page.save_screenshot path
end
Assertion with Javascript
タイムアウトする場合の対応
Minitest::UnexpectedError:
Capybara::ElementNotFound:
Unable to find checkbox "公開設定" that is not disabled
- capybaraの操作がブラウザの操作より早く動くので意図しないエラーがよく発生する
- そんな時はTimeoutを設定してあげて処理を待ってあげよう
- タイムアウトは10秒設定しないと、Redなテストで時間ロスしてしまう
test/test_helper.rb
class ActiveSupport::TestCase
parallelize(workers: :number_of_processors)
fixtures :all
+ Capybara.default_max_wait_time = 10
end
test 'タイムアウト処理' do
Timeout.timeout(Capybara.default_max_wait_time) do
loop until (target = find('a.footer-link', text: text = '新規カテゴリ作成')).visible?
target.click
end
end
フルサイズスクリーンショット
def take_full_page_screenshot(path)
width = Capybara.page.execute_script("return Math.max(document.body.scrollWidth, document.body.offsetWidth, document.documentElement.clientWidth, document.documentElement.scrollWidth, document.documentElement.offsetWidth);")
height = Capybara.page.execute_script("return Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);")
window = Capybara.current_session.driver.browser.manage.window
window.resize_to(width+100, height+100)
page.save_screenshot path
end
デフォルトのシステムテスト
class SetUp < self
def setup
@one = 1
end
end
class AccessCheck < SetUp
class ValidCase < self
test '' do
assert_equal 1, @one
end
end
class InvalidCase < self
end
end
class Default < SetUp
class ValidCase < self
end
class InvalidCase < self
end
end
処理を共通化してユーザーを変更
class SetUp < self
def setup
@one = 1
@public_category = categories(:public)
@unpublic_category = categories(:unpublic)
@public_menu = menus(:public)
@unpublic_menu = menus(:unpublic)
end
def success_story
visit edit_category_menu_path(@public_category, @public_menu, locale: 'ja')
beforeChange = @public_menu.title
afterChange = @public_menu.title+'changed!'
fill_in 'タイトル', with: afterChange
find("input[value$='Update Menu']").click
@public_menu.reload
assert_equal afterChange, @public_menu.title
end
end
class Default < SetUp
class ValidCase < self
test 'Adminは更新できる' do
sign_in(users(:admin).email, 'password')
success_story
end
test 'Maintainは更新できる' do
sign_in(users(:maintain).email, 'password')
success_story
end
end
end
デフォルトセッティング
テスト用のgemを追加
Gemfile
group :test do
gem "capybara"
gem "selenium-webdriver"
gem "webdrivers"
gem 'minitest-reporters', '~> 1.5'
end
テストの際のブラウザ使用の有無を設定
require "test_helper"
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :chrome, screen_size: [500, 800]
# driven_by :selenium_chrome_headless, using: :chrome, screen_size: [500, 800]
end
デフォルトのテストメソッド作成/読み込み
touch test/default_test_helper.rb
test/default_test_helper.rb
def log_in(email, password)
visit new_user_session_path
fill_in 'メールアドレス', with: email
fill_in 'パスワード', with: password
Capybara.execute_script("arguments[0].click();", find("input[type='submit']"))
end
def log_out
Capybara.execute_script("arguments[0].click();", find('button', text: 'サインアウト'))
end
def access_refused
assert_text "Access Denied."
end
def access_permitted
assert_no_text "Access Denied."
end
必要なファイルを読み込み
test/test_helper.rb
ENV["RAILS_ENV"] ||= "test"
require_relative "../config/environment"
require "rails/test_help"
require "minitest/reporters"
Minitest::Reporters.use!
+ include ApplicationHelper
+ require "default_test_helper"
class ActiveSupport::TestCase
parallelize(workers: :number_of_processors)
fixtures :all
end
テストの作成
システムテストの作成
rails g system_test user_create
-
user_creates_test.rb
が作成される
テストの実行
(test/ 以下の)すべてのテストを実行
rails test
特定フォルダ以下のすべてのテストを実行
rails test test/models
複数のフォルダ以下のすべてのテストを実行
rails test test/models test/jobs
特定のファイルを実行
rails test test/models/user_test.rb
特定のファイルの特定の行を実行
rails test test/models/user_test.rb:14