続き、W3C WebDriver APIについてザザザーっと勉強しました。
- PowerShellでSelenium使わずWebDriver操作
- セッションの生成、ページ遷移、ウィンドウ制御
- タグ要素の情報取得
- タグ要素の操作・スクリプトの実行(今ここ)
さて、WebDriverの仕様勉強の完結編。頑張っていきましょー。
前提条件
- 前回に引き続き、PowerShellプロンプトには以下の関数だけロードしている状態で検証を進めていきます。
- 元ネタはW3C WebDriver APIを参照しながら、ChromeDriverで進めていきます。
- コマンド単位でうまく動かないところがある場合は、Driverのバージョンを確認してみましょう。
# 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 }
前回のHTML要素の取得と同じく、この関数でelementIdが取得できてるか検証しながらやってきます。
Add-Type -AssemblyName System.Windows.Forms function Check-OnErrorStop($chk_res) { If($chk_res.status -ne 0){ $errmsg = "停止します。よろしいですか?`r`n" + $chk_res.value.message $ans = [System.Windows.Forms.MessageBox]::Show($errmsg,"要素の取得に失敗","YesNo","Exclamation","Button1") If($ans -eq "Yes"){ exit }Else{ return $false } }Else{ return $true } }
さっそく、使い方を見ていきましょう。
要素のクリック(Element Click)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/element/{elementId}/click
$body = @{using="xpath";value='//*[@id="lit_str"]'} $elm_uri = $uri + '/element' $rsp = Post-JsonContent $elm_uri $body If(Check-OnErrorStop($rsp)){ $elmId = $rsp.value.ELEMENT $body = @{} $elm_uri = $uri + '/element/' + $elmId + '/click' $rsp = Post-JsonContent $elm_uri $body }
動いた。要素が見切れていれば見える位置までスクロールしてクリックイベントを発生させてくれるらしい。
なんかいろいろ注意事項かいてある。
DOMでIE操作するのと違って、mouseOverとかmouseDownとかマウス操作関連のイベントを発生させてくれてるみたい。
ただ裏でクリック時の動作をキックしてるんじゃなくてマウスでクリックされたかの様にイベントを辿ってくれてる様だ。
それ故にイベント処理の競合が発生して動き変になる時あるかもよみたいなこと書いてあるぽぃ?
要素クリア(Element Clear)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/element/{elementId}/clear
$body = @{using="xpath";value='//*[@id="literal_str"]'} $elm_uri = $uri + '/element' $rsp = Post-JsonContent $elm_uri $body If(Check-OnErrorStop($rsp)){ $elmId = $rsp.value.ELEMENT $body = @{} $elm_uri = $uri + '/element/' + $elmId + '/clear' $rsp = Post-JsonContent $elm_uri $body }
んむ。普通にクリアできた。
これはinputかtextareaみたいな要素向けね。
入力フォームにキー入力(Element Send Keys)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/element/{elementId}/value
$body = @{using="xpath";value='//*[@id="literal_str"]'} $elm_uri = $uri + '/element' $rsp = Post-JsonContent $elm_uri $body If(Check-OnErrorStop($rsp)){ $elmId = $rsp.value.ELEMENT $val = "テスト入力、keyDownイベントもしっかり発生しているらしい。" $body = @{value=$val.ToCharArray()} $elm_uri = $uri + '/element/' + $elmId + '/value' $rsp = Post-JsonContent $elm_uri $body }
なるほど、valueプロパティで文字送るんだけど文字列でそのままぶっこむとこんなエラー出る。
status : 61
message : invalid argument: 'value' must be a list
valueは、リストでくれと。
なので、PowerShellだと文字列.ToCharArray()で配列にしてから渡してる。
なんか、普通のブラウザ操作のイメージだとすでに入力されている文字は上書きされて入力されるイメージだけど
WebDriverのブラウザ操作はあくまで開発テストとかが目的に立ち上がってるだけあって
キー入力の操作がトレースされる感じになってるんだって。
keyDownイベントもちゃんと発生する感じになってて、すでに入ってる文字の後ろに追記されたわ。
こっから、ドキュメント制御にはいってくよ。
ページソースの取得(Get Page Source)
リクエスト
(GET) http://localhost:9515/session/{sessionId}/source
$doc_uri = $uri + '/source' Invoke-RestMethod -Uri $doc_uri
valueに文字列で直接、ページの全ソースが返ってくる。
スクリプトの実行(Executing Script)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/execute/sync
# ただ純粋にスクリプトを実行する。 $body = @{script="alert('test');";args=@()} $elm_uri = $uri + '/execute/sync' $rsp = Post-JsonContent $elm_uri $body
よー説明わからんかったから、bodyを@{}でリクエスト送って
とりあえずエラーでなくなるまで補正した(笑)
message=invalid argument: 'script' must be a string
message=invalid argument: 'args' must be a list
scriptとargsというプロパティさえあれば動くようだ。
scriptは見ての通り、Javascriptを書けば実行される。
# 引数を取得する $body = @{script="alert(arguments[0]);";args=@("test")} $elm_uri = $uri + '/execute/sync' $rsp = Post-JsonContent $elm_uri $body
argsプロパティで渡した配列の引数は、argumentsっていう名前から取り出せるようだ。
固有のスクリプト作っといてパラメータ渡しで他所のサイトにゴニョゴニョ…した使い方ができるな!
# 戻り値を受け取る例 $body = @{script="return 'aaaa'";args=@()} $elm_uri = $uri + '/execute/sync' $rsp = Post-JsonContent $elm_uri $body
とりあえず、returnしとけばレスポンスのvalueに戻り値が取得できた。
$body = @{script="return {name:'aaaa',value:'bbbb'}";args=@()} $elm_uri = $uri + '/execute/sync' $rsp = Post-JsonContent $elm_uri $body
Jsonで戻り値返せば複数フィールドも受け取れた。
Send Keysは追記になる仕様だったし、確実にフォーム操作したいなら
スクリプト実行でquerySelectorAllして要素操作したほうが早くて確実かもー?
非同期のスクリプト実行(Execute Async Script)
リクエスト
(POST) http://localhost:9515/session/{sessionId}/execute/async
んーーーー。
制御方法がよくわからんな。
非同期の宣言ミスってるとプロンプト戻ってこなくなるし、
Promise制御がうまくハマらなかった。。。
もう少し試して、うまくいったらうまくいったコードで再更新しよう。。。
あとは、CookieとActionsの項なんですが・・・
有効利用する方法が思いつきません。。。(;^ω^)
Javascriptの実行ができるなら、大概できそうな気がしてしまいました。
Javascriptの流し込みでどこまでやれるのか、隙を見ていろいろ検証してきたいと思いまーす。
とりあえず、W3C WebDriver APIの勉強はこの辺にしときまーす。
「W3C WebDriver APIをPowerShell制御まとめ③」への3件のフィードバック