JSスクリプトを使ってUI自動化を実現してみよう

## はじめに
突然ですが、下図のサイトに対してRPAで情報を入力してサブミットするためにはいくつのアクティビティが必要になると思いますか？

通常、UI操作するための「ブラウザを使用」が1つ、情報を入力するための「文字を入力」5つ、そしてサブミットするための「クリック」が1つ、合わせて7つが必要だと考える方が多いでしょう。しかし、本日は、たった2つのアクティビティだけで実現させようと思います。その秘訣は「JSスクリプトを挿入」アクティビティです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334103/a7531915-a5b9-9dae-f0e3-b32727101c97.png)

## 「JSスクリプトを挿入」とは？
そもそもJavaScriptとは何かという疑問を持つ方がいるかもしれません。それは、簡単に言うと、ブラウザを動かすために、使われている主流のプログラム言語です。ウエブサイト訪問の際に、ボタンを押すとほかの画面に遷移するという動きを誰でも見たことがあると思いますが、あのブラウザが動けるように、指示を出すのがJavaScriptなのです。「JSスクリプトを挿入」というのは、UiElementに対応するWebページのコンテキストでJavaScriptコードを実行するという意味のアクティビティです。

まだJavaScriptに詳しくない方は、15分学べるJavaScriptの記事があるため、軽くご覧いただければ今日のやることは何なのかより簡単に理解できると思います。

https://qiita.com/Miyate2/items/28352f370913d79a4580

## 「JSスクリプトを挿入」の優れたところは？
上記のように、複数のアクティビティを一つ集約できるメリット以外、「JSスクリプトを挿入」を使う理由として、処理の速さと安定性などが挙げられます。

①処理の速さ：「文字を入力」や「クリック」といったRPA操作で、一個一個の項目に入力してクリックするという手の動きのような過程が目の前に呈するため、特に繰り返し処理の際に、スピードが遅いです。それに対して、「JSスクリプトを挿入」はバックグラウンドで操作するので、一瞬で終わるのです。そのため、処理効率からみれば、「JSスクリプトを挿入」が圧倒的に早いです。

②処理の安定性：ネットワーク状況や端末のパフォーマンスなどによって、人の動きを真似したRPAのUI操作はたまにミスが発生したりします。それに対して、バックグラウンドで動いてくれるJSスクリプトのほうは安定性がより高いといえます。

## 環境の準備
今回は以下の環境でデモを作成していきます。
| 項目 | バージョン |
|:-----------|------------:|
| UiPath Studio| 2024.10.1        |
| UiPath.UiAutomation.Activities     | 24.10.0      |
| Chrome     | 127.0.6533.100      |

なお、デモサイトには Restful Booker Platform （ページ最下部）を使用します。ゴールは「JSスクリプトを挿入」アクティビティを使って、下図5つのインプットボックスに情報を入力してサブミットすることです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334103/e77a0e10-04d6-d102-3946-cca4e5e0b301.png)


## Chrome開発者ツールでUI要素の中身を確認する
Chrome開発者ツールはChromeに搭載されている検証ツールであり、ブラウザを起動し、F12を押下すると出てきます。ツールにたくさんの機能がありますが、今回は簡単にElementパネルとConsoleパネルの使い方を紹介します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334103/25240e4d-f296-266b-e9a2-47d58bd50d63.png)

まず、Elementsパネルは、簡単に言うとUI要素の検証に使われるものだと認識していただければと思います。そこで、ウェブページで上のUI要素の中身が確認できます。確認の方法は以下のようです。

①Elementタブ左の矢印アイコンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334103/2ae7560d-d078-ee04-ac8d-45fe76db6f1b.png)

②ウェブページ画面の要素にホバーすると、要素の中身がハイライトで表示されます。赤枠のところは要素の中身（HTMLで記述されているものです）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334103/90dc8b8a-de7d-ce00-c914-947cf19d7097.png)

今回はまさにこれらの要素の情報を活用して、JSスクリプトを実行してみようと思います。拡大すると、こうなりますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334103/65cf1726-ca0f-4217-1678-2a597233262a.png)

中には、**id="name"** というコードがあります。それは、UI要素の一意識別子です。**id="name"** で指定された要素は、ページ内で一つしか存在していないのです。そのため、**id="name"** さえあれば、Nameというインプットボックスが特定できますし、それに対する操作も可能となります。

次に、どのように要素を操作するかを説明していきます。Elementsパネル下のConsoleパネルでJSスクリプトを打つと、要素を動かすことができるようになります。操作方法はDOM（Document Object Model）です。DOMに関する内容は上記添付した記事で詳細に説明されているため、詳しい話を省きますが、ここで今回使う**getElementById** というメソッドだけを紹介します。

