今回は、W3C WebDriver APIについてザザザーっと勉強しました。
概要から入って、仕様に乗っかってコマンドをバシバシ試していきます。
- PowerShellでSelenium使わずWebDriver操作
- セッションの生成、ページ遷移、ウィンドウ制御(今ここ)
- タグ要素の情報取得
- タグ要素の操作・スクリプトの実行
長いテーマなので3本立てになっています!
1.WebDriverってなんじゃいって話
もともとは、「Selenium WebDriver browser automation framework」ってことで
Seleniumって呼ばれているブラウザテストができるツール群として開発されていたそうです。
実際、ブラウザ自動化って検索すると、Seleniumの情報ばっかり出てくると思います。
で、そこで培った知見を基にW3Cの方でブラウザ操作の仕組みを標準化して
API仕様を勧告したのが、2018年6月5日のことなんだそうです。
なるほどー、結構最近なんだね。って感じ。
で、W3Cの勧告を受けて、その標準仕様に合わせて各ブラウザベンダが
各自ブラウザを操作する為のWebDriverを開発提供してくれていると。
2.基本的な使い方は?
Seleniumはdll化されたクラスライブラリとしてJavaとかC++とかで読み込んで使う感じだったんだけど、標準規格化されて嬉しいのは言語縛りなく組み込みコンパイル不要で独立して動く様にモジュール化されたってところ。
さっくり使ってみる記事で試した通り、WebDriverを起動するとlocalhost上で
localhostからのみ受け付けるportセッションがListen状態になる。
デフォルトでListenになるport番号はブラウザによって異なるけども、
基本portオプションを付けて起動すれば好きなport番号でListenできる。
あとは、http://localhost:xxxx/に対してHttpリクエストを送ってコマンドを発行していくんだけど
いくつかの簡単な法則に乗っ取って仕様は定義されているみたいだ。
- コマンドは、1つのURLへのリクエストが1のコマンドになるようになってる。
- New SessionコマンドとStatusコマンド以外では、URLでSessionIDを指定してコマンド発行する。
- Postリクエストでは、BodyにJsonを使う。だからヘッダーはこう『application/json; charset=utf-8』
- コマンドがエラーだった時は、Json形式でこんなパラメータが返ってくる?「error」、「message」、「stacktrace」
3.コマンドを試していく。
基本的には、このページ(W3C WebDriver API)を見ながら、手元では、ChromeDriverを動かして試していきました。
W3C WebDriver APIの方は、標準仕様としてこうあった方がいいよって話で
実際には他のWebDriverを使った時には違う拡張がされている部分もあるかもということを念頭に置きながら・・・。
検証の前提条件
- WebDriverは、自身の端末ブラウザのバージョンを確認して適切なものをダウンロードしましょう。
- 今回はChromeDriverで確認したからportはデフォルトの9515を使用。
- 検証はPowerShellで行っていきました。
いっぱいリクエスト飛ばしてテストするから、この関数だけ先に宣言しとく。
# Uriと連想配列を渡してJsonでPostするfunction function Post-JsonContent($postUri,$body) { $json = $body | ConvertTo-Json -Compress $JsonBody = [Text.Encoding]::UTF8.GetBytes($json) return Invoke-RestMethod -Method POST -Uri $postUri -Body $JsonBody -ContentType application/json }
では、WebDriverのプロセス起動から。
Start-Process -FilePath chromedriver.exe -ArgumentList port=9515
ブラウザ起動(New Session)
リクエスト
(POST) http://localhost:9515/session
$body = @{desiredCapabilities=@{}} $uri = "http://localhost:9515/session" $rsp = Post-JsonContent $uri $body $sessionId = $rsp.sessionId $uri = $uri + '/' + $sessionId
リクエストとして、capabilitiesっていう項目は必ず入れる必要あり。
capabilitiesの指定が入ってないと以下のエラーメッセージが返ってきます。
message : session not created exception: Missing or invalid capabilities
他にもいろいろ指定できるオプションあるけど、とりあえず上記の記述だけで通りました。
ブラウザ起動に成功するとレスポンスとして本文にsessionIdが返ってきます。
以降の処理では、この[sessionId]をURLに組み込んでコマンドを実行していく。
ブラウザ閉じる(Delete Session)
リクエスト
(DELETE) http://localhost:9515/session/{sessionId}
Invoke-RestMethod -Method DELETE -Uri $uri
リクエストのmethod自体をDELETEにする。
bodyは特に何もセットしなくてもブラウザは閉じられます。
URLページ表示(Navigate To)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/url
$body = @{url="https://yizm.work/"} $url_uri = $uri + '/url' $rsp = Post-JsonContent $url_uri $body
とりあえず、Jsonパラメータで開きたいURLを指定すればそのページ開ける。
Basic認証とかどーやって通過するかちょっと調べとかないとな。。。
開かれているページURLを取得(Get Current URL)
リクエスト
(GET) http://localhost:9515/session/{sessionId}/url
Invoke-RestMethod -Uri $url_uri
valueにURLが入って返ってくる。
戻る(Back)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/back
$body = @{} $back_uri = $uri + '/back' $rsp = Post-JsonContent $back_uri $body
bodyは空っぽでも、とりあえずブラウザ履歴の「戻る」ボタンの動きする。
進む(Forward)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/forward
$fwd_uri = $uri + '/forward' $rsp = Post-JsonContent $fwd_uri $body
bodyは空っぽでも、とりあえずブラウザ履歴の「進む」ボタンの動きする。
更新(Refresh)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/refresh
$rfr_uri = $uri + '/refresh' $rsp = Post-JsonContent $rfr_uri $body
bodyは空っぽでも、とりあえずブラウザF5の「更新」の動きする。
タイトル取得(Get Title)
リクエスト
(GET) http://localhost:9515/session/{sessionId}/title
$title_uri = $uri + '/title' Invoke-RestMethod -Uri $title_uri
valueにサイトのタイトルが入ってくる。
ウィンドウハンドルの取得(Get Window Handle)
リクエスト
(GET) http://localhost:9515/session/{sessionId}/title
$hwnd_uri = $uri + '/window' Invoke-RestMethod -Uri $hwnd_uri
ブラウザは、タブごとにウィンドウハンドルを持っていてSessionIdとは別にタブごとのウィンドウハンドルが取得できる。
valueに直接ウィンドウハンドルの文字列が返る。
新しいタブを開く(New Window)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/window/new
$hwnd_uri = $uri + '/window/new' $body = @{type="tab"} $rsp = Post-JsonContent $hwnd_uri $body
@{}でbody空っぽでも新しいタブでウィンドウ開けるけど、
type="window"って指定することで新しいタブを新しいウィンドウ化して分離起動もできる。
value.handle ⇒ ウィンドウハンドル値
value.type ⇒ tab または window
という形式のレスポンスが返ってくる。
ウィンドウハンドルを全て取得(Get Window Handles)
リクエスト
(GET) http://localhost:9515/session/{sessionId}/window/handles
$hwnd_uri = $uri + '/window/handles' Invoke-RestMethod -Uri $hwnd_uri
valueに配列の形でウィンドウハンドルが取得される。
ウィンドウ切替(Switch To Window)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/window
$hwnd_uri = $uri + '/window' $body = @{name='ウィンドウハンドル値'} $rsp = Post-JsonContent $hwnd_uri $body
W3C見てるとhandleっていうプロパティが必要そうなんだけど、handle='ウィンドウハンドル値'で送るとこんなエラーがでた。
status:61
message:invalid argument: 'name' must be a string
nameプロパティでウィンドウハンドル値を送るとタブの切替ができた。
nameプロパティを空白にして送ると一番最初のタブが選択された。
タブを閉じる(Close Window)
リクエスト
(DELETE) http://localhost:9515/session/{sessionId}/window
$hwnd_uri = $uri + '/window' Invoke-RestMethod -Method DELETE -Uri $hwnd_uri
選択中のタブが閉じられる。
カレントタブは自動的には切り替わらない。
閉じた直後のウィンドウハンドルをそのまま取得しようとすると、以下のエラーが出た。
status:23
message:no such window: target window already closed\
なので、閉じた後はウィンドウ切替でカレント移動が必要。
ウィンドウのサイズ変更と配置(Resizing and positioning windows)
ウィンドウの取得(Get Window Rect)
リクエスト
(GET) http://localhost:9515/session/{sessionId}/window/rect
$wnd_uri = $uri + '/window/rect' Invoke-RestMethod -Uri $wnd_uri
valueに以下のプロパティが取得される。
height、width、x、y
ウィンドウが最小化されてても元々のサイズと位置が取得される様だ。
ウィンドウの位置サイズの設定(Set Window Rect)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/window/rect
$wnd_uri = $uri + '/window/rect' $body = @{height=600;width=1000;x=20;y=10} $rsp = Post-JsonContent $wnd_uri $body
んまぁ・・・使いたいシーンが思いつかんがな。
サイズと位置が動かせることは確認できたよ。
ウィンドウの最大化(Maximize Window)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/window/maximize
$wnd_uri = $uri + '/window/maximize' $body = @{} $rsp = Post-JsonContent $wnd_uri $body
ウィンドウの最小化(Minimize Window)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/window/minimize
$wnd_uri = $uri + '/window/minimize' $body = @{} $rsp = Post-JsonContent $wnd_uri $body
全画面ウィンドウ(Fullscreen Window)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/window/fullscreen
$wnd_uri = $uri + '/window/fullscreen' $body = @{} $rsp = Post-JsonContent $wnd_uri $body
これは、F11とかでなるタイトルバーが見えなくなるタイプの全画面ね。
・・・項目数多くて疲れたから一旦ここまで!
後編から、HTML要素の取得・操作の部分に入ってきます。
「W3C WebDriver APIをPowerShell制御まとめ①」への5件のフィードバック