TodoアプリにPlayWrightを導入してみたので紹介
PR
PlayWrightとは?
- 最新のE2Eテストフレームワーク
- コードジェネレータが使えて便利
モチベーション
以前、記事で紹介した開発中のTODOアプリでmarkdown-to-jsxを使用しているがユニットテストで動かそうとすると正常に動作しない。
なので、E2Eテストで継続的にテストが実装できるか試してみた。
実装
テスト実装は以下のコードジェネレータの機能を使用してベースを作成。
実行は以下のコマンドで実行
$ yarn playwright codegen http://127.0.0.1:142
以下みたいに画面が立ち上がり、操作すると自動でテストコードが生成されて簡単にE2Eのテストケースを作成できる。
今回作成したいテストケースだと入力した値をlocalStorageに保存しているので、それが正しく保存されているのかテストしたかったので、evaluate
の機能を使用。
evaluateの機能を使用することでE2Eを実行している側のブラウザの情報も取得できるので、ここからlocalStorageを取得して想定通りかチェックしている。
最終的なテストコードは以下のようになった。
import { test, expect } from "@playwright/test"; // @ts-ignore import { mockDate } from "./mockdate.ts"; import dayjs from "dayjs"; test.beforeEach(async ({ page }) => { await page.goto("/"); }); test("初期画面の確認", async ({ page }) => { await expect(page).toHaveTitle(/todo/); }); test.describe("Markdownの入力テスト", () => { test("プレビューにチェックでMarkdownにチェックが付く", async ({ page }) => { await page.getByText("編集").click(); await page.locator("data-testid=input-markdown").click(); await page .locator("data-testid=input-markdown") .fill("- [ ] Task1\n- [ ] Task2"); await page.getByText("プレビュー").click(); await page.locator("data-testid=checkbox-Task1").click(); expect( await page.locator("data-testid=checkbox-Task1").isChecked() ).toBeTruthy(); await page.getByText("編集").click(); expect( await page.locator("data-testid=input-markdown").inputValue() ).toMatch("- [x] Task1\n- [ ] Task2"); }); }); test.describe("Markdownの入力した時に、保存されるデータのチェック", () => { test("編集してチェックした時のデータが保存されている", async ({ page }) => { await mockDate(page, "2023-01-01T00:00:00+09:00"); await page.getByText("編集").click(); await page.locator("data-testid=input-markdown").click(); await page .locator("data-testid=input-markdown") .fill("- [ ] Task1\n- [ ] Task2\n- [ ] Task3"); await page.getByText("プレビュー").click(); await page.locator("data-testid=checkbox-Task1").click(); const taskListValue = await page.evaluate(() => { return localStorage.getItem("taskList"); }); const r = JSON.parse(taskListValue ?? "").map((task: any) => ({ ...task, checkedAt: task.checkedAt ? dayjs(task.checkedAt).format("YYYY-MM-DDTHH:mm:ss") : null, })); expect(r).toMatchObject([ { checked: true, checkedAt: "2023-01-01T00:00:00", depth: 3, text: "Task1", }, { checked: false, checkedAt: null, depth: 3, text: "Task2", }, { checked: false, checkedAt: null, depth: 3, text: "Task3", }, ]); }); });
これでE2Eテストは完成。継続的にチェックしたいのでGitHub Actionsでも実行するように設定。
■.github/workflows/playwright.yml
name: Playwright Tests on: push: branches: - "*" tags-ignore: - "v*" jobs: test: timeout-minutes: 60 runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16.x cache: yarn - name: Cache node_modules uses: actions/cache@v3 with: path: ~/.cache/yarn key: ${{ runner.os }}-todo-${{ hashFiles(format('{0}{1}', github.workspace, '/yarn.lock')) }} restore-keys: ${{ runner.os }}-todo- - name: Install node_modules if: steps.cache.outputs.cache-hit != 'true' run: yarn install - name: Install Playwright Browsers run: yarn playwright install --with-deps - name: Run Playwright tests run: TZ=Asia/Tokyo yarn e2e:all - uses: actions/upload-artifact@v3 if: always() with: name: playwright-report path: playwright-report/ retention-days: 30
手軽に使えて良いフレームワークだったので、今後も使っていくと思った。