Playwrightを使ってE2Eテストしよう

本記事は「 [TTDC Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ttdc) 」 5 日目の記事です。  

# はじめに
Webアプリの単体テストはjestやpytestなどで自動化されていても、UIのテストは手で行っていませんか？  
CI/CDするのであればUIテストも自動化できるPlaywrightを使ってみましょう。

# E2Eテストとは
E2E(End to End)テストは実際の環境を使用して行うテストです。  
リリース後にユーザが操作するのと同じ方法でテストすることで、早期に問題を発見することができます。  
E2Eテストツールは[Selenium](https://www.selenium.dev/ja/documentation/)が有名ですが、他にも[Puppeteer](https://pptr.dev/)や今回説明する[Playwright](https://playwright.dev/)などのコードベースのツールやSaaS系のサービスがあります。

# Playwrightって何？
[Playwright](https://playwright.dev/)はMicrosoftが開発したOpenSourceのブラウザ自動テストライブラリです。  
- 各種ブラウザに対応
- 各種言語(TypeScript,JavaScript,Python,.NET,Java)に対応
- 自動でテストコードを作成する機能あり
- 操作中の動作を画像が動画で保存する事が可能

# 準備
Pythonを使用してPlaywrightを動かしてみます。  
今回はWindows PowerShellを使用しています。  
Mac/Linuxでも動作しますので、手順は環境に応じて読み替えてください。  

1. Pythonをインストール  
1. pyenvインストール  
```powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/pyenv-win/pyenv-win/master/pyenv-win/install-pyenv-win.ps1" -OutFile "./install-pyenv-win.ps1"; &"./install-pyenv-win.ps1"
```
3. 実行環境作成  
```powershell
python -m venv .env
.env/Scripts/activate
pip install playwright
playwright install
```

# テストコード生成
[Playwright Codegen](https://playwright.dev/docs/codegen)を使用すれば、ブラウザ操作をスクリプトに変換してくれます。
```powershell
playwright codegen https://www.toyota-td.jp/ -o e2etest.py
```
ブラウザが立ち上がり、記録が開始されます。  
ブラウザ操作をするとInspectorウィンドウにスクリプトが出力されます。  
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939019/91ad248a-c2bf-6dc5-2550-b31f9e4d4354.png)
ブラウザに表示されているツールバーにある赤丸ボタンを押すと、記録を終了します。  

# テスト実施
生成したテストコードを実行します。  
```powershell
python .\e2etest.py
```
テストコード例  
※テストコードの先頭にawait(アサーション)を付けることでテストコード実行に失敗した場合エラーとなるため自動テストに使用できます。  
```python
await page.get_by_role("link", name="・ View more 事業・商品を見る").click()  #指定リンククリック
await page.locator("11").filter(has_text="計測解析サービス").click()          #表示文字を取得しクリック
```
![6.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939019/8c1d29c6-3c1f-8ccd-671d-1c281a1c8fc9.gif)
※この実行結果は上のソースに操作を追加しています。  

# Tips
## テスト結果を動画で保存したい
[Browser Class](https://playwright.dev/docs/api/class-browser#browser-new-context-option-record-video)にある、newContextメソッドの引数にrecordVideoオブジェクトを指定すると録画できます。
```python
    context = browser.new_context(
        record_video_dir="./videos",
        record_video_size={"height": 768, "width": 1024},
    )
```
webm形式で出力されます。  

## MFA認証
TOTP生成ライブラリを使用。  
[totp-generator](https://www.npmjs.com/package/totp-generator)  
[PyOTP](https://pyauth.github.io/pyotp/)  
```python
import pyotp
MFA_SECRET_CODE = "XXX"
totp = pyotp.TOTP(MFA_SECRET_CODE)
mfa_code = totp.now()
page.get_by_placeholder("認証コード").fill(mfa_code)
```

## 音声入力
ブラウザ(chromium)のfake deviceを使用して音声ファイルをマイク入力の代わりにすることが出来ます。
```python
wav_file_path = os.path.abspath('audio.wav')
browser = playwright.chromium.launch(headless=False,
            args=[
                # use Chrome's fake media streams
                "--use-fake-device-for-media-stream",
                # bypasses Chrome's cam/mic permissions dialog
                "--use-fake-ui-for-media-stream",
                # pass in your own custom media
                f"--use-file-for-fake-audio-capture={wav_file_path}"]
            )
```
[List of Chromium Command Line Switches](https://peter.sh/experiments/chromium-command-line-switches/#use-fake-device-for-media-stream)

# あとがき
これがQiita初投稿です。  
読みにくい部分があればご容赦ください。  
ご一読ありがとうございました。