【Rails】Seleniumをアプリケーションの機能で使う方法

RubyOnRails

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/

Gemの公式
https://github.com/SeleniumHQ

コメント

タイトルとURLをコピーしました