mcpField
P
pw-init

pw-init

github.com/bondar-artemテスト・品質138 回インストール17 週間前に更新
リポジトリ

pw-init について

pw-initは、既存プロジェクトにPlaywrightのエンドツーエンドテスト環境を構築するスキルです。環境と認証の要件を確認し、Chromium単一ブラウザーを前提に設定やファイル、スクリプトを整えます。

主な機能

  1. 01環境とロールの要件確認
  2. 02Chromium限定のPlaywright設定
  3. 03ロール別プロジェクトと認証状態
  4. 04環境別dotenvファイル
  5. 05スモークテストとテストスクリプト

活用シーン

  1. 01プロジェクトでE2Eテストを開始
  2. 02複数環境のテスト設定
  3. 03認証済み・ゲストのテストロール追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bondar-artem/playwright-scripting-skills --skill pw-init

インストール後、Claude Code で/pw-initを入力して読み込まれたか確認します。

詳細

現在のプロジェクトに Playwright E2E フレームワークをゼロから初期化します。以下の手順に従ってください。

このスキルの AskUserQuestion の手順は、たとえ自律的に作業するよう指示されていても、絶対に省略しないでください。

適用する規約

生成するフレームワークは、次の構成に従います。

tests/
  auth.setup.ts                   # Auth state persistence (only if roles requested)
  <role>/                         # One subfolder per auth role (e.g. guest, admin)
    smoke.spec.ts                 # Generated sample smoke test
playwright-utils/
  .auth/                          # storageState files — gitignored
  fixtures/
    index.ts                      # Extended test + expect re-export (skeleton)
  helpers/                        # Stateless utilities
  pages/                          # Page objects (empty — created on demand)
  types/
    env.d.ts                      # process.env typing
.env.test.<env>                   # Per-environment vars — gitignored
playwright.config.ts              # Single Chromium browser, one project per role

主な規約:

  • ブラウザーは1つのみ(Desktop Chrome)。Firefox/WebKit のプロジェクトは作成しません。
  • 環境ファイルの名前は .env.test.<env>(例:.env.test.local、.env.test.qa)とし、TEST_ENV に基づいて dotenv で読み込みます。デフォルトは local です。
  • ロールごとのプロジェクトを playwright.config.ts に設定し、それぞれに独自の testDir: ./tests/<role> を指定します。また、認証が必要なロールには storageState と dependencies: ['auth-setup'] を設定します。
  • ストレージ状態は playwright-utils/.auth/<role>.json に保存します(playwright/.auth/ ではありません)。

1. 要件の収集

AskUserQuestion と自由入力のチャットを使って情報を収集します。以下の順序で質問してください。

1.1 環境

AskUserQuestion を使って質問を視覚的に強調します。ただし、多くの場合、回答は自由入力テキストとして「Other」から送られてくることを想定してください。質問は次のように設定します。

  • header:Environments
  • question:How many test environments do you need, and what should they be called? Provide a baseURL for each. Example: local: http://localhost:3000, qa: https://qa.example.com
  • multiSelect:false
  • options(よくあるケースをプリセットで用意します。「Other」は自動的に追加され、ユーザーが独自のリストを入力できます):
    1. Just local — Single env, BASE_URL=http://localhost:3000
    2. local + qa — Two envs; I'll ask for the qa baseURL next
    3. local + qa + production — Three envs; I'll ask for qa and production baseURLs next

追加の baseURL(qa/production)が必要なプリセットをユーザーが選んだ場合は、通常のチャットで追加の URL をそれぞれ確認します。ユーザーが「Other」を選んだ場合は、自由入力のリストを解析します。

最初に記載された環境がデフォルトになります(TEST_ENV が設定されていない場合に使用されます)。

1.2 認証ロール

AskUserQuestion を使います。次のように設定します。

  • header:Auth roles
  • question:What auth roles do you need? Each authenticated role gets an entry in auth.setup.ts plus its own project with storageState. "guest" is unauthenticated — no setup needed for it.
  • multiSelect:false
  • options(よくあるケースをプリセットで用意します。独自のリストを入力できる「Other」も自動的に追加されます):
    1. guest only — Unauthenticated tests only; skip auth.setup.ts and the auth-setup project
    2. guest + user — One unauthenticated project plus one authenticated role
    3. user + admin — Two authenticated roles, no guest project
    4. guest + user + admin — One unauthenticated project plus two authenticated roles

