プログラマがPower Automate for Desktopを使う(3)実行時にURLが決まり同一タイトルの複数タブが出る動的サイトの扱い方

※この記事は [プログラマがPower Automate for Desktopを使う](https://qiita.com/jzephyr/items/3ba3b02bfdb3d6a32442) シリーズの一つです。
# 実行時にURLが決まり同一タイトルの複数タブが出るサイトの扱い方
Web操作で「URLが実行時に決まる」「 同じタイトルの複数のタブが出る」「ページ内の要素のクリックで表示内容が変わる」という特徴を持つサイトを扱う際に、アクションの選択とパラメタの指定で留意すべき点を述べます。また、タブ外のブラウザ操作にも触れます。

## タブに接続する方法
### タブ接続に使うアクション
タブに接続するには、**新しいChromeを起動する**アクションの**実行中のインスタンスに接続する**起動モードを使い**Chromeタブに接続する**オプションを指定します。接続方法は3つあります。
* **タイトルを使用**
アクションには**タブのタイトル**パラメタがあり、フロー作成時にフロー作成者が指定した「タイトル名パタン(造語)」を保持します。フロー実行時には、そのパタンにマッチするタイトル名を持つタブに接続します。
~~~
［実験結果］
同一タイトルのタブが複数ある場合には、最初に見つかったタブが選ばれます。
~~~
* **URLを使用**
アクションには**タブのURL**パラメタがあり、フロー作成時にフロー作成者が指定した「URLパタン(造語)」を保持します。フロー実行時には、そのパタンにマッチするURLのページを表示中のタブに接続します。実行時にURLが決まるシナリオでは、URLパタンの変化する部分を取り除く編集が必要です。
* **フォアグラウンド ウィンドウを使用**
アクションには接続先を明示するパラメタが無く、タブを特定するために何の情報を使うかは分かりませんでした。なお「フォアグラウンド」は「フロー実行時ではなくフロー作成時にフォアグラウンド」という意味なので注意が必要です。
~~~
［実験結果］
手動で起動したタブとの接続は失敗します。フローが起動したタブとの接続は成功します。
実行時にURLが決まるシナリオでは必ず接続に失敗します。
ブラウザ変数を使ってタブを閉じると、フロー実行時にはバックグラウンドにあっても、そのタブが消えます。
~~~

私は**URLを使用**する方法を採用し、URLパタンを編集してフローを作りました。

なお、**レコーダー**で自動的に挿入される**新しいChromeを起動する**アクションの接続方法は**URLを使用**方式です。

### タブ名とURLのパタンについて
[公式ドキュメント](https://learn.microsoft.com/ja-jp/power-automate/desktop-flows/actions-reference/webautomation#launchchromebase)によると「説明設定」に
>接続先の Chrome タブのタイトル (またはその一部) を入力します
>接続先の Chrome タブの URL (またはその一部) を入力します

とあります。この「(またはその一部)」 がどういう意味か実験で確認しました。
* タイトル名の場合、フロー実行時に表示されているタブのうち、タイトル名がそのパタンを含むタブがマッチします。
* URLの場合、フロー実行時に表示されているタブのうち、URLがそのパタンを含むページを表示中のタブがマッチします。

マッチの詳細については次の通りです。
* （含むの意味は）パタンが先頭でも、途中でも、末尾でもマッチが成立します。
* 「\*」はワイルドカード文字ではないです。
* 「.*」などの正規表現は使えません。
* 「%変数名%」を使えます。

## タブを閉じる方法
表示中のタブを閉じる手段を挙げます。
* **Webページのリンクをクリック**アクション
この手段は、タブに表示中のページ内に「タブを閉じる」意味のリンクがある場合に使えます。なお、アクションのオプションでリンク先の画面を待機しないように指定する必要があります。さもないと、実行時にタイムアウトエラーになります。
* **Webブラウザーを閉じる**アクション
この手段では、ブラウザ変数で閉じるべきタブを指定します。
* **キーの送信**アクション
この手段では、フォアグラウンドなウィンドウに{Ctrl}{W}キーを送ることで、結果としてブラウザのフォアグラウンドなタブを閉じます。
アクションには次のパラメタを指定します。
　　キーの送信先:フォアグラウンドウィンドウ
　　送信するテキスト:{LControlKey}(w)
自然な操作の模倣だとは思いますが、タブを明示しない点が少し心配です。

私は一つのタブを閉じるために二つのアクションを使いました。
* **Webページのリンクをクリック**アクション
…対話型のページで、タブから去る意図をページに知らせるため
* **Webブラウザーを閉じる**アクション
…専ら表示されるのみのページで、ブラウザからタブを消すため

使い分けをしたのは、「閉じる」意味のリンクのクリックしてもタブが消えないケースがあったためです。

## リンクを操作する方法
リンクはクリックすると画面遷移を引き起こすUI要素です。画面遷移の結果、タブ内のページが変わる場合もあるし、新しいタブがポップアップする場合もあるし、タブが消える場合もあります。
リンクを操作するには**Webページのリンクをクリック**アクションを使います。

リンクの結果がタブを閉じる場合は、オプションでリンク先の画面を待機しないように指定する必要があります。さもないと、実行時にタイムアウトエラーになります。

**レコーダー**でリンクの操作を記録できます。
記録で**新しいChromeを起動する**アクション が挿入される場合があり、その結果2つのブラウザ変数が同一ページを指すことが生じる場合があります。

## 操作対象を待機する方法
操作対象または見たい内容があるUI要素の表示を待機するには**Webページのコンテンツを待機**アクションを使用します。
次の場合に待機が必要な可能性があります。
* ページが大きくて（スクロールをするまで）全部は表示されない。
* （インナーフレーム等の）ページのHTML外の要素が取得されるまで表示されない。
* ページ内をクリックすると表示内容が変わるページ。（タブ風、プルダウンメニュー風など）

## ブラウザのタブ外の操作を扱う方法
ブラウザのタブ内に表示されているページが対象の操作では**ブラウザ自動化**グループの**Webフォーム入力**にあるアクションを使いますが、タブ外の対象の操作では**UIオートメーション**グループの**フォーム入力**にあるアクションを使います。

### タブ外操作に使うアクション
私が使用したアクションを挙げます。
* **ウィンドウ内のメニューオプションを選択**アクション
拡張機能のアイコンをクリックする際に使用しました。
* **ウィンドウのUI要素をクリック**アクション
拡張機能がポップアップした画面内のUI要素をクリックする際に使用しました。
* **ウィンドウ内のボタンを押す**アクション
拡張機能が出したWindowsの「名前をつけて保存」ダイアログのボタンをクリックする際に使いました。

参照先：[UI要素ペインの中身](https://qiita.com/jzephyr/private/8d7344cac40104d13295#ui要素ペインの中身) 

<a id="タブ外操作ステップの作り方"></a>
### タブ外操作ステップの作り方
タブ外の要素を操作するアクションについては、**レコーダー**での記録が便利です。

私のシナリオには次の場面があります。
* 拡張機能がポップアップした画面の対象を選ぶ
* 拡張機能が出したダイアログのボタンをクリックする

手動でステップを作る場合は、操作対象をUI要素ペインに追加する際に**UI要素ピッカー**で操作対象を選ぶのですが、ポップアップして出る要素を選ぶ際には、次の煩雑な手順になります。
1. 操作対象画面をフォワードにし、拡張機能アイコンをクリックする前の状態まで操作しておく。
1. **フローデザイナー**をフォワードにして**UI要素ピッカー**を出す。
1. **UI要素ピッカー**を出したまま、拡張機能アイコンをCtrlキーなしでクリックする。
1. **UI要素ピッカー**を出したまま、ポップアップして出た要素要素をCtrlキーありでクリックする。

 [シリーズの記事一覧へ](https://qiita.com/jzephyr/items/3ba3b02bfdb3d6a32442#シリーズの記事一覧)