Browserアクション
Browserアクションはchromedp を通して実際のChromeを操作します。ページを開き、内容を読み、入力し、要素を待ち、スクリーンショットを撮ります。Probeを実行する環境にChromeかChromiumが必要です。
外部アクションとしてmozership/probe-browser で公開しています。Probe v1.21.0までは組み込みアクションでした。ワークフローが初めて使うときにProbeがダウンロードし、固定したコミットのaction.ymlが示すSHA-256と一致する実行ファイルだけを実行します。Probe v1.21.0以降が必要です。各リリース のノートの先頭に、コピーして使うusesの行があります。
このアクションはページが何をするかを判定できないため、ガードを守りません。--read-onlyや--allow-hostの下では、--allow-actionで指定しない限り、このアクションを使うステップを拒否します。
基本的な構文
browserステップでは、行う操作をactionsに順番に並べます。ステップごとに新しいブラウザを起動し、操作を実行して閉じます。そのためクッキーやログイン状態は次のステップに引き継がれません。一連の流れは1つのステップにまとめます。
steps:
- name: Read the heading
uses: github.com/mozership/probe-browser@42dda412d5d183c091f8baf071237cc090f16052 # v0.1.0
with:
actions:
- name: navigate
url: "{{vars.url}}/"
- name: text
id: heading
selector: h1
test: res.code == 0 && res.results.heading == "Welcome"パラメータ
以下はwithの直下に書きます。
| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
actions | List | 必須 | 順に実行する操作。アクションを参照 |
timeout | 期間の文字列、または秒数 | 5s | ステップ全体の制限時間。ブラウザの起動とすべての操作を含む。30s、30、"30"はどれも30秒。それ以外の値や0以下の値はエラーになる |
headless | Boolean | true | ウィンドウを表示せずにChromeを動かす |
window_w | Integer | 1920 | ウィンドウの幅(ピクセル) |
window_h | Integer | 1080 | ウィンドウの高さ(ピクセル) |
evidence_dir | String | 一時ディレクトリ | 操作が失敗したときにページを保存する場所。失敗時のページを参照 |
Chromeの起動にもtimeoutの一部を使い、1秒以上かかることもよくあります。短すぎる制限では、最初のページを開く前に時間切れになることがあります。
アクション
actionsの各要素は、nameで操作を指定し、次のフィールドを取ります。
| フィールド | 使うアクション | 説明 |
|---|---|---|
name | すべて | 下の表にある操作の名前 |
id | 結果を返すアクション | res.resultsやres.filepathsで結果を引くキー。省くとアクション名がキーになるため、同じ種類のアクションを後に置くと前の結果を置き換える |
url | navigate | 開くアドレス |
selector | 要素に対するアクション | CSSセレクタ |
value | type、send_keys、select | 使うテキスト |
attribute | get_attribute | 読む属性をhrefか[href]で指定する。リストの場合は最初の要素だけを読む |
quality | full_screenshot | 1から99はその品質のJPEGで保存する。それ以外は、省略、0、100以上、負の数も含めてPNGで保存する |
path | スクリーンショット | 非推奨。画像をこのパスにも書き出す。代わりにres.filepathsを使う |
要素を探すアクションは、要素が現れるまで待ちます。先にtimeoutが尽きるとステップは失敗します。多くは要素が表示されるまでも待ちます。
移動と待機
ページを開くか、次の操作に必要な状態になるまでステップを待たせます。
| アクション | 内容 |
|---|---|
navigate | urlを開き、ページの読み込みを待つ。net::ERR_CONNECTION_REFUSEDのようにブラウザがネットワークのエラーを返すとすぐに失敗する。応答のないアドレスではtimeoutまで待つ |
wait_visible | selectorが表示されるまで待つ |
wait_not_visible | selectorが表示されなくなるまで待つ |
wait_enabled | selectorが表示され、有効になるまで待つ |
wait_ready | ページのbodyの準備ができるまで待つ。selectorは使わない |
ページの読み取り
以下は文字列をres.resultsに、idまたはアクション名をキーにして入れます。
| アクション | 結果 |
|---|---|
text | selectorのテキスト |
wait_text | selectorが表示されるまで待ち、そのテキスト |
value | inputなどのフォーム項目の値 |
get_attribute | selectorの、attributeの最初の属性の値。要素がその属性を持たなければ空文字列 |
get_html | 表示されたselectorの外側のHTML |
操作
利用者と同じようにページを操作します。結果は返しません。
| アクション | 内容 |
|---|---|
click | 表示されたselectorをクリックする |
double_click | 表示されたselectorをダブルクリックする |
type、send_keys | selectorの内容を消してからvalueを入力する |
submit | selectorが属するフォームを送信する |
focus | selectorにフォーカスを移す |
scroll | selectorが見える位置までスクロールする |
select | selectorのvalue属性をvalueに設定する。<select>の選択肢は選ばないため、選ぶ場合は選択肢をクリックする |
hover | selectorにmouseoverイベントを送る。待たず、一致する要素がなければ何もしない |
right_click | selectorにcontextmenuイベントを送る。待たず、一致する要素がなければ何もしない |
スクリーンショット
以下は画像をファイルに保存し、そのパスをres.filepathsに、idまたはアクション名をキーにして入れます。ファイル名の拡張子は形式に合わせて.pngか.jpgになります。
| アクション | 画像 |
|---|---|
capture_screenshot | ウィンドウに見えている範囲。PNG |
full_screenshot | ページ全体。PNG。qualityが1から99ならJPEG |
screenshot | 表示されたselectorだけ。PNG |
レスポンスオブジェクト
すべての操作が成功すると、ステップからは次の値を参照できます。
| フィールド | 型 | 説明 |
|---|---|---|
res.code | Integer | 0 |
res.results | Object | 読み取りのアクションが返した値。キーはidまたはアクション名 |
res.filepaths | Object | スクリーンショットの保存先。キーはidまたはアクション名 |
rt.duration | String | ステップにかかった時間。"663.268333ms"など |
status | Integer | 0 |
操作が失敗した場合は、テストできるレスポンスはありません。ステップはエラーハンドリングのとおりアクションのエラーとして失敗します。
例
どの例も1つのステップです。1つのステップの操作は同じブラウザを共有し、次のステップは新しいブラウザで始まるためです。
ログイン
ログインと、それが成功したことの確認は同じブラウザで行う必要があるため、1つのステップにします。
secrets:
- PASSWORD
vars:
url: "{{APP_URL}}"
user: "{{USERNAME}}"
password: "{{PASSWORD}}"
jobs:
- name: Sign in
steps:
- name: Log in and reach the dashboard
uses: github.com/mozership/probe-browser@42dda412d5d183c091f8baf071237cc090f16052 # v0.1.0
with:
timeout: 30s
actions:
- name: navigate
url: "{{vars.url}}/login"
- name: type
selector: "#username"
value: "{{vars.user}}"
- name: type
selector: "#password"
value: "{{vars.password}}"
- name: click
selector: "button[type='submit']"
- name: wait_visible
selector: "#dashboard"
- name: text
id: greeting
selector: "#dashboard h1"
test: res.code == 0 && res.results.greeting contains vars.user複数の値の読み取り
結果が互いに置き換わらないよう、読み取りのアクションにはそれぞれidを付けます。
- name: Product page
uses: github.com/mozership/probe-browser@42dda412d5d183c091f8baf071237cc090f16052 # v0.1.0
with:
actions:
- name: navigate
url: "{{vars.url}}/products/42"
- name: text
id: title
selector: "h1"
- name: text
id: price
selector: ".price"
- name: get_attribute
id: image
selector: "img.product"
attribute: [src]
test: |
res.code == 0 &&
res.results.title != "" &&
res.results.price startsWith "$"
outputs:
image_url: res.results.imageスクリーンショットを残す
保存した画像のパスはres.filepathsに入り、表示したり次に渡したりできます。
- name: Checkout page
uses: github.com/mozership/probe-browser@42dda412d5d183c091f8baf071237cc090f16052 # v0.1.0
with:
window_w: 1280
window_h: 800
actions:
- name: navigate
url: "{{vars.url}}/checkout"
- name: full_screenshot
id: page
test: res.code == 0
echo: "Saved {{res.filepaths.page}}"エラーハンドリング
アクションが完了できないと、ステップ全体がアクションのエラーとして失敗し、実行は終了ステータス3で終わります。セレクタが何にも一致しなくても空の結果にはなりません。wait_visible、text、clickなど要素を探すアクションは、ステップのtimeoutまで待ち続けます。ナビゲーションは、接続の拒否のようにブラウザがネットワークのエラーを返すとすぐに失敗しますが、応答のないアドレスではtimeoutまで待ちます。いずれの場合もテストできるresはなく、失敗のメッセージにブラウザのエラーが入ります。
失敗時のページ
アクションが失敗すると、Probeはその時点のページを保存します。ページ全体のPNGのスクリーンショットと、文書のHTMLです。2つのファイルはprobe-browser-failure-1947177907.pngと.htmlのように同じ名前を共有します。失敗のメッセージには、ページのURLとあわせて両方のファイルのパスが入ります。
action error in step_execute: action execution failed (caused by: ... context deadline exceeded (page at failure: url http://localhost:8090/, screenshot /tmp/probe-browser-failure-1947177907.png, html /tmp/probe-browser-failure-1947177907.html))--reportで書き出すファイルでも、このメッセージが失敗のmessageになります。テストがfalseになるのはアクションの失敗ではないため、そのときはページを保存しません。残したい場合はcapture_screenshotアクションを加えます。
ファイルはシステムの一時ディレクトリに保存します。evidence_dirを指定するとそこに保存し、ディレクトリは必要に応じて作成します。CIのアーティファクトとしてアップロードする場合に便利です。ページには個人の情報が写りうるため、ファイルはProbeを実行したユーザーだけが読めるようにします。
- name: Checkout page
uses: github.com/mozership/probe-browser@42dda412d5d183c091f8baf071237cc090f16052 # v0.1.0
with:
evidence_dir: out/browser
actions:
- name: navigate
url: "{{vars.url}}/checkout"
- name: wait_visible
selector: "#pay"ページを読み取れるように、ブラウザはタイムアウトのあとも最大10秒残します。ブラウザが起動しなかった場合や、時間切れの時点でページがまだ読み込み中だった場合など、読み取れなかったときはその旨をメッセージに書き、何も保存しません。
CIでの実行
CIのランナーには、ブラウザと、手元より少し長い時間が必要です。
- ランナーにChromeかChromiumを入れる。
headless: trueのままにするか、ウィンドウが必要ならXvfbなどのディスプレイを用意する。- コンテナで多く必要になるため、Chromeは
--no-sandboxで起動する。信頼できるサイトだけを開く。 - コールドスタートのランナーではChromeの起動が遅いため、
timeoutに余裕を持たせる。