Upgrade to Pro — share decks privately, control downloads, hide ads and more …

自分だけの小さなSelenium「Olenium」を作って始める、ブラウザ自動化技術の理論と実践

ikuma-t
October 22, 2022

 自分だけの小さなSelenium「Olenium」を作って始める、ブラウザ自動化技術の理論と実践

Kaigi on Rails 2022の登壇資料です!

https://kaigionrails.org/2022/talks/ikumatdkr/

ikuma-t

October 22, 2022
Tweet

More Decks by ikuma-t

Other Decks in Programming

Transcript

  1. Olenium じぶんだけの小さなSelenium を作って始める ブラウザ自動化技術の と 理論 実践 Olenium @ikuma-t

  2. ikuma-t ・ で勤務。いわゆる です。 株式会社エンペイ newbie ・最近 と名乗り始めました フロントエンドエンジニア ・未経験から

    で学んでプログラマーへ FJORD BOOT CAMP kaigi on rails 2022 アニメ好き / ツール好き / パン好きな人
  3. kaigi on rails 2022 ブラウザ自動化 テーマ

  4. わたしとブラウザ自動化 kaigi on rails 2022 ・SIerでのExcelペタペタ → 自動テストに感動 ・サンプルデータ「学校法人SQLインジェクション」の作成 ・Cypressで自作サービスのフロントエンドのテスト

  5. kaigi on rails 2022 なんとなく動いているけど、 どうやって ブラウザを操作しているの?

  6. kaigi on rails 2022 capybaraのfill_in!!

  7. kaigi on rails 2022 capybaraのfill_in!! 途中に なんかある

  8. kaigi on rails 2022 capybaraのfill_in!! 途中に なんかある ここを知りたい

  9. ブラウザ自動化の や とその を理解し、
 ブラウザ自動化を用いる際の を高める 登場人物 用語 関係性 解像度

    kaigi on rails 2022 「発表のゴール」
  10. Olenium 2. Olenium ・WebDriverベース ・HTTP ・Seleniumに名前が似てる Olaywright 3. Olaywright ・CDPベース

    ・WebSocket ・Playwrightに名前が似てる kaigi on rails 2022 xv ざっくりとした全体像 仕様を参考に自分でブラウザを自動操作してみよう
  11. kaigi on rails 2022 ブラウザ自動化の 全体図 Chapter 1

  12. わりとよく聞くブラウザ自動化/E2Eテストツール kaigi on rails 2022 Selenium Playwright Puppeteer Cypress (Microsoft)

    Puppeteer作ってた人が移動 (Google)
  13. ブラウザとの距離が近くなるほど、大きな力を手に入れるが... Devtools Protocol WebDriver 遠い △ △ ◦ ◎ ◎

    ◎ ◦ ◦ ◦ 近い もはや ブラウザ ブラウザとの 対話方法 ツール例 ブラウザとの 距離 テストの安定性 クロスブラウザ 使用可能言語 JavaScript in Browser
  14. ブラウザとの距離が近くなるほど、大きな力を手に入れるが... Devtools Protocol WebDriver 遠い △ △ ◦ ◎ ◎

    ◎ ◦ ◦ ◦ 近い もはや ブラウザ ブラウザとの 対話方法 ツール例 ブラウザとの 距離 テストの安定性 クロスブラウザ 使用可能言語 JavaScript in Browser JSしか使えない 馬力は低いけど 多様な環境で動く 馬力は低いけど 多様な環境で動く 環境に依存するけど その分高馬力 環境に依存するけど その分高馬力
  15. WebDriver kaigi on rails 2022 使用例:Selenium ローカルエンド リモートエンド UserAgent HTTPリクエスト

    HTTPレスポンス WebDriver ChromeDriver geckodriverなど 各プログラミング言語のための インターフェース Google Chrome Firefoxなど Command ・W3C勧告で最低限実装すべきコマンド(エンドポイント)が定義されている。 ・リモートエンドが仲介に立つことで、幅広い環境に対応している。 規定のエンドポイントを叩くと Command実行
  16. Devtools Protocol kaigi on rails 2022 使用例:Playwright、Puppeteer クライアント ターゲット ターゲット

    UserAgent WebSocket 実行できるMethodはProtocolで定義 各プログラミング言語のための インターフェース 操作対象のブラウザ、タブ、 サービスワーカーなど Google Chrome Firefoxなど ・各ブラウザごとにDevtools Protocolが提供されている。Chrome版がCDP。 ・SeleniumやCypressでも本流ではないが部分的に使用されている。
  17. JavaScript in Browser kaigi on rails 2022 使用例:Cypress Proxy OS

    WEB Node.js WebSocket HTTP 外部とのやりとりはここを通す これ自体は Vue.jsアプリ (DesktopAppもある) 【iframe1】 テスト対象のアプリ 【iframe2】 テストコード document.domainを いじることでSOPを回避
  18. Olenium 2. Olenium ・WebDriverベース ・HTTP ・Seleniumに名前が似てる Olaywright 3. Olaywright ・CDPベース

    ・WebSocket ・Playwrightに名前が似てる kaigi on rails 2022 xv ざっくりとした全体像 仕様を参考に自分でブラウザを自動操作してみよう
  19. kaigi on rails 2022 Chapter 2 WebDriver Olenium

  20. WebDriverという仕様 kaigi on rails 2022 もともとSeleniumの機能の1つ 2018年6月にW3C勧告として発表 Seleniumが元であると明記

  21. WebDriver kaigi on rails 2022 ローカルエンド リモートエンド UserAgent HTTPリクエスト HTTPレスポンス

    WebDriver ChromeDriver geckodriverなど 各プログラミング言語のための インターフェース Google Chrome Firefoxなど Command 規定のエンドポイントを叩くと Command実行 いまから作っていくところ
  22. エンドポイント kaigi on rails 2022 3) リモートエンドのエンドポイントを叩くと 2. 対応するコマンドが実行され、ブラウザが動く

  23. kaigi on rails 2022 ・テストの実行環境を指定する   ブラウザ名やタイムアウトを指定できる ・JSONオブジェクト形式で渡す ・空でもいいが、指定しないとエラー  

    リクエストになる https://www.w3.org/TR/webdriver2/#capabilities Capabilities
  24. curlコマンドでエンドポイントを叩いてみる kaigi on rails 2022 ChromeDriverを実行(localhost:9515で通知を待ち受ける) POST /session

  25. kaigi on rails 2022 ・ChromeDriverが localhost:9515 で起動している ・/session にPOSTする Capabilitiesの指定

    ・sessionIdがかえってきている
  26. Session kaigi on rails 2022 ほとんどのエンドポイントは「session_id」が必要

  27. Session kaigi on rails 2022 ・セッションにはブラウジング・コンテキストが  あり、これを操作していく ・現在操作対象となっているのが「カレント・  ブラウジング・コンテキスト」 ・操作対象を切り替えるには、ブラウジング・

     コンテキストを切り替えるエンドポイントを叩く 文書が表示されるタブやウィンドウのこと。HTML Living Standardで定義
  28. 8章以降はセクションごとにエンドポイントの説明 kaigi on rails 2022 今話してたのが 8. Sessions

  29. kaigi on rails 2022 Rubyで実装

  30. Olenium kaigi on rails 2022 ・Rubyで作るWebDriverの  ローカルエンド ・俺のSelenium(名前だけ)

  31. Olenium::Client kaigi on rails 2022 ・接続のための初期設定を行う ・sessionが不要なエンドポイントも  ここに実装 ・Olenium::Connectionは  Net::HTTPの簡易ラッパー

    session_idが必要なエンドポイント用 次ページ参照
  32. Olenium::Session kaigi on rails 2022 資料の掲載スペースが足りないだけで エンドレスメソッドである意味はまったくない ・session_idが必要なエンドポイント群 ・一部スクショを取るエンドポイントだけ  分割するほどでもないのでそのまま

    ・WebDriverのセクション単位で  別クラスとして抽出している。  中身としては愚直にHTTPリクエストを  しているだけです
  33. Oleniumで遊ぶ kaigi on rails 2022

  34. kaigi on rails 2022 お分かりいただけただろうか... Olenium 引用元:https://www.oreocookie.jp/

  35. Olenium 2. Olenium ・WebDriverベース ・HTTP ・Seleniumに名前が似てる Olaywright 3. Olaywright ・CDPベース

    ・WebSocket ・Playwrightに名前が似てる kaigi on rails 2022 xv ざっくりとした全体像 仕様を参考に自分でブラウザを自動操作してみよう
  36. kaigi on rails 2022 Chrome Devtools Protocol Chapter 3 Olaywright

  37. Chrome Devtools Protocolの仕様 kaigi on rails 2022 【各Domainごとの詳細】 ・赤: Experimental

    ・黄: Deprecated プロトコルについての説明 【バージョンごとの詳細】 バージョンによって使用できるDomain や機能が異なる https://chromedevtools.github.io/devtools-protocol/
  38. Chrome Devtools Protocol kaigi on rails 2022 使用例:Playwright、Puppeteer クライアント ターゲット

    ターゲット UserAgent WebSocket 実行できるMethodはProtocolで定義 各プログラミング言語のための インターフェース 操作対象のブラウザ、タブ、 サービスワーカーなど いまから作っていくところ
  39. kaigi on rails 2022 WebSocket ・URLスキーマとしてws://または暗号化されたwss://を用いる ・サーバとクライアントが接続を確立した後は、   そのコネクション上で専用のプロトコルを用いて通信を行う ・クライアントとサーバ間で双方向通信するためのプロトコル

    ・RailsだとActionCableで使用 https://www.rfc-editor.org/rfc/rfc6455
  40. WebSocketでChromeと接続する kaigi on rails 2022 WebSocketを扱えるツール(例:Postman) Chromeを起動

  41. 【再掲】Chrome Devtools Protocol kaigi on rails 2022 使用例:Playwright、Puppeteer クライアント ターゲット

    ターゲット UserAgent WebSocket 実行できるMethodはProtocolで定義 各プログラミング言語のための インターフェース 操作対象のブラウザ、タブ、 サービスワーカーなど いまから作っていくところ
  42. JSON-RPC kaigi on rails 2022 RPC(Remote Procedure Call)の1つ https://www.jsonrpc.org/specification 同じIDで紐付け

    同じIDで紐付け
  43. kaigi on rails 2022 メッセージを構成する① 各Domainごとに Methodが定義されている 紐付けのためのIDを指定 <Domain><method>の形式で指定 定義されているMethodを参照して、methodの値を指定

  44. kaigi on rails 2022 メッセージを構成する② 各Methodごとの説明 引数の一覧(optionalは任意引数) (少なくとも必須の)引数を設定

  45. メッセージを投げてみる① kaigi on rails 2022 PostmanでTarget.createTarget 新規タブで指定したURLが開く (計画通り)

  46. メッセージを投げてみる② kaigi on rails 2022 PostmanでPage.navigate 指定したURLに移動してほしいけど 変わってない エラー「‘Page.navigate’ wasn’t

    found 」
  47. 【再掲】Chrome Devtools Protocol kaigi on rails 2022 使用例:Playwright、Puppeteer クライアント ターゲット

    ターゲット UserAgent WebSocket 実行できるMethodはProtocolで定義 各プログラミング言語のための インターフェース 操作対象のブラウザ、タブ、 サービスワーカーなど いまから作っていくところ
  48. 【再掲】Chrome Devtools Protocol kaigi on rails 2022 使用例:Playwright、Puppeteer クライアント ターゲット

    ターゲット UserAgent WebSocket 実行できるMethodはProtocolで定義 各プログラミング言語のための インターフェース 操作対象のブラウザ、タブ、 サービスワーカーなど いまから作っていくところ
  49. kaigi on rails 2022 [Contributing to Chrome DevTools Protocol] (https://docs.google.com/document/d/1c-COD2kaK__

    5iMM5SEx-PzNA7HFmgttcYfOHHX0HaOM/edit#) ・デバッグ可能な実体。ページやブラウザ、   サービスワーカー ・ターゲットには次の2つがある   ・トップレベル(ex: ページ)   ・ネストされた(ex: ウェブワーカー) ・ターゲット別にWebSocketのURLが   振られている ターゲット
  50. メッセージを投げてみる② kaigi on rails 2022 PostmanでPage.navigate 指定したURLに移動してほしいけど 変わってない エラー「‘Page.navigate’ wasn’t

    found 」
  51. 【再掲】メッセージを投げてみる② kaigi on rails 2022 PostmanでPage.navigate 指定したURLに移動してほしいけど 変わってない エラー「‘Page.navigate’ wasn’t

    found 」 ・ターゲットがbrowserだったので、エラーになっていた  (ページ遷移ができるのはブラウザではなくて、ページ=タブなので) ・なので、このWebSocketの接続先(ターゲット)をページにすれば期待通りに動く
  52. ターゲットを取得するには kaigi on rails 2022 https://chromedevtools.github.io/devtools-protocol/ remote-debugging-portを指定すると、いくつかのエンドポイント(HTTP)が有効になる このURLでWebSocket接続をする。URLは`devtools/{target_type}/targetId`の形式

  53. メッセージを投げてみる③ kaigi on rails 2022 PostmanでPage.navigate 無事ページ遷移できた!

  54. kaigi on rails 2022 Rubyで実装

  55. Olaywright kaigi on rails 2022 ・WebSocket接続には【Gem】  websocket-client-simpleを使用 ・大人の事情でirbで動かす前提  (普通にやっても動きはするけど) ・俺のPlaywright(名前だけ)

  56. Olaywright:初期設定 kaigi on rails 2022 Wc GET /json/list でターゲット一覧を取3 2c

    pageを接続対象に指定 3. WebSocket接続
  57. 公開されているプロトコル定義を使用する kaigi on rails 2022 browser_protocol 2フォーマットで公開されている 各Domainの情報がJSONで返ってくる js_protocol PDL

    or JSON PDLはCDPを記述するために 作られたフォーマット (発音:ˈpo͞ odl") GET /json/protocol
  58. 例: chromedp(Go言語実装) kaigi on rails 2022 ユーザー browser_protocol js_protocol Renée

    French PDL or JSON chromedp/pdlgen chromedp/ cdproto chromedp/ chromedp 自動生成 【罠】エラーなく動作する最新のブランチ名は、「main」ではなく「old」
  59. 例: chromedp(Go言語実装) kaigi on rails 2022 ユーザー browser_protocol js_protocol Renée

    French PDL or JSON chromedp/pdlgen chromedp/ cdproto chromedp/ chromedp 自動生成 【罠】エラーなく動作する最新のブランチ名は、「main」ではなく「old」 Olaywrightもこんな感じで 動的にプロトコルをパースして 低レベルで呼び出せるようにした
  60. Olaywrightで遊ぶ kaigi on rails 2022

  61. Olenium 2. Olenium ・WebDriverベース ・HTTP ・Seleniumに名前が似てる Olaywright 3. Olaywright ・CDPベース

    ・WebSocket ・Playwrightに名前が似てる kaigi on rails 2022 xv ざっくりとした全体像 仕様を参考に自分でブラウザを自動操作してみよう
  62. kaigi on rails 2022 まとめ Chapter 4

  63. kaigi on rails 2022 ブ ラ ウ ザ ブ ラ

    ウ ザ 自 動 化 ツ I ル 途中になんかある
  64. kaigi on rails 2022 ブ ラ ウ ザ ブ ラ

    ウ ザ 自 動 化 ツ I ル 途中になんかある リモートエンド ロ I カ ル エ ン ド HTTPリクエスト HTTPレスポンス Command WebDriver 規定のエンドポイントを叩くと Command実行
  65. kaigi on rails 2022 ブ ラ ウ ザ ブ ラ

    ウ ザ 自 動 化 ツ I ル リモートエンド HTTPリクエスト ク ラ イ ア ン ト HTTPレスポンス Command WebDriver Devtools Protocol 規定のエンドポイントを叩くと Command実行 JSON RPC via WebSocket 実行できるMethodはProtocolで定義 ロ I カ ル エ ン ド
  66. kaigi on rails 2022 ブ ラ ウ ザ ブ ラ

    ウ ザ 自 動 化 ツ I ル リモートエンド HTTPリクエスト ク ラ イ ア ン ト HTTPレスポンス Command WebDriver Devtools Protocol 規定のエンドポイントを叩くと Command実行 JSON RPC via WebSocket 実行できるMethodはProtocolで定義 ロ I カ ル エ ン ド iframe
  67. ‘‘ ’’ kaigi on rails 2022 r7kamura [個人サイトについて](https://r7kamura.com/articles/2020-09-21-personal-website) 多くの人にとって、ウェブの技術は魔法だ。 少し指を動かすだけで、世界中の人に自分の声を届けられる。

    しかし自分にとって、ウェブの技術はもはや魔法ではない。 知ってしまった以上、 使いこなしたいと思うのが人の性というもの。
  68. kaigi on rails 2022 ブ ラ ウ ザ ブ ラ

    ウ ザ 自 動 化 ツ I ル リモートエンド HTTPリクエスト ク ラ イ ア ン ト HTTPレスポンス Command WebDriver Devtools Protocol 規定のエンドポイントを叩くと Command実行 JSON RPC via WebSocket 実行できるMethodはProtocolで定義 ロ I カ ル エ ン ド iframe RailsのE2Eで馴染みのあるSelenium
  69. kaigi on rails 2022 ブ ラ ウ ザ ブ ラ

    ウ ザ 自 動 化 ツ I ル リモートエンド HTTPリクエスト ク ラ イ ア ン ト HTTPレスポンス Command WebDriver Devtools Protocol 規定のエンドポイントを叩くと Command実行 JSON RPC via WebSocket 実行できるMethodはProtocolで定義 ロ I カ ル エ ン ド iframe Railsで学ぶWebの基礎 RailsのE2Eで馴染みのあるSelenium
  70. kaigi on rails 2022 ブ ラ ウ ザ ブ ラ

    ウ ザ 自 動 化 ツ I ル リモートエンド HTTPリクエスト ク ラ イ ア ン ト HTTPレスポンス Command WebDriver Devtools Protocol 規定のエンドポイントを叩くと Command実行 JSON RPC via WebSocket 実行できるMethodはProtocolで定義 ロ I カ ル エ ン ド iframe Railsで学ぶWebの基礎 別プロトコルだけど、指定の形式でリクエストするのは同じ RailsのE2Eで馴染みのあるSelenium
  71. kaigi on rails 2022 ブ ラ ウ ザ ブ ラ

    ウ ザ 自 動 化 ツ I ル リモートエンド HTTPリクエスト ク ラ イ ア ン ト HTTPレスポンス Command WebDriver Devtools Protocol 規定のエンドポイントを叩くと Command実行 JSON RPC via WebSocket 実行できるMethodはProtocolで定義 ロ I カ ル エ ン ド iframe Railsで学ぶWebの基礎 別プロトコルだけど、指定の形式でリクエストするのは同じ 他言語実装を 参考にしてみる RailsのE2Eで馴染みのあるSelenium
  72. kaigi on rails 2022 ブ ラ ウ ザ ブ ラ

    ウ ザ 自 動 化 ツ I ル リモートエンド HTTPリクエスト ク ラ イ ア ン ト HTTPレスポンス Command WebDriver Devtools Protocol 規定のエンドポイントを叩くと Command実行 JSON RPC via WebSocket 実行できるMethodはProtocolで定義 ロ I カ ル エ ン ド iframe Railsで学ぶWebの基礎 別プロトコルだけど、指定の形式でリクエストするのは同じ 他言語実装を 参考にしてみる RailsのE2Eで馴染みのあるSelenium With Ruby
  73. kaigi on rails 2022 With With Ruby Rails

  74. kaigi on rails 2022 PR Extra Chapter

  75. kaigi on rails 2022 やさしいフィンテックを。 テクノロジーの力で、 新しいお金の流れをつくる。

  76. kaigi on rails 2022 ぜひお話ししましょう!

  77. kaigi on rails 2022 ありがとうございました!

  78. 参考 kaigi on rails 2022 ・WebDriver - W3C: https://www.w3.org/TR/webdriver/ ・Chrome

    Devtools Protocol: https://chromedevtools.github.io/devtools-protocol/ ・Cypress: https://www.cypress.io/ ・Contributing to Chrome DevTools Protocol: https://onl.la/JEzM2cp ・getting-started-with-cdp: https://onl.la/kfLHLxE ・pdlgen: https://github.com/chromedp/pdlgen ・chrome-remote-interface: https://github.com/cyrus-and/chrome-remote-interface ・ferrum: https://github.com/rubycdp/ferrum ・Cypress vs Other Test Runners: https://onl.la/cNnSNsc