Chrome + KatalonRecorder + vscode + Katalium でUIテストの自動化を体験してみた

# なんでやってみたのか
業務で、同一ファイルの複数回ダウンロードを検証する必要が発生した。
簡単な準備で検証できないかと考え、UIテスト自動化ツールが使えないかと考えた。
KatalonRecorderを以前に聞いたことがあったので、試してみた。

# サマリ
KatalonRecorderとVSCodeのExtensionを組み合わせることで、複数回のファイルダウンロードのテストは実現できた。
※Extensionのサンプルプロジェクトと、その中のWebDriver（Chrome）を利用。

- KatalonRecorderで1回ダウンロードをRecorde
- KatalonRecorderでRecordeしたシナリオをJavaでExport
- VSCodeの公式Extensionを利用し、ExportしたJavaをサンプルプロジェクトに取り込み
- ファイルダウンロードを待つためにSleepを追加
- 繰り返し処理を追加

# 動作確認環境
- macOS Catalina 10.15
- java 1.8.0_202
- nginx 1.13.10
- chrome （2019年10月上旬の最新版）
    - Katalon Recorder (Selenium tests generator) 3.9.2
        - [chrome web store: Katalon Recorder](https://chrome.google.com/webstore/detail/katalon-recorder-selenium/ljdobmomdgdljniojadhoplhkpialdid?utm_source=chrome-ntp-icon)
- vscode 
    - Extension: Katalium - Selenium and TestNG made easy
        - [Marketplace: katalon-llc.katalium](https://marketplace.visualstudio.com/items?itemName=katalon-llc.katalium)
    - Extension: Java Extension Pack
        - [Marketplace: vscjava.vscode-java-pack](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack)


# やりたいこと
下記のような画面にて、画像をクリックするとテキストファイルがダウンロードされます。
そのダウンロードを複数回（1,000回）実行して、下記の動作の確認がしたい。

- 想定回数のダンロードが完了するのか
- ダウンロードされたファイルのファイル名がどのようになるのか

#### テスト画面の画面イメージ
![localhost_8081_o310yusuke-test.html.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237003/c34c9c51-0d89-c949-80c6-217b3139120f.png)

#### テスト画面のHTML
```html:o310yusuke-test.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>o310yusuke-test</title>
</head>
<body>
    <h1>o310yusuke-test</h1>
    <div id="test0" onclick="console.log('div clicked!');">
        <a href="data/test.yusuke">
            <img src="img/100125-114814.jpg" height="100" onClick="console.log('img clicked!!!!');" />
        </a>
    </div>
</body>
</html>
```


# やったこと・ハマったこと・脱出するためにやったこと
**注意** 各ツールのインストールやアクティベーションの方法は割愛させていただきます。

## まずは、KatalonRecorderでRecordを。
![スクリーンショット 2019-11-02 12.04.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237003/d3a2d76e-2d0e-3728-2f5e-1f7ee68e7e4d.png)

Recordした操作の中から、ダウンロードの処理をループ化する。
（赤矢印部分を追加）
![スクリーンショット 2019-11-02 12.08.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237003/d6c62927-3882-d855-dff1-60df010d6da2.png)

- ダウンロード処理の前に変数を設定
    - Command: store
    - Target: 0
    - Value: count
- ダウンロード処理の前でループの条件を記載
    - Command: while
    - Target: $(count)<2
    - Value: 空欄
- カウント数を更新
    - Command: storeEval
    - Target: $(count)+1
    - Value: count
- ループの終了を記述 
    - Command: endWhile
    - Target: 空欄
    - Value: 空欄

Play！
・・・
あれ？？
・・・・・・
上記ループを追加しない状態ではダウンロードされるが、ループを追加すると動かない。。。
Chomeのダウンロード前に保存場所を確認しないようにはしている。。。
原因はなんだ？！
調べてみたが、原因の特定には至らず。。。

## KatalonStudioではできるのか、試してみるか。。。
### KatalonStudioをMacにインストール
KatalonStudioをダウンロードして、Applicationに移動させて、さて、実行！！
・・・
あれ？？
・・・・・・
起動エラーが出る。。。（内容は忘れました）

うん、他の方法を探してみよう、ということで、VSCodeに公式Extensionがあるとわかったので、導入！

### VSCodeに公式Extensionを導入してみる。
下記の公式サイト見ながら、サンプルプロジェクトが動作することは確認できた。
[Get Started with Katalium Framework in Visual Studio Code](https://docs.katalon.com/katalium-framework/docs/katalium-framework-get-started-vscode.html)

### 先程RecordしたテストシナリオをVSCodeの公式Extensionを使って動くか試してみる。
KatalonRecorderの「Export」ボタンをクリックして、フォーマットをExtensionに合わせて「Java (WebDriver + TestNG)」でExport。

![スクリーンショット 2019-11-02 15.36.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237003/4299c6c3-acb8-156f-44e3-b333e5e608fc.png)

パッケージ名とかクラス名は適宜修正し、Katalonのサンプルプロジェクトに取り込むと下記のような感じに。
今回は、「jp.o310yusuke.qiita.testcase.TestCase.java」とした。

![スクリーンショット 2019-11-02 15.39.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237003/23c67323-eaf8-27b5-8108-1530eb47a756.png)

このままではImportしたテストシナリオが動かないので、修正する。

- FirefoxDriverではなく、サンプルで準備しているDriverを使うようにする
    - TestTemplateを継承する
    - TestTemplateのWebDriverを利用するようにprivate変数のWebDriverをコメントアウトする
    - 同様に、setUp()もコメントアウトする

```java:jp.o310yusuke.qiita.testcase.TestCase
public class TestCase extends TestTemplate {
  // private WebDriver driver;
  private String baseUrl;
  private boolean acceptNextAlert = true;
  private StringBuffer verificationErrors = new StringBuffer();

  // @BeforeClass(alwaysRun = true)
  // public void setUp() throws Exception {
  //   driver = new FirefoxDriver();
  //   baseUrl = "https://www.katalon.com/";
  //   driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
  // }
```

- インポートしたテストクラスをテスト対象に登録する
    - テスト名「simple」と「parameterize」をコメントアウト
    - インポートしたクラスを登録

```xml:/src/test/resources/testng.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >

<suite name="Suite1" verbose="1" >
    <!-- <test name="simple" >
        <parameter name="kataDisableScreenshot" value="false" />
        <classes>
            <class name="com.katalon.kata.sample.testcase.simple.MakeAppointmentTest" />
        </classes>
    </test>

    <test name="parameterize" >
        <parameter name="kataDisableScreenshot" value="true" />
        <parameter name="facility" value="Hongkong CURA Healthcare Center" />
        <parameter name="visitDate" value="27/12/2016" />
        <parameter name="comment" value="Please make appointment as soon as possible." />
        <classes>
            <class name="com.katalon.kata.sample.testcase.parameterize.ParameterizedMakeAppointmentTest" />
        </classes>
    </test> -->

    <test name="qiitaTest">
        <classes>
            <class name="jp.o310yusuke.qiita.testcase.TestCase" />
        </classes>
    </test>
</suite>
```

- コンソールで下記を実行して、実行を確認する（繰り返し処理はコメントアウト状態）
    - このままでは、ダウンロード完了前にWebDriverを閉じてしまうので、実際にはDLされず。。。


```bash
mvn clean test
```

- ダウンロードするようにSleepを追加

```java:jp.o310yusuke.qiita.testcase.TestCase
  @Test
  public void testTestCase() throws Exception {
    driver.get("http://localhost:8081/o310yusuke-test.html");
    String count = "0";
    // ERROR: Caught exception [ERROR: Unsupported command [while | $(count)<2 | ]]
    driver.findElement(By.xpath("(.//*[normalize-space(text()) and normalize-space(.)='o310yusuke-test'])[2]/following::img[1]")).click();
    // ダウンロードが完了するのを待つためにSleep
    try {
      Thread.sleep(2000);
    } catch (Exception e) {
      e.printStackTrace();
    }
    // ERROR: Caught exception [ERROR: Unsupported command [getEval | $(count)+1 | ]]
    // ERROR: Caught exception [ERROR: Unsupported command [endWhile |  | ]]
  }
```

- 繰り返しを実装（不要な実装は削除）

```java:jp.o310yusuke.qiita.testcase.TestCase
  @Test
  public void testTestCase() throws Exception {
    driver.get("http://localhost:8081/o310yusuke-test.html");
    int count = 0;
    while (count < 2) {
      driver.findElement(By.xpath("(.//*[normalize-space(text()) and normalize-space(.)='o310yusuke-test'])[2]/following::img[1]")).click();
      // ダウンロードが完了するのを待つためにSleep
      try {
        Thread.sleep(2000);
      } catch (Exception e) {
        e.printStackTrace();
      }
      count++;
    }
  }
```

- 完成！！！