Selenide + Allureでクリック毎にスクリーンショットを取得して、テストレポートに添付する

# やりたいこと

[Selenide](https://selenide.org/)のテスト結果を[Allure](http://allure.qatools.ru/)のテストレポートとして表示させる時に、Selenideでの要素クリック前後のブラウザ画面のスクリーンショットを添付します。

# 環境
- macOS Catalina
- Maven 3.6.3
- JDK 1.8.0_181

# 下準備
本記事のベースには、[Selenideのドキュメント](https://selenide.org/documentation/reports.html#allure-report)で紹介されているGitHubにあるサンプルプロジェクト[ selenide-examples/selenide-allure-junit ](https://github.com/selenide-examples/selenide-allure-junit)を利用します。
なお、本記事作成時点のSelenideとAllureは、`pom.xml`で次のバージョンが指定されていました。

- Selenide: 5.18.1
- Allure: 2.13.8

まずは、これを適当な場所にダウンロードして動作することを確認します。
READMEに従って、テストを実行し、生成されたレポートがブラウザ上で見られること確認しておきます。

```console
$ curl -L -o selenide-allure-junit-master.zip https://github.com/selenide-examples/selenide-allure-junit/archive/refs/heads/master.zip
$ unzip -q selenide-allure-junit-master.zip
$ cd selenide-allure-junit-master
$ mvn clean test
$ mvn allure:serve
```

# クリック前後のスクリーンショット取得
`src/test/java/org/selenide/examples/`に、`ScreenshotTest.java`というクラスを作成します。
コード全体は下記です。

```java:ScreenshotTest.java
package org.selenide.examples;

import com.codeborne.selenide.junit.TextReport;
import com.codeborne.selenide.logevents.SelenideLogger;
import com.codeborne.selenide.*;
import io.qameta.allure.Attachment;
import io.qameta.allure.selenide.AllureSelenide;
import org.junit.*;
import org.openqa.selenium.*;
import org.openqa.selenium.support.events.AbstractWebDriverEventListener;

import static com.codeborne.selenide.Condition.*;
import static com.codeborne.selenide.Selenide.*;
import static com.codeborne.selenide.Selectors.*;

public class ScreenshotTest {
  @Rule
  public TextReport report = new TextReport();

  @BeforeClass
  public static void setUp() {
    SelenideLogger.addListener("AllureSelenide", new AllureSelenide().screenshots(true).savePageSource(true));
    // 匿名クラスを使って実装したイベント補足クラスのインスタンスを登録
    WebDriverRunner.addListener(new AbstractWebDriverEventListener() {
      @Override
      //要素をクリックする直前の処理
      public void beforeClickOn(WebElement element, WebDriver driver){
        screenshot();
        System.out.println("beforeClickOn:" + driver.getCurrentUrl());
      }
      @Override
      //要素をクリックした直後の処理
      public void afterClickOn(WebElement element, WebDriver driver){
        screenshot();
        System.out.println("afterClickOn:" + driver.getCurrentUrl());
      }
      @Attachment(type = "image/png")
      // スクリーンショットを取得
      public byte[] screenshot() {
        return Selenide.screenshot(OutputType.BYTES);
      }
    });
  }

  @Test
  public void searchSelenideTest() {
    open("https://www.google.co.jp/");
    $(By.name("q")).val("Selenide").pressEnter();
    $(byText("Selenide: concise UI tests in Java")).click();
    $(byText("Blog")).click();
  }
}
```

- [WebDriverRunner.addListener()](https://selenide.org/javadoc/current/com/codeborne/selenide/WebDriverRunner.html#addListener-org.openqa.selenium.support.events.WebDriverEventListener-)にイベント補足クラスである`AbstractWebDriverEventListener`クラスを匿名クラスを利用して実装したものを登録しています。  
　参考: [イベント処理について](https://www.seleniumqref.com/api/java/about/About_event.html)
- `beforeClickOn()`と`afterClickOn()`メソッドにそれぞれ要素のクリック直前および直後に行いたい処理を記述します。ここで、スクリーンショットをAllureのテストレポートに添付する`screenshot()`というメソッドを呼び出します。
- `screenshot()`メソッドには、Allureの[@Attachment](https://docs.qameta.io/allure/#_attachments)というアノテーションを付与しています。
`@Attachment`を使うことで`String`または`byte[]`型のメソッドの戻り値をテストレポートに添付することができます。

```java
@Attachment(type = "image/png")
// スクリーンショットを取得
public byte[] screenshot() {
   return Selenide.screenshot(OutputType.BYTES);
}
```

## テストレポート
ここまで実装したコードを実行し、テストレポートを見てみます。

```console
$ mvn clean test
$ mvn allure:serve
```

ブラウザでテストレポートを見ると、クリック前後の画面のスクリーンショットが添付されていることが確認できました。


# 参考サイト
- [Allure](http://allure.qatools.ru/)
- [Selenide](https://selenide.org/index.html)
- https://github.com/selenide-examples/selenide-allure-junit
- [Selenide～Javaで超簡単・簡潔にUIテストを書く～](https://qiita.com/tatesuke/items/589e30ab9b3dc7037e26)