サイトアイコン わんすけに聞いてみる

W3C WebDriver APIをPowerShell制御まとめ③

続き、W3C WebDriver APIについてザザザーっと勉強しました。

さて、WebDriverの仕様勉強の完結編。頑張っていきましょー。

 

前提条件
# 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の勉強はこの辺にしときまーす。

モバイルバージョンを終了