Conversation
- Playwrightのインストールと設定 - トップページと記事ページのE2Eテストを追加 - GitHub Actionsでmain PRへのE2Eテスト実行を設定 - テスト用シードデータの投入スクリプトを追加 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
このPRは、PlaywrightによるE2Eテストをプロジェクトに導入し、GitHub Actions経由でmainブランチへのPR時に自動実行されるようにします。トップページと記事ページの主要な機能をカバーするテストケースが含まれています。
Changes:
- Playwrightの依存関係とテスト実行スクリプトの追加
- トップページと記事ページのE2Eテストケース(合計11テスト)の実装
- GitHub Actionsワークフローの追加(mainブランチへのPR時に自動実行)
Reviewed changes
Copilot reviewed 6 out of 8 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Playwrightの依存関係とE2Eテスト実行用スクリプト(test:e2e, test:e2e:ui, test:e2e:debug, test:e2e:report, test:e2e:server)を追加 |
| pnpm-lock.yaml | Playwright関連の依存関係の解決とロックファイルの更新 |
| playwright.config.ts | Playwright設定ファイルの追加(テストディレクトリ、タイムアウト、リトライ設定、webServerの設定など) |
| e2e/index.spec.ts | トップページのE2Eテスト(記事セクション、ツイートセクション、リンクの表示確認など5つのテストケース) |
| e2e/article.spec.ts | 記事ページのE2Eテスト(遷移、タイトル、日付、本文、いいねボタン、404ページの確認など6つのテストケース) |
| e2e/fixtures/seed.sql | テスト用ツイートデータのシードSQL |
| .github/workflows/e2e.yaml | E2Eテストを実行するGitHub Actionsワークフロー |
| .gitignore | Playwright関連のディレクトリ(test-results, playwright-report, playwright/.cache)を追加 |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
e2e/article.spec.ts
Outdated
| // 記事ヘッダー内に日付が表示される(main内のheader) | ||
| const articleHeader = page.locator("main").locator("..").locator("header").first(); |
There was a problem hiding this comment.
記事ヘッダーを選択するために親要素(..)を使用するのは、DOM構造の変更に対して脆弱です。より明確なセレクタを使用することをお勧めします。例えば、適切なdata属性やクラス名を使ってヘッダーを直接選択するか、article > headerのようなより具体的なセレクタを使用してください。
| // 記事ヘッダー内に日付が表示される(main内のheader) | |
| const articleHeader = page.locator("main").locator("..").locator("header").first(); | |
| // 記事ヘッダー内に日付が表示される(main内のarticle > header) | |
| const articleHeader = page.locator("main article > header").first(); |
e2e/article.spec.ts
Outdated
| test("存在しない記事は404を表示する", async ({ page }) => { | ||
| await page.goto("/articles/non-existent-article-slug"); | ||
|
|
||
| // 404表示を確認(div要素内の404テキスト) | ||
| await expect(page.locator("div").filter({ hasText: /^404$/ })).toBeVisible(); |
There was a problem hiding this comment.
存在しない記事のテストで404ページの表示を確認していますが、正しいHTTPステータスコード(404)が返されているかの検証も追加することをお勧めします。これにより、ページの表示だけでなく、サーバーの応答が正しいことも確認できます。
e2e/article.spec.ts
Outdated
|
|
||
| // 記事ヘッダー内に日付が表示される(main内のheader) | ||
| const articleHeader = page.locator("main").locator("..").locator("header").first(); | ||
| await expect(articleHeader).toContainText("2023-11-09"); |
There was a problem hiding this comment.
テストで使用している日付「2023-11-09」がハードコードされています。この日付が記事のメタデータ(publishedAt)と一致することを確認してください。また、日付のフォーマットが変更された場合にテストが壊れる可能性があるため、より柔軟なアサーション(例:日付形式のパターンマッチング)を検討してください。
| await expect(articleHeader).toContainText("2023-11-09"); | |
| await expect(articleHeader).toContainText(/\d{4}-\d{2}-\d{2}/); |
| "test:e2e:ui": "playwright test --ui", | ||
| "test:e2e:debug": "playwright test --debug", | ||
| "test:e2e:report": "playwright show-report", | ||
| "test:e2e:server": "pnpm wrangler d1 migrations apply blog-iine-counter --local && pnpm wrangler d1 execute blog-iine-counter --local --file=./e2e/fixtures/seed.sql && pnpm preview" |
There was a problem hiding this comment.
test:e2e:serverスクリプトが長く複雑です。このスクリプトを複数のステップに分割するか、専用のシェルスクリプトファイルに移動することで、可読性と保守性が向上します。また、各コマンドのエラーハンドリングが不明確です。
| "test:e2e:server": "pnpm wrangler d1 migrations apply blog-iine-counter --local && pnpm wrangler d1 execute blog-iine-counter --local --file=./e2e/fixtures/seed.sql && pnpm preview" | |
| "test:e2e:db:migrate": "pnpm wrangler d1 migrations apply blog-iine-counter --local", | |
| "test:e2e:db:seed": "pnpm wrangler d1 execute blog-iine-counter --local --file=./e2e/fixtures/seed.sql", | |
| "test:e2e:server": "pnpm run test:e2e:db:migrate && pnpm run test:e2e:db:seed && pnpm preview" |
| command: "pnpm test:e2e:server", | ||
| url: "http://localhost:8787", | ||
| reuseExistingServer: !process.env.CI, | ||
| timeout: 180 * 1000, |
There was a problem hiding this comment.
webServerのtimeoutが180秒(3分)に設定されていますが、この長いタイムアウトが必要な理由を検討してください。もし実際のサーバー起動時間が短い場合は、より短いタイムアウト値を設定することで、テストの失敗をより早く検出できます。
| timeout: 180 * 1000, | |
| timeout: 60 * 1000, |
e2e/article.spec.ts
Outdated
| // 最初の記事をクリック | ||
| const firstArticle = page.locator("main ul li").first(); | ||
| await firstArticle.click(); | ||
|
|
||
| // 記事ページに遷移したことを確認 | ||
| await expect(page).toHaveURL(/\/articles\/.+/); |
There was a problem hiding this comment.
テストで「最初の記事」をクリックして遷移確認を行っていますが、記事が存在しない場合や記事の順序が変わった場合にテストが失敗する可能性があります。より堅牢なテストにするため、特定のslugを持つ記事へのリンクを明示的に選択することを検討してください。
| // 最初の記事をクリック | |
| const firstArticle = page.locator("main ul li").first(); | |
| await firstArticle.click(); | |
| // 記事ページに遷移したことを確認 | |
| await expect(page).toHaveURL(/\/articles\/.+/); | |
| // 特定の slug を持つ記事リンクをクリック | |
| const targetArticleLink = page.locator(`main a[href="/articles/${testArticleSlug}"]`); | |
| await targetArticleLink.click(); | |
| // 対象の記事ページに遷移したことを確認 | |
| await expect(page).toHaveURL(`/articles/${testArticleSlug}`); |
e2e/index.spec.ts
Outdated
| test("「もっと見る」リンクが存在する", async ({ page }) => { | ||
| const moreLink = page.locator("a", { hasText: "もっと見る" }); | ||
| await expect(moreLink).toBeVisible(); | ||
| await expect(moreLink).toHaveAttribute("href", "/tweets"); | ||
| }); |
There was a problem hiding this comment.
「もっと見る」リンクの存在確認はしていますが、リンクをクリックして実際にツイート一覧ページ(/tweets)に遷移できるかのテストが含まれていません。実際の遷移動作もテストすることをお勧めします。
| @@ -0,0 +1,9 @@ | |||
| -- テスト用ツイートデータ(既存データがあれば削除して挿入) | |||
| DELETE FROM tweets; | |||
There was a problem hiding this comment.
テスト用シードデータでDELETE FROM tweets;を実行していますが、これは既存のデータを削除します。テスト環境が適切に分離されていることを確認してください。また、テスト後のクリーンアップ処理が必要かどうかも検討してください。
| export default defineConfig({ | ||
| testDir: "./e2e", | ||
| timeout: 30 * 1000, | ||
| retries: process.env.CI ? 2 : 0, |
There was a problem hiding this comment.
現在のテスト設定では1つのワーカー(workers: 1)のみが使用されていますが、この制限が必要な理由をコメントで説明することをお勧めします。もしデータベースの競合を避けるためであれば、その旨を明記すると他の開発者の理解が深まります。
| retries: process.env.CI ? 2 : 0, | |
| retries: process.env.CI ? 2 : 0, | |
| // NOTE: テスト並列実行によるデータベースや共有リソースの競合を避けるため、ワーカー数を 1 に固定している |
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
概要
PlaywrightによるE2Eテストを導入し、mainブランチへのPR時に自動実行されるようにしました。
変更内容
playwright.config.ts)e2e/index.spec.ts)e2e/article.spec.ts).github/workflows/e2e.yaml)e2e/fixtures/seed.sql)テスト項目
pnpm test:e2eで全11テストがパスすることを確認