Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
自分だけの小さなSelenium「Olenium」を作って始める、ブラウザ自動化技術の理論と実践
Search
ikuma-t
October 22, 2022
Programming
24
9.8k
自分だけの小さなSelenium「Olenium」を作って始める、ブラウザ自動化技術の理論と実践
Kaigi on Rails 2022の登壇資料です!
https://kaigionrails.org/2022/talks/ikumatdkr/
ikuma-t
October 22, 2022
Tweet
Share
More Decks by ikuma-t
See All by ikuma-t
Make Impossible States Impossibleを 意識してReactのPropsを設計しよう
ikumatadokoro
0
140
いまさらのStorybook
ikumatadokoro
0
180
これで最後にしたい! Astroと立ち向かう 6度目の個人ブログ再開発
ikumatadokoro
4
330
Panda CSS と Ark UI ではじめる個人開発
ikumatadokoro
2
870
見た目から始める生産性向上
ikumatadokoro
10
5.3k
ぼくが 美容師さんに伝えたかった バンドの話
ikumatadokoro
0
130
Railsアプリをコスパよく読むための環境整備
ikumatadokoro
2
780
HTTPを手で書いて学ぶ ファイルアップロードの仕組み
ikumatadokoro
74
27k
たどころくん1号を支える技術
ikumatadokoro
1
190
Other Decks in Programming
See All in Programming
色々なIaCツールを実際に触って比較してみる
iriikeita
0
320
CPython 인터프리터 구조 파헤치기 - PyCon Korea 24
kennethanceyer
0
250
AI時代におけるSRE、 あるいはエンジニアの生存戦略
pyama86
4
1.1k
Dev ContainersとGitHub Codespacesの素敵な関係
ymd65536
1
140
NSOutlineView何もわからん:( 前編 / I Don't Understand About NSOutlineView :( Pt. 1
usagimaru
0
300
開発効率向上のためのリファクタリングの一歩目の選択肢 ~コード分割~ / JJUG CCC 2024 Fall
ryounasso
0
440
Pinia Colada が実現するスマートな非同期処理
naokihaba
4
210
ふかぼれ!CSSセレクターモジュール / Fukabore! CSS Selectors Module
petamoriken
0
150
みんなでプロポーザルを書いてみた
yuriko1211
0
230
Tuning GraphQL on Rails
pyama86
2
1.2k
外部システム連携先が10を超えるシステムでのアーキテクチャ設計・実装事例
kiwasaki
1
280
Amazon Qを使ってIaCを触ろう!
maruto
0
380
Featured
See All Featured
How To Stay Up To Date on Web Technology
chriscoyier
788
250k
VelocityConf: Rendering Performance Case Studies
addyosmani
325
24k
[RailsConf 2023] Rails as a piece of cake
palkan
51
4.9k
Navigating Team Friction
lara
183
14k
GraphQLとの向き合い方2022年版
quramy
43
13k
10 Git Anti Patterns You Should be Aware of
lemiorhan
654
59k
Building an army of robots
kneath
302
42k
Designing the Hi-DPI Web
ddemaree
280
34k
KATA
mclloyd
29
14k
Intergalactic Javascript Robots from Outer Space
tanoku
268
27k
Raft: Consensus for Rubyists
vanstee
136
6.6k
How to Ace a Technical Interview
jacobian
276
23k
Transcript
Olenium じぶんだけの小さなSelenium を作って始める ブラウザ自動化技術の と 理論 実践 Olenium @ikuma-t
ikuma-t ・ で勤務。いわゆる です。 株式会社エンペイ newbie ・最近 と名乗り始めました フロントエンドエンジニア ・未経験から
で学んでプログラマーへ FJORD BOOT CAMP kaigi on rails 2022 アニメ好き / ツール好き / パン好きな人
kaigi on rails 2022 ブラウザ自動化 テーマ
わたしとブラウザ自動化 kaigi on rails 2022 ・SIerでのExcelペタペタ → 自動テストに感動 ・サンプルデータ「学校法人SQLインジェクション」の作成 ・Cypressで自作サービスのフロントエンドのテスト
kaigi on rails 2022 なんとなく動いているけど、 どうやって ブラウザを操作しているの?
kaigi on rails 2022 capybaraのfill_in!!
kaigi on rails 2022 capybaraのfill_in!! 途中に なんかある
kaigi on rails 2022 capybaraのfill_in!! 途中に なんかある ここを知りたい
ブラウザ自動化の や とその を理解し、 ブラウザ自動化を用いる際の を高める 登場人物 用語 関係性 解像度
kaigi on rails 2022 「発表のゴール」
Olenium 2. Olenium ・WebDriverベース ・HTTP ・Seleniumに名前が似てる Olaywright 3. Olaywright ・CDPベース
・WebSocket ・Playwrightに名前が似てる kaigi on rails 2022 xv ざっくりとした全体像 仕様を参考に自分でブラウザを自動操作してみよう
kaigi on rails 2022 ブラウザ自動化の 全体図 Chapter 1
わりとよく聞くブラウザ自動化/E2Eテストツール kaigi on rails 2022 Selenium Playwright Puppeteer Cypress (Microsoft)
Puppeteer作ってた人が移動 (Google)
ブラウザとの距離が近くなるほど、大きな力を手に入れるが... Devtools Protocol WebDriver 遠い △ △ ◦ ◎ ◎
◎ ◦ ◦ ◦ 近い もはや ブラウザ ブラウザとの 対話方法 ツール例 ブラウザとの 距離 テストの安定性 クロスブラウザ 使用可能言語 JavaScript in Browser
ブラウザとの距離が近くなるほど、大きな力を手に入れるが... Devtools Protocol WebDriver 遠い △ △ ◦ ◎ ◎
◎ ◦ ◦ ◦ 近い もはや ブラウザ ブラウザとの 対話方法 ツール例 ブラウザとの 距離 テストの安定性 クロスブラウザ 使用可能言語 JavaScript in Browser JSしか使えない 馬力は低いけど 多様な環境で動く 馬力は低いけど 多様な環境で動く 環境に依存するけど その分高馬力 環境に依存するけど その分高馬力
WebDriver kaigi on rails 2022 使用例:Selenium ローカルエンド リモートエンド UserAgent HTTPリクエスト
HTTPレスポンス WebDriver ChromeDriver geckodriverなど 各プログラミング言語のための インターフェース Google Chrome Firefoxなど Command ・W3C勧告で最低限実装すべきコマンド(エンドポイント)が定義されている。 ・リモートエンドが仲介に立つことで、幅広い環境に対応している。 規定のエンドポイントを叩くと Command実行
Devtools Protocol kaigi on rails 2022 使用例:Playwright、Puppeteer クライアント ターゲット ターゲット
UserAgent WebSocket 実行できるMethodはProtocolで定義 各プログラミング言語のための インターフェース 操作対象のブラウザ、タブ、 サービスワーカーなど Google Chrome Firefoxなど ・各ブラウザごとにDevtools Protocolが提供されている。Chrome版がCDP。 ・SeleniumやCypressでも本流ではないが部分的に使用されている。
JavaScript in Browser kaigi on rails 2022 使用例:Cypress Proxy OS
WEB Node.js WebSocket HTTP 外部とのやりとりはここを通す これ自体は Vue.jsアプリ (DesktopAppもある) 【iframe1】 テスト対象のアプリ 【iframe2】 テストコード document.domainを いじることでSOPを回避
Olenium 2. Olenium ・WebDriverベース ・HTTP ・Seleniumに名前が似てる Olaywright 3. Olaywright ・CDPベース
・WebSocket ・Playwrightに名前が似てる kaigi on rails 2022 xv ざっくりとした全体像 仕様を参考に自分でブラウザを自動操作してみよう
kaigi on rails 2022 Chapter 2 WebDriver Olenium
WebDriverという仕様 kaigi on rails 2022 もともとSeleniumの機能の1つ 2018年6月にW3C勧告として発表 Seleniumが元であると明記
WebDriver kaigi on rails 2022 ローカルエンド リモートエンド UserAgent HTTPリクエスト HTTPレスポンス
WebDriver ChromeDriver geckodriverなど 各プログラミング言語のための インターフェース Google Chrome Firefoxなど Command 規定のエンドポイントを叩くと Command実行 いまから作っていくところ
エンドポイント kaigi on rails 2022 3) リモートエンドのエンドポイントを叩くと 2. 対応するコマンドが実行され、ブラウザが動く
kaigi on rails 2022 ・テストの実行環境を指定する ブラウザ名やタイムアウトを指定できる ・JSONオブジェクト形式で渡す ・空でもいいが、指定しないとエラー
リクエストになる https://www.w3.org/TR/webdriver2/#capabilities Capabilities
curlコマンドでエンドポイントを叩いてみる kaigi on rails 2022 ChromeDriverを実行(localhost:9515で通知を待ち受ける) POST /session
kaigi on rails 2022 ・ChromeDriverが localhost:9515 で起動している ・/session にPOSTする Capabilitiesの指定
・sessionIdがかえってきている
Session kaigi on rails 2022 ほとんどのエンドポイントは「session_id」が必要
Session kaigi on rails 2022 ・セッションにはブラウジング・コンテキストが あり、これを操作していく ・現在操作対象となっているのが「カレント・ ブラウジング・コンテキスト」 ・操作対象を切り替えるには、ブラウジング・
コンテキストを切り替えるエンドポイントを叩く 文書が表示されるタブやウィンドウのこと。HTML Living Standardで定義
8章以降はセクションごとにエンドポイントの説明 kaigi on rails 2022 今話してたのが 8. Sessions
kaigi on rails 2022 Rubyで実装
Olenium kaigi on rails 2022 ・Rubyで作るWebDriverの ローカルエンド ・俺のSelenium(名前だけ)
Olenium::Client kaigi on rails 2022 ・接続のための初期設定を行う ・sessionが不要なエンドポイントも ここに実装 ・Olenium::Connectionは Net::HTTPの簡易ラッパー
session_idが必要なエンドポイント用 次ページ参照
Olenium::Session kaigi on rails 2022 資料の掲載スペースが足りないだけで エンドレスメソッドである意味はまったくない ・session_idが必要なエンドポイント群 ・一部スクショを取るエンドポイントだけ 分割するほどでもないのでそのまま
・WebDriverのセクション単位で 別クラスとして抽出している。 中身としては愚直にHTTPリクエストを しているだけです
Oleniumで遊ぶ kaigi on rails 2022
kaigi on rails 2022 お分かりいただけただろうか... Olenium 引用元:https://www.oreocookie.jp/
Olenium 2. Olenium ・WebDriverベース ・HTTP ・Seleniumに名前が似てる Olaywright 3. Olaywright ・CDPベース
・WebSocket ・Playwrightに名前が似てる kaigi on rails 2022 xv ざっくりとした全体像 仕様を参考に自分でブラウザを自動操作してみよう
kaigi on rails 2022 Chrome Devtools Protocol Chapter 3 Olaywright
Chrome Devtools Protocolの仕様 kaigi on rails 2022 【各Domainごとの詳細】 ・赤: Experimental
・黄: Deprecated プロトコルについての説明 【バージョンごとの詳細】 バージョンによって使用できるDomain や機能が異なる https://chromedevtools.github.io/devtools-protocol/
Chrome Devtools Protocol kaigi on rails 2022 使用例:Playwright、Puppeteer クライアント ターゲット
ターゲット UserAgent WebSocket 実行できるMethodはProtocolで定義 各プログラミング言語のための インターフェース 操作対象のブラウザ、タブ、 サービスワーカーなど いまから作っていくところ
kaigi on rails 2022 WebSocket ・URLスキーマとしてws://または暗号化されたwss://を用いる ・サーバとクライアントが接続を確立した後は、 そのコネクション上で専用のプロトコルを用いて通信を行う ・クライアントとサーバ間で双方向通信するためのプロトコル
・RailsだとActionCableで使用 https://www.rfc-editor.org/rfc/rfc6455
WebSocketでChromeと接続する kaigi on rails 2022 WebSocketを扱えるツール(例:Postman) Chromeを起動
【再掲】Chrome Devtools Protocol kaigi on rails 2022 使用例:Playwright、Puppeteer クライアント ターゲット
ターゲット UserAgent WebSocket 実行できるMethodはProtocolで定義 各プログラミング言語のための インターフェース 操作対象のブラウザ、タブ、 サービスワーカーなど いまから作っていくところ
JSON-RPC kaigi on rails 2022 RPC(Remote Procedure Call)の1つ https://www.jsonrpc.org/specification 同じIDで紐付け
同じIDで紐付け
kaigi on rails 2022 メッセージを構成する① 各Domainごとに Methodが定義されている 紐付けのためのIDを指定 <Domain><method>の形式で指定 定義されているMethodを参照して、methodの値を指定
kaigi on rails 2022 メッセージを構成する② 各Methodごとの説明 引数の一覧(optionalは任意引数) (少なくとも必須の)引数を設定
メッセージを投げてみる① kaigi on rails 2022 PostmanでTarget.createTarget 新規タブで指定したURLが開く (計画通り)
メッセージを投げてみる② kaigi on rails 2022 PostmanでPage.navigate 指定したURLに移動してほしいけど 変わってない エラー「‘Page.navigate’ wasn’t
found 」
【再掲】Chrome Devtools Protocol kaigi on rails 2022 使用例:Playwright、Puppeteer クライアント ターゲット
ターゲット UserAgent WebSocket 実行できるMethodはProtocolで定義 各プログラミング言語のための インターフェース 操作対象のブラウザ、タブ、 サービスワーカーなど いまから作っていくところ
【再掲】Chrome Devtools Protocol kaigi on rails 2022 使用例:Playwright、Puppeteer クライアント ターゲット
ターゲット UserAgent WebSocket 実行できるMethodはProtocolで定義 各プログラミング言語のための インターフェース 操作対象のブラウザ、タブ、 サービスワーカーなど いまから作っていくところ
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が 振られている ターゲット
メッセージを投げてみる② kaigi on rails 2022 PostmanでPage.navigate 指定したURLに移動してほしいけど 変わってない エラー「‘Page.navigate’ wasn’t
found 」
【再掲】メッセージを投げてみる② kaigi on rails 2022 PostmanでPage.navigate 指定したURLに移動してほしいけど 変わってない エラー「‘Page.navigate’ wasn’t
found 」 ・ターゲットがbrowserだったので、エラーになっていた (ページ遷移ができるのはブラウザではなくて、ページ=タブなので) ・なので、このWebSocketの接続先(ターゲット)をページにすれば期待通りに動く
ターゲットを取得するには kaigi on rails 2022 https://chromedevtools.github.io/devtools-protocol/ remote-debugging-portを指定すると、いくつかのエンドポイント(HTTP)が有効になる このURLでWebSocket接続をする。URLは`devtools/{target_type}/targetId`の形式
メッセージを投げてみる③ kaigi on rails 2022 PostmanでPage.navigate 無事ページ遷移できた!
kaigi on rails 2022 Rubyで実装
Olaywright kaigi on rails 2022 ・WebSocket接続には【Gem】 websocket-client-simpleを使用 ・大人の事情でirbで動かす前提 (普通にやっても動きはするけど) ・俺のPlaywright(名前だけ)
Olaywright:初期設定 kaigi on rails 2022 Wc GET /json/list でターゲット一覧を取3 2c
pageを接続対象に指定 3. WebSocket接続
公開されているプロトコル定義を使用する kaigi on rails 2022 browser_protocol 2フォーマットで公開されている 各Domainの情報がJSONで返ってくる js_protocol PDL
or JSON PDLはCDPを記述するために 作られたフォーマット (発音:ˈpo͞ odl") GET /json/protocol
例: chromedp(Go言語実装) kaigi on rails 2022 ユーザー browser_protocol js_protocol Renée
French PDL or JSON chromedp/pdlgen chromedp/ cdproto chromedp/ chromedp 自動生成 【罠】エラーなく動作する最新のブランチ名は、「main」ではなく「old」
例: 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もこんな感じで 動的にプロトコルをパースして 低レベルで呼び出せるようにした
Olaywrightで遊ぶ kaigi on rails 2022
Olenium 2. Olenium ・WebDriverベース ・HTTP ・Seleniumに名前が似てる Olaywright 3. Olaywright ・CDPベース
・WebSocket ・Playwrightに名前が似てる kaigi on rails 2022 xv ざっくりとした全体像 仕様を参考に自分でブラウザを自動操作してみよう
kaigi on rails 2022 まとめ Chapter 4
kaigi on rails 2022 ブ ラ ウ ザ ブ ラ
ウ ザ 自 動 化 ツ I ル 途中になんかある
kaigi on rails 2022 ブ ラ ウ ザ ブ ラ
ウ ザ 自 動 化 ツ I ル 途中になんかある リモートエンド ロ I カ ル エ ン ド HTTPリクエスト HTTPレスポンス Command WebDriver 規定のエンドポイントを叩くと Command実行
kaigi on rails 2022 ブ ラ ウ ザ ブ ラ
ウ ザ 自 動 化 ツ I ル リモートエンド HTTPリクエスト ク ラ イ ア ン ト HTTPレスポンス Command WebDriver Devtools Protocol 規定のエンドポイントを叩くと Command実行 JSON RPC via WebSocket 実行できるMethodはProtocolで定義 ロ I カ ル エ ン ド
kaigi on rails 2022 ブ ラ ウ ザ ブ ラ
ウ ザ 自 動 化 ツ I ル リモートエンド HTTPリクエスト ク ラ イ ア ン ト HTTPレスポンス Command WebDriver Devtools Protocol 規定のエンドポイントを叩くと Command実行 JSON RPC via WebSocket 実行できるMethodはProtocolで定義 ロ I カ ル エ ン ド iframe
‘‘ ’’ kaigi on rails 2022 r7kamura [個人サイトについて](https://r7kamura.com/articles/2020-09-21-personal-website) 多くの人にとって、ウェブの技術は魔法だ。 少し指を動かすだけで、世界中の人に自分の声を届けられる。
しかし自分にとって、ウェブの技術はもはや魔法ではない。 知ってしまった以上、 使いこなしたいと思うのが人の性というもの。
kaigi on rails 2022 ブ ラ ウ ザ ブ ラ
ウ ザ 自 動 化 ツ I ル リモートエンド HTTPリクエスト ク ラ イ ア ン ト HTTPレスポンス Command WebDriver Devtools Protocol 規定のエンドポイントを叩くと Command実行 JSON RPC via WebSocket 実行できるMethodはProtocolで定義 ロ I カ ル エ ン ド iframe RailsのE2Eで馴染みのあるSelenium
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
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
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
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
kaigi on rails 2022 With With Ruby Rails
kaigi on rails 2022 PR Extra Chapter
kaigi on rails 2022 やさしいフィンテックを。 テクノロジーの力で、 新しいお金の流れをつくる。
kaigi on rails 2022 ぜひお話ししましょう!
kaigi on rails 2022 ありがとうございました!
参考 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