pw-init について
pw-initは、既存プロジェクトにPlaywrightのエンドツーエンドテスト環境を構築するスキルです。環境と認証の要件を確認し、Chromium単一ブラウザーを前提に設定やファイル、スクリプトを整えます。
主な機能
- 01環境とロールの要件確認
- 02Chromium限定のPlaywright設定
- 03ロール別プロジェクトと認証状態
- 04環境別dotenvファイル
- 05スモークテストとテストスクリプト
活用シーン
- 01プロジェクトでE2Eテストを開始
- 02複数環境のテスト設定
- 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」は自動的に追加され、ユーザーが独自のリストを入力できます):
Just local—Single env, BASE_URL=http://localhost:3000local + qa—Two envs; I'll ask for the qa baseURL nextlocal + 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」も自動的に追加されます):
guest only—Unauthenticated tests only; skip auth.setup.ts and the auth-setup projectguest + user—One unauthenticated project plus one authenticated roleuser + admin—Two authenticated roles, no guest projectguest + 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:
Explore the source code—コードベース内でログインページ、フォームフィールド、ログイン後の URL を検索してから、セットアップを作成しますGenerate placeholders—汎用の <LOGIN_LINK_TEXT>/<EMAIL_LABEL>/<PASSWORD_LABEL>/<POST_LOGIN_PATH> プレースホルダーと // TODO マーカーを使用します。後でユーザーが入力します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)について:
- ソース:
~/.claude/skills/init-playwright-<name>/SKILL.md。ファイルが存在しない場合は、ユーザーにはっきり伝えて、そのルールをスキップします。内容を捏造してはいけません。 マーカーとマーカーの間の内容を抽出します(マーカーは含めません)。先頭と末尾の空行を削除します。- 抽出した内容を、現在のプロジェクトの
.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=