ユーザーが「Other」を選んだ場合は、自由入力のリストを解析します。最終的なリストに guest しか含まれていない場合は、auth.setup.ts と auth-setup プロジェクトの生成を省略します。

1.3 ログインフローの詳細(認証済みロールがある場合のみ)

AskUserQuestion を使用します。次のように設定します。

  • header:Login flow
  • question:How should I figure out the login flow for auth.setup.ts? I need: link text to the login page from /, form field labels for email and password, and the URL each role lands on after login.
  • multiSelect:false
  • options:
    1. Explore the source code — コードベース内でログインページ、フォームフィールド、ログイン後の URL を検索してから、セットアップを作成します
    2. Generate placeholders — 汎用の <LOGIN_LINK_TEXT>/<EMAIL_LABEL>/<PASSWORD_LABEL>/<POST_LOGIN_PATH> プレースホルダーと // TODO マーカーを使用します。後でユーザーが入力します
    3. I'll provide the details — ユーザーが「Other」からリンクテキスト、フィールドラベル、ログイン後の URL を入力します

ユーザーが Explore the source code を選択した場合:ログインページを検索します(src/app/login、app/login、src/pages/login、Login* に一致するコンポーネント、または「Log In」/「Sign In」リンクから参照されるルートを確認します)。メールアドレスとパスワードの入力ラベル、およびログイン後のリダイレクト先を特定します。auth.setup.ts の生成時には、それらの値をそのまま使用します。検索しても信頼できる情報が見つからない場合は、Generate placeholders の手順に切り替えます。

ユーザーが Generate placeholders を選択した場合:プレースホルダー値を使用し、各セットアップブロックの上に // TODO: confirm selectors コメントを1つ追加します。

ユーザーが I'll provide the details を選択した場合(または「Other」に回答を入力した場合):入力内容を(a)リンクテキスト、(b)メールアドレスのラベル、(c)パスワードのラベル、(d)ログイン後のパスとして解析します。

この手順で作業を止めず、いずれかの方法を選んで続行します。

1.4 追加の任意項目

それぞれについて、AskUserQuestion を使用して質問します(個別の質問、選択肢は2つずつ — yes/no)。

  • CI の webServer ブロック — 「CI で開発サーバーを自動起動するために、playwright.config.ts に webServer 設定を含めますか?」 はいの場合、起動コマンド(例:npm run dev)と、配信する URL を尋ねます。
  • Claude ルールのコピー — 「今後の AI 作業で規約に従えるよう、playwright-architecture.md と playwright-scripting.md を .claude/rules/ にコピーしますか?」 はい/いいえのみ — コピー元のパスは尋ねないでください。正規のコピー元は、ユーザーレベルのインストーラースキルである ~/.claude/skills/init-playwright-architecture/SKILL.md と ~/.claude/skills/init-playwright-scripting/SKILL.md です。ルールの内容は と のマーカーの間に埋め込まれています。これらのファイルが存在しない場合は、ユーザーにはっきり伝えてスキップします — 内容を捏造しないでください。

2. Playwright インストーラーを実行する

create-playwright フラグを使用して、インストーラーを非対話形式で実行します。これによりプロンプトウィザードをスキップできるため、この手順全体を自動で実行できます。

npm init playwright@latest -- --quiet --browser=chromium --install-deps

フラグ:

  • --quiet — ウィザードをスキップし、デフォルトを使用します
  • --browser=chromium — Chromium のみをインストールします(単一ブラウザーの規約に準拠)
  • --install-deps — ブラウザーとシステム依存関係を自動インストールします
  • TypeScript、tests/ フォルダー、「GitHub Actions ワークフローなし」は quiet モードのデフォルトです — フラグは不要です

インストールに失敗するか、停止した場合は、ターミナルでコマンドを対話形式で実行するようユーザーに依頼します。

3. デフォルト設定をクリーンアップする

インストーラーが作成したファイルのうち、規約に合わないものを削除します。

rm -r tests-examples 2>/dev/null
rm tests/example.spec.ts 2>/dev/null

4. サポート用の依存関係をインストールする

次のコマンドを実行するようユーザーに依頼します。

npm install -D dotenv

5. playwright.config.ts を生成する

デフォルト設定を上書きします。収集した環境変数とロールを使用します。テンプレート:

import { defineConfig, devices } from '@playwright/test'
import dotenv from 'dotenv'