**getElementById** はJSスクリプトで特定のIDを持つUI要素を取得するためのメソッドです。**document.getElementById('要素ID')** を使うことで、要素にアクセスしてその内容を変更することができます。例えば、Nameのインプットボックスに **James** を入力しようとする場合、

```ruby:名前を入力する
document.getElementById('name').value = 'James'
```
上記のコードをConsoleパネルに入力してEnterを押せば、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334103/631b9b9c-45fd-b1ea-bf50-96e9757a858f.png)

インプットボックスの値は**James** となりました。

しかし、**Submit** ボタンに対しては、値の入力ではなく、クリック操作のが目標ですね。この場合、**.click()** メソッドを使えばいいです。

```ruby:Submitボタンをクリックする
document.getElementById('submitContact').click()
```
ほかのインプットボックスの入力方法は同じなので、まとめると、コードはこうなります。

```ruby:まとめるコード
document.getElementById('name').value = 'James';
document.getElementById('email').value='James@test.com';
document.getElementById('phone').value='13600123456789';
document.getElementById('subject').value='I want to book this room';
document.getElementById('description').value='This is a room booking test';
document.getElementById('submitContact').click()
```

では、実行してみましょう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334103/6fdf5320-20e9-6cea-f9e4-96f9b3d2838c.png)

あら、エラーがでました。インプットボックスが入力されているにもかかわらず、下に「空白にしてはいけない」という警告がでていますし、Consoleパネルにも400のステータスコードが返ってきました。これはなぜなのでしょうか。

この問題の原因は、document.getElementById で入力フィールドに値を設定しましたが、ブラウザがそれらの動作を検知できなかったからです。値を入力するだけでなく、ちゃんとブラウザに「値を入力したよ」というメッセージを届けなければいけません。それを実現するため、手動トリガーを設定して、「入力した」というイベントをブラウザに通知する必要があります。方法は以下です。

```ruby:トリガーの設定
//インプットイベントの設定
var event = new Event('input',{bubbles:true});

//手動でインプットイベントをトリガーする
UiElement.dispatchEvent(event);
```
これで、UI要素に対する操作は2つのパーツとなっています。まずは、値を設定すること、次に、トリガーを設定すること。コードを簡潔にするため、UI要素を変数にしたほうがいいと思いますので、整理すると、以下のようになりましたね。

```ruby:まとめたコード
//UiElementの定義と値の設定
 var inName=document.getElementById('name');
 inName.value='James';
 var inEmail=document.getElementById('email');
 inEmail.value='James@test.com';
 var inPhone=document.getElementById('phone');
 inPhone.value='13600123456789';
 var inSub=document.getElementById('subject');
 inSub.value='I want to book this room';
 var inDes=document.getElementById('description');
 inDes.value='This is a room booking test';

//各UiElementにトリガーを設定
 var event = new Event('input',{bubbles:true});
 inName.dispatchEvent(event);
 inEmail.dispatchEvent(event);
 inPhone.dispatchEvent(event);
 inSub.dispatchEvent(event);
 inDes.dispatchEvent(event);

 //Submitをクリック
 document.getElementById('submitContact').click()
```

## 「JSスクリプトを挿入」でコードを実行する
これから、上記のコードを「JSスクリプトを挿入」で動かしてみましょう。

①モダンアクティビティの「JSスクリプトを挿入」を利用するので、「ブラウザを使用」の中に配置する必要があります。（すでにウェブページを指定済みです）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334103/ad4e7b76-3074-6893-9926-bff215a16052.png)

②上図のスクリプトコードを開くと、式エディターが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334103/77771a80-84e0-8950-fae8-12a4e4ad9705.png)

③先ほど書いたコードを式エディターの { } に入れます。今回は特にパラメータを使用しないため、**function()** 中のelementとinputを削除しましょう。するとこのようになりますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334103/453b4d85-4b8a-ad17-86c4-6bd187e35382.png)

④式を保存してワークフローを実行してみたら、今回はエラーがでず、インプットボックスに値が一気に入力されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334103/5eea5005-d6f9-1644-1885-12e8f1ffba50.png)

そして、その瞬間Submitボタンが正しくクリックされ、送信結果がきました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334103/c68c6520-418e-5646-f2bf-ea9369497eb6.png)

## まとめ
今回は、

①Chrome開発者ツールの基本的な使い方

②JavaScriptの概念と簡単なコードの書き方

③「JSスクリプトを挿入」を用いた早くて安定した操作方法によるUI自動化の実現方法

以上三つを紹介しました。ぜひ試してみてください！

## 関連URL
https://docs.uipath.com/ja/activities/other/latest/ui-automation/inject-js-script

https://qiita.com/Miyate2/items/28352f370913d79a4580

https://automationintesting.online/