🦁

VRTでPlaywright のグローバルセットアップ

2024/09/22に公開

テスト自動化を行う際、毎回ログイン処理を挟むのは手間がかかり、テストの実行時間も増えてしまいます。そこで、ログインを一度だけ行い、そのセッション情報を再利用する方法をご紹介します。

背景

Playwrightを使用してE2Eテストやビジュアルリグレッションテスト(VRT)を行っていると、各テストごとにログイン処理を実装するのは煩雑です。特に複数のテストケースがある場合、ログイン処理が繰り返され、テスト全体のパフォーマンスにも影響を与えます。

解決策:認証状態の共有

PlaywrightのstorageState機能を利用することで、一度ログインした認証状態を保存し、他のテストで再利用することが可能です。これにより、ログイン処理を各テストから省略し、テストの効率化を図ることができます。

実装手順

1. グローバルセットアップスクリプトの作成

プロジェクトのルートディレクトリにglobal-setup.tsファイルを作成します。このスクリプトでログイン処理を一度だけ行い、認証状態をファイルに保存します。

// global-setup.ts
import { chromium, FullConfig } from '@playwright/test';

async function globalSetup(config: FullConfig) {
  // ブラウザを起動
  const browser = await chromium.launch();
  const page = await browser.newPage();

  // ログイン処理
  await page.goto('http://localhost:3060/auth/login');
  await page.getByLabel('メールアドレス').fill('your-email@example.com');
  await page.getByLabel('パスワード', { exact: true }).fill('your-password');
  await Promise.all([
    page.getByRole('button', { name: 'ログイン' }).click(),
    page.waitForNavigation({ waitUntil: 'load' }),
  ]);

  // 認証状態を保存
  await page.context().storageState({ path: 'auth.json' });

  // ブラウザを閉じる
  await browser.close();
}

export default globalSetup;

注意your-email@example.comyour-passwordは、ご自身の認証情報に置き換えてください。ただし、セキュリティ上の観点から、これらの情報は環境変数や設定ファイルで管理することをおすすめします。

2. Playwrightの設定ファイルを修正

playwright.config.tsを修正し、グローバルセットアップスクリプトと認証状態ファイルを指定します。

// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: 'html',

  // グローバルセットアップスクリプトを指定
  globalSetup: require.resolve('./global-setup'),

  use: {
    // 認証状態ファイルを指定
    storageState: 'auth.json',
    baseURL: 'http://localhost:3060',
    trace: 'on-first-retry',
    launchOptions: {
      headless: false,
      slowMo: 750,
      chromiumSandbox: true,
      timeout: 100000,
    },
    viewport: {
      width: 1920,
      height: 1080,
    },
  },

  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },
  ],
});

3. テストコードからログイン処理を削除

各テストファイルからログイン処理を削除します。認証状態が自動的に読み込まれるため、テストは認証済みの状態で開始されます。

// example-test.ts
import { test } from '@playwright/test';

test('認証が必要なページのテスト', async ({ page }) => {
  await page.goto('/protected-page');
  // ここからテスト内容を記述
});

4. セキュリティ対策

  • 認証情報の管理:メールアドレスやパスワードなどの機密情報は、ハードコードせず環境変数や設定ファイルで管理しましょう。
  • auth.jsonの保護:認証状態が保存されたauth.json.gitignoreに追加し、バージョン管理システムに含めないようにします。

5. 補足:セッションの有効期限に注意

アプリケーションのセッション有効期限が短い場合、テスト中にセッションが切れる可能性があります。その場合は、セッションの有効期限を延ばすか、global-setup.tsで定期的に認証状態を更新するようにします。

まとめ

  • 一度のログインで認証状態を共有storageState機能を利用し、一度のログインで認証状態を保存・共有します。
  • テストの効率化:各テストでログイン処理を省略でき、テストの実行時間を短縮できます。
  • セキュリティへの配慮:機密情報の管理や認証状態ファイルの取り扱いに注意が必要です。

これらの手順を踏むことで、テストの効率化とセキュリティの両立が可能になります。毎回ログインをしている手間を省き、テスト自動化の生産性を向上させましょう。

Discussion