const testEnv = process.env.TEST_ENV ?? '<DEFAULT_ENV>'
process.env.TEST_ENV = testEnv
dotenv.config({ path: `.env.test.${testEnv}`, quiet: true })

const isCI = !!process.env.CI

export default defineConfig({
  testDir: './tests',
  fullyParallel: false,
  retries: isCI ? 2 : 0,
  workers: isCI ? 1 : undefined,
  reporter: isCI ? [['html', { open: 'never' }], ['github']] : [['html', { open: 'never' }]],
  timeout: 60000,
  expect: { timeout: 10000 },
  use: {
    baseURL: process.env.BASE_URL,
    trace: 'on-first-retry'
  },
  projects: [
    // Include only if any authenticated roles exist:
    {
      name: 'auth-setup',
      testMatch: 'auth.setup.ts',
      use: { ...devices['Desktop Chrome'] },
    },
    // Per-role projects — one entry per role.
    // Unauthenticated roles (e.g. guest) omit storageState + dependencies:
    {
      name: '<role>',
      testDir: './tests/<role>',
      use: {
        ...devices['Desktop Chrome'],
        storageState: 'playwright-utils/.auth/<role>.json', // omit for guest
      },
      dependencies: ['auth-setup'], // omit for guest
    },
  ],
  // Include only if user opted into webServer block:
  // webServer: {
  //   command: '<USER_DEV_COMMAND>',
  //   url: '<USER_DEV_URL>',
  //   reuseExistingServer: !process.env.CI,
  //   timeout: 120_000,
  // },
})

<DEFAULT_ENV> を、ユーザーが列挙した最初の環境名に置き換えます。ロールごとにプロジェクトエントリを1つ生成します。

6. .gitignore を更新する

追記します(ファイルが存在しない場合は作成します)。

# Playwright
playwright-utils/.auth/
test-results/
playwright-report/
playwright/.cache/

# Local env files (keep .env.test.example committed)
.env
.env.local
.env.test.*
!.env.test.example

7. ディレクトリー構成を作成する

mkdir -p playwright-utils/{fixtures,helpers,pages,types,.auth}
mkdir -p tests/<role>  # one per role from step 1.2

8. tests/auth.setup.ts を生成する

認証済みロールがない場合はスキップします。それ以外の場合は、手順 1.3 のログインフローの詳細を使って、認証済みロールごとに setup(...) ブロックを 1 つ生成します。

import { test as setup } from '@playwright/test'

const <role>File = 'playwright-utils/.auth/<role>.json'

setup('authenticate as <role>', async ({ page }) => {
  await page.goto('/')
  await page.getByRole('link', { name: '<LOGIN_LINK_TEXT>' }).click()
  await page.getByRole('textbox', { name: '<EMAIL_LABEL>' }).fill(process.env.<ROLE>_EMAIL!)
  await page.getByLabel('<PASSWORD_LABEL>').fill(process.env.<ROLE>_PASSWORD!)
  await page.getByRole('button', { name: 'Login', exact: true }).click()
  await page.waitForURL('**<POST_LOGIN_PATH>')
  await page.context().storageState({ path: <role>File })
})

ユーザーから部分的な詳細しか提示されていない場合は、妥当なプレースホルダーを残し、各 setup ブロックの上に 1 行の // TODO: confirm selectors コメントを追加します。セレクターは実行時にユーザーが調整します。(許可されるコメント:ユーザーによる対応が必要であることを示すもの。説明文は不可。)

9. playwright-utils/types/env.d.ts を生成する

export {}

declare global {
  namespace NodeJS {
    interface ProcessEnv {
      TEST_ENV?: '<env1>' | '<env2>' | ...
      BASE_URL?: string
      CI?: string
      // One pair per authenticated role:
      <ROLE>_EMAIL?: string
      <ROLE>_PASSWORD?: string
    }
  }
}

namespace NodeJS 宣言を declare global { ... } で囲みます。export {} があるため、このファイルはモジュールです。モジュール内からグローバルの NodeJS.ProcessEnv インターフェースを拡張するには declare global が必要です。そうしないと、TypeScript はローカル宣言として扱い、process.env.<ROLE>_EMAIL に型が付与されません。

tsconfig.json にこのファイルが含まれていることを確認します。Playwright が生成するデフォルトの tsconfig.json は **/*.ts を対象とするため、自動的に含まれます。

10. playwright-utils/fixtures/index.ts を生成する

拡張テストを再エクスポートするスケルトンです。将来のページオブジェクトを組み込める状態にします。

import { test as base, expect } from '@playwright/test'

type Fixtures = {
  // Add fixtures here as page objects and helpers are built.
}

export const test = base.extend<Fixtures>({})

export { expect }

11. サンプルのスモークテストを生成する

各ロールについて、tests/<role>/smoke.spec.ts を作成します。スモークテストでは、フレームワークが正しく設定されていることを検証します。環境変数を設定すれば、新規インストール時に合格する必要があります。

ゲスト用スモークテストのテンプレート:

import { test, expect } from '@playwright/test'

test.describe('Guest smoke', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/')
  })

  test('Home page loads', async ({ page }) => {
    await expect(page).toHaveURL('/')
  })
})

認証済みロール用スモークテストのテンプレート:

import { test, expect } from '@playwright/test'

test.describe('<Role> smoke', () => {
  test('Authenticated session is active', async ({ page }) => {
    await page.goto('/')
    // TODO: replace with a real authenticated-only assertion
    // (e.g. expect(page.getByRole('button', { name: '<user menu>' })).toBeVisible())
  })
})

12. package.json のスクリプトを更新する

以下のスクリプトを追加します。既存の scripts とマージし、上書きしないでください。

{
  "scripts": {
    "test:e2e": "playwright test",
    "test:e2e:ui": "playwright test --ui"
  }
}

ユーザーが複数の環境を定義した場合は、デフォルトに加えて、それぞれの環境用のエイリアスも追加します。

"test:e2e:<env>": "TEST_ENV=<env> playwright test"

13. Claude のルールをコピーする(ユーザーが選択した場合のみ)

手順 1.4 でユーザーが選択した場合は、ユーザーレベルのインストーラースキルからルールの内容を抽出し、新しいプロジェクトの .claude/rules/ ディレクトリに書き込みます。パスをユーザーに尋ねてはいけません。ソースは固定されています。

各ルール(architecture と scripting)について:

  1. ソース:~/.claude/skills/init-playwright-<name>/SKILL.md。ファイルが存在しない場合は、ユーザーにはっきり伝えて、そのルールをスキップします。内容を捏造してはいけません。
  2. マーカーと マーカーの間の内容を抽出します(マーカーは含めません)。先頭と末尾の空行を削除します。
  3. 抽出した内容を、現在のプロジェクトの .claude/rules/playwright-<name>.md に書き込みます。
mkdir -p .claude/rules

# Architecture rule
awk '/^$/{flag=1; next} /^$/{flag=0} flag' \
  ~/.claude/skills/init-playwright-architecture/SKILL.md \
  > .claude/rules/playwright-architecture.md

# Scripting rule
awk '/^$/{flag=1; next} /^$/{flag=0} flag' \
  ~/.claude/skills/init-playwright-scripting/SKILL.md \
  > .claude/rules/playwright-scripting.md

新しいプロジェクトに対象ファイルがすでに存在する場合は、上書きする前に Overwrite / Skip をユーザーに尋ねます。

14. 最終サマリーと環境ファイル(最後の手動ステップ)

ここでスキルを終了します。確認を求めて一時停止したり、ファイルを検証したり、スモークテストを実行したりしないでください。

手順 1.1 の環境ごとに 1 つ(Git で無視されるもの)と、.env.test.example(コミット対象)のブロックを出力します。各ブロックには BASE_URL=<env baseURL> と、手順 1.2 の認証済みロールごとに空欄の <ROLE>_EMAIL / <ROLE>_PASSWORD のペアを 1 つずつ含めます。.env.test.example のブロックでは、最初の環境の BASE_URL をプレースホルダーとして使います。

ユーザーの実際の環境名とロール名を使って、ブロックを具体的に記述します。環境が local と qa、ロールが user と admin の場合の例:

フレームワークの準備ができました — 最後に、以下の環境ファイルを作成してください。

.env.test.local(Git で無視されます):

BASE_URL=http://localhost:3000
USER_EMAIL=
USER_PASSWORD=
ADMIN_EMAIL=
ADMIN_PASSWORD=

.env.test.qa(Git で無視されます):

BASE_URL=https://qa.example.com
USER_EMAIL=
USER_PASSWORD=
ADMIN_EMAIL=
ADMIN_PASSWORD=

.env.test.example(コミット対象):

BASE_URL=http://localhost:3000
USER_EMAIL=
USER_PASSWORD=
ADMIN_EMAIL=
ADMIN_PASSWORD=

コメント