RailsではSeleniumをRspecなどのテストで使用することが多いと思いますが、今回はアプリケーションの機能の中で使用する方法をご紹介します。
概要
アプリケーションからWebサイトのフォーム要素を取得し、入力する機能を例にご紹介します。
Seleniumの公式はこちらです。
https://www.selenium.dev/ja/
Gemの公式はこちらです。
https://github.com/SeleniumHQ/selenium/
環境
- Ruby 3.3.4
- Rails 8.0.0
- selenium-webdriver 4.27.0
概要
URLと対象のフォームの要素、その値はJSONなどでデータがある状態を想定して解説します。
- URLを指定してWebサイトにアクセス
- 目的のフォーム要素を検索&取得
- 値を入力
- 送信
以下が諸々のデータを格納するテーブルです。
- contact_form: URL、フォーム要素のJSON
- contact_form_values: 対象要素と入力値のペアのJSON
なお、今回はmodel
に一連の流れを行うクラスを作成し、rake
で実行します。
seleniumのセットアップ
あまり特別なことはないのですが、デフォルトでseleniumはテスト環境のみにインストールされているので、全体に適用されるよう記述箇所を移動します。
# Gemfile
gem "selenium-webdriver", require: false # group :testから全体に移動
$bundle install
したあとは、使用したいファイルで呼び出してください。
require "selenium-webdriver"
Webサイトアクセス
require "selenium-webdriver"
def access_url
driver ||= Selenium::WebDriver.for :chrome, options: options
driver.navigate.to contact_form.url
end
def options
Selenium::WebDriver::Chrome::Options.new.tap do |options|
options.add_argument('--headless')
user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'
options.add_argument("--user-agent=#{user_agent}")
end
end
実際にアクセスしているのは driver.navigate.to contact_form.url
この部分です。
options
の中身は、どのようにアクセスするかをしているするオプションの設定で、 Selenium::WebDriver.for :chrome, options: options
この部分でそれを適用させながら初期化しています。
今回のオプションは、ヘッドレスモードとユーザーエージェントの指定で、ヘッドレスモードは実際にブラウザを開くことなくアクセスし、ユーザーエージェントはアクセスしている環境を模倣するものです。
初期化されたWebDriverオブジェクトを使ってブラウザを操作します。
フォーム要素の取得
form_ele = driver.find_element(:tag_name, 'form')
form_ele.find_element(name: 対象name属性の値) # 通常のinputなど
form_ele.find_element(:css, "label[for='#{labelのfor属性の値}']") # checkboxでlabelをクリックしたい時など
form_element.find_element(:xpath, '//input[@type="submit"]')
ブラウザを操作できるオブジェクトは前節でdriver
に格納されています。
まず form
要素を取り出し、そこ中から対象の input
要素を取得しています。
基本的に要素の取得に使うのは find_element
です。
タグの種類、id、class、cssセレクターなど様々な属性値を使って検索、取得が可能です。
詳しくはこちらを参考にしてください。
https://www.selenium.dev/ja/documentation/webdriver/elements/finders/
入力、送信する
form_ele = driver.find_element(:tag_name, 'form')
form_ele.find_element(name: 対象name属性の値).send_keys(入力値)
form_ele.find_element(:css, "label[for='#{labelのfor属性の値}']").click
form_element.find_element(:xpath, '//input[@type="submit"]').click
前節で取得した要素に実際に値を設定します。
send_keys
はテキストフィールドなどに値を入力します。
click
はそのままですが、取得した要素をクリックします。これによりcheckboxのlabelをクリックしてチェックしたり、送信ボタンを押すことが可能です。
※ ちなみになぜlabel要素をクリックしているかというと、デザインのために素のcheckboxを隠してlabel要素にスタイリングしていたからです。
そのほかの操作についてはこちらを参考にしてください。
https://www.selenium.dev/ja/documentation/webdriver/elements/interactions/
おまけ
前節でスタイリングされたチェックボックスをラベルのクリックでチェックしていましたが、 display: hidden
のはJavaScriptを使って非表示から表示にさせてクリックすることもできます。
click_element = driver.find_element(:class, '非表示要素のクラス名')
driver.execute_script("arguments[0].style.display = 'block';", click_element)
click_element.click
要素を取得し、そのまま click
ではエラーになってしまうので、driver.execute_script("arguments[0].style.display = 'block';", click_element)
で表示させてからクリックしています。
execute_script
は要素に対して直接JavaScriptを実行できるメソッドです。
まとめ
今回はseleniumをアプリケーションの機能の中で使用する方法をご紹介しました。
手順としては以下です。
Gemfile
の記述位置をテストのみから全体に変更$bundle install
- 使用するファイルで
require "selenium-webdriver"
使用できるメソッドなどは公式を見ていただけるとより詳しく解説されています!ありがとうございました!
Selenium公式
https://www.selenium.dev/ja/
コメント