ReactアプリをPlaywrightでテストする〜まず試してみる〜

React3年目、初めてのe2eテストをPlaywright使って書いてみました。
なかなかよかったので何回かに分けて簡単にご紹介したいと思います。

# Playwrightとは

Node.jsからブラウザ操作するためのライブラリで、e2eテストが書けるとても便利なツールです。
お仕事で品質評価を行う方からおすすめのe2eテストライブラリとして教えていただきました。
jestと同じように書けるのでとっつきやすい印象です。

# 環境

- macOS Monterey 12.2.1
- Visual Studio Code 1.66.2
- Node.js 16.13.0
- React 18.0.0
- playwright 1.21.1

# インストール

今回はcreate-react-app を使って、Reactアプリのテストを書いてみることにします。
```shell
npx create-react-app playwright-app --typescript
```
出来上がったプロジェクトに移動してそのプロジェクトにtestライブラリを追加します。
```shell
cd playwright-app
yarn add -D @playwright/test
```
その後、playwrightで使うブラウザをインストールします。デフォルトでは、Chromium,Firefox, Webkitがインストールされます。
```shell
yarn playwright install
```

Visual Studio Codeの拡張機能[Playwright Test for VSCode](https://marketplace.visualstudio.com/items?itemName=ms-playwright.playwright)を入れます。

# 簡単なテストを書いてみる

`yarn start`すると、お馴染みのReactの回る画像と、「Edit src/App.js and save to reload.」というテキスト、そしてリンクといった構成の画面が表示されるかと思います。
その表示内容を検証するテストを書いてみることにします。

まずはトップ画面を表示させるコードを書きます。
先ほどの拡張機能を入れると、testsフォルダができているのでそちらにテストコードを作成します。

```ts:App.spec.ts
import { test, expect } from '@playwright/test';

test('basic test', async ({ page }) => {
  await page.goto('http://localhost:3000/');
  await expect(page).toHaveTitle(/React App/);
});
```

fixturesと呼ばれる引数のうち、pageオブジェクトを使ってページ遷移したり、ページの内容を検証できます。

VSCode のテストエクスプーラーから、デバッグモードでテストするとchromiumが立ち上がり、テストが実施されます。通常のテスト実行ではブラウザは表示されないです。

package.json の scripts に以下を追加すればコマンドから`yarn test`で実行できます。その他色々な指定でテスト実行ができますので、詳しくは、[Command Line](https://playwright.dev/docs/test-cli) を参照してください。
```json
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "playwright test",  // これを追加
    "eject": "react-scripts eject"
  }
```

次に、テキストの内容を検証するテストコードを追加します。
Dom要素は、locatorを使ってselectorで指定して取得します。
```ts
import { test, expect } from '@playwright/test';

test('basic test', async ({ page }) => {
  await page.goto('http://localhost:3000/');
  await expect(page).toHaveTitle(/React App/);
  const text = page.locator('p');
  await expect(text).toHaveText(/Edit src\/App.js and save to reload./);
});
```
指定したselectorで合ってるのか、locatorの指定した行にブレークポイントを設定し、デバッグモードでテスト実行すると確認ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116042/acb98e74-d02b-be62-0f50-03fe241c6d11.png)
chromium に、該当箇所が強調表示されてるのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116042/53371503-7334-c7e1-d9b5-61538494eb46.png)
テストが成功すると、
```shell
To open last HTML report run:

  npx playwright show-report
```
と表示されるので、`yarn playwright show-report`を実行すると、レポートがブラウザ上で表示されます。
今回はレポートを意識してテストコードを書いていないためとてもシンプルな表示になってますが、この辺どこかで試してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116042/ad115b87-0a8b-982d-de23-23a37fe369b1.png)

もう1つ、Reactのサイトを開くリンクをクリックした時の動作も検証しましょう。
このリンクは、`target="_blank"`なので別タブで開くことになります。
[Pageのドキュメント](https://playwright.dev/docs/pages#handling-new-pages)を確認したところ、`Handling new pages`に実装の方法が記載されていたのでそちらを参考にしました。

```ts
import { test, expect } from '@playwright/test';

test('basic test', async ({ page, context }) => {
  // ...(略)...

  // リンクのクリック検証
  const [newPage] = await Promise.all([
    context.waitForEvent('page'),
    page.click('a[target="_blank"]')
  ]);
  await newPage.waitForLoadState();
  await expect(newPage).toHaveURL('https://reactjs.org/');
  await expect(newPage).toHaveTitle(/React/);
});
```

他にもたくさんいろんなテストの書き方ができるのですが、今回はここまで。
ドキュメントも盛りだくさんでまだまだ把握してないところが多いのですが、ゆっくりじっくり進めていこうと思います。

# リンク

Playwright https://playwright.dev/