PlaywrightとTypeScriptの併用

Playwright × TypeScript を併用するメリット ――なぜ上級者ほど TS を選ぶのか

目的 Playwright 単体 TypeScript 併用時
IDE 補完 API 名の記憶が必要 page. を打った瞬間に候補が出る
リファクタリング耐性 セレクターや関数名の誤字は実行時エラー 事前にコンパイルエラーで検知
大規模テスト ファイル依存が増えると保守負荷大 paths エイリアスや型共有で整理
CI 信頼性 “通ったはず” のテストが動かないことも tsc --noEmit 併走で型崩れを防止 playwright.dev

1. プロジェクト雛形と依存ライブラリ

bash
# 初期化 npm init -y npm i -D playwright @playwright/test typescript ts-node # 雛形生成 npx playwright install # ブラウザバイナリ取得 npx playwright test --init # playwright.config.ts と tests/ を作成
  • @playwright/test はテストランナー+型定義を同梱しているので @types/* を追加する必要はない。

  • Playwright 1.43 以降は ts-node を内蔵しており、事前トランスパイルせず .ts のまま実行できる playwright.dev


2. tsconfig.json ―― Playwright 用の推奨設定

json
{ "compilerOptions": { "target": "ESNext", "module": "CommonJS", "strict": true, // null 安全 "moduleResolution": "node", "types": ["@playwright/test"],// これが無いと Page 型などが出ない "baseUrl": ".", // ↓ import エイリアス "paths": { "@pages/*": ["src/pages/*"] }, "outDir": "dist" }, "include": ["tests/**/*.ts", "src/**/*.ts"] }
  • 1.47 以降、Playwright Test は baseUrlpaths を解釈して実行してくれるため、ビルド不要で短い import が書ける playwright.dev

  • プロジェクトが複数の tsconfig を持つ場合は playwright.config.tstsconfig: './tests.tsconfig.json' を明示する(1.46 新機能) github.com


3. playwright.config.ts の高度な型安全設定

ts
import { defineConfig, devices, expect } from '@playwright/test'; export default defineConfig({ testDir: 'tests', use: { viewport: { width: 1280, height: 720 }, screenshot: 'only-on-failure' as const, trace: 'retain-on-failure' }, /* プロジェクト毎のブラウザ設定 */ projects: [ { name: 'Chromium', use: { ...devices['Desktop Chrome'] } }, { name: 'Firefox', use: { ...devices['Desktop Firefox'] } }, ], });
  • as const により 設定値もリテラル固定 となり、typo を防止。

  • defineConfig() が返す型は PlaywrightTestConfig。VS Code 上でホバーすればプロパティの説明を読める。


4. 型で強化する Page Object Model(POM)

ts
// src/pages/LoginPage.ts import { Page, expect } from '@playwright/test'; export class LoginPage { constructor(private readonly page: Page) {} readonly user = this.page.locator('#user'); readonly pass = this.page.locator('#pass'); async login(u: string, p: string) { await this.user.fill(u); await this.pass.fill(p); await Promise.all([ this.page.waitForURL('/dashboard'), this.page.click('button[type=submit]') ]); } }
  • Generics で URL や Fixture を表現すれば、login<U extends string,P extends string>(u:U,p:P) のように入力値の型制約も可能。

  • POM を共通パッケージ化するとアプリ本体とテストの型を 同一定義 で再利用できる。


5. Fixtures & expect 拡張を型安全に

ts
// fixtures.ts import { test as base } from '@playwright/test'; import { LoginPage } from '@pages/LoginPage'; type TestFixtures = { loginPage: LoginPage }; export const test = base.extend<TestFixtures>({ loginPage: async ({ page }, use) => { await use(new LoginPage(page)); }, }); export const expect = test.expect;
  • カスタム fixture もジェネリクスで型を明示すれば、テスト側は補完 OK。

  • expect.extend@types/jest と衝突しやすいので、ES module 環境では PW_EXPERIMENTAL_TS_ESM=1 を付与し、Jest 型を外すと解決 playwright.dev


6. 速度最適化 ―― ビルド or 直実行

実行方法 長所 短所
npx playwright test(ts-node 内蔵) 設定が少なく即実行 巨大プロジェクトでは起動が遅い
tsc --build && node dist/test-runner.js 一度ビルドすれば高速 CI で 2 step 必要
esbuild-register ビルド無し + 初期化高速 experimental

7. CI/CD での型チェックとレポート

yaml
# .github/workflows/test.yml - name: Type check run: npx tsc --noEmit - name: Run E2E Tests run: npx playwright test --reporter=line,html - name: Upload Report uses: actions/upload-artifact@v4 with: name: playwright-report path: playwright-report/
  • 失敗時のスクリーンショット/トレースplaywright.config.tstracescreenshot で制御。

  • HTML レポートは自動生成されるため、アーティファクトとして保存しておくと分析しやすい。


8. ありがちなトラブルと対処

症状 原因 解決策
Cannot find module '@pages/LoginPage' paths 設定を Playwright が解釈しない 1.47 未満なら ts-node/registerNODE_OPTIONS に追加
Property 'toBeVisible' does not exist @playwright/test の型が古い npm i -D @playwright/test@latest で更新
SyntaxError: Cannot use import statement outside a module ESM と CJS が混在 "module": "ESNext" + PW_EXPERIMENTAL_TS_ESM=1 を導入

9. ベストプラクティス ✔︎ チェックリスト

  • strictnoImplicitAny で型抜けをゼロに

  • playwright/test 以外の型衝突(Jest 等)を排除

  • POM と Fixtures を共通化し テストの重複を削減

  • paths エイリアスで import をフラットに

  • tsc --noEmit を CI に追加して 型破壊の検出を自動化

  • レポートとトレースをアーティファクト保存し 失敗調査を高速化


まとめ

Playwright はデフォルトで TypeScript をサポートし、1.45 以降は tsconfig を深く理解するなど 型安全性と開発速度の両立 が進んでいます。
IDE 補完から CI 型チェックまで一貫して “壊れにくい E2E テスト基盤” を構築できるため、大規模プロジェクトや長期運用の現場では TypeScript 併用が実質必須 と言えるでしょう。

ChatGPT4o 生成日:2025/06/22