Skip to content

chore: PlaywrightによるE2Eテストを導入#73

Merged
sh1ma merged 4 commits intomainfrom
chore/add-playwright-e2e
Jan 10, 2026
Merged

chore: PlaywrightによるE2Eテストを導入#73
sh1ma merged 4 commits intomainfrom
chore/add-playwright-e2e

Conversation

@sh1ma
Copy link
Owner

@sh1ma sh1ma commented Jan 10, 2026

概要

PlaywrightによるE2Eテストを導入し、mainブランチへのPR時に自動実行されるようにしました。

変更内容

  • Playwrightのインストールと設定(playwright.config.ts
  • トップページのテスト(e2e/index.spec.ts
    • 「最新の記事」セクションの表示確認
    • 記事リストの表示確認
    • 「最新のつぶやき」セクションの表示確認
    • ツイートリスト(5件)の表示確認
    • 「もっと見る」リンクの存在確認
  • 記事ページのテスト(e2e/article.spec.ts
    • トップページからの記事遷移
    • タイトル・公開日・本文・いいねボタンの表示確認
    • 404ページの表示確認
  • GitHub Actions(.github/workflows/e2e.yaml
    • mainへのPR時にE2Eテストを実行
    • 失敗時にPlaywrightレポートをartifactとしてアップロード
  • テスト用シードデータ(e2e/fixtures/seed.sql

テスト項目

  • pnpm test:e2e で全11テストがパスすることを確認
  • ローカルのwrangler環境でD1データベースと連携できることを確認

- Playwrightのインストールと設定
- トップページと記事ページのE2Eテストを追加
- GitHub Actionsでmain PRへのE2Eテスト実行を設定
- テスト用シードデータの投入スクリプトを追加

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sh1ma sh1ma added the chore 何かの設定ファイルなどの変更関連など、雑多な変更につけるタグ label Jan 10, 2026
Copilot AI review requested due to automatic review settings January 10, 2026 07:53
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment on lines +30 to +31
// 記事ヘッダー内に日付が表示される(main内のheader)
const articleHeader = page.locator("main").locator("..").locator("header").first();
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

記事ヘッダーを選択するために親要素(..)を使用するのは、DOM構造の変更に対して脆弱です。より明確なセレクタを使用することをお勧めします。例えば、適切なdata属性やクラス名を使ってヘッダーを直接選択するか、article > headerのようなより具体的なセレクタを使用してください。

Suggested change
// 記事ヘッダー内に日付が表示される(main内のheader
const articleHeader = page.locator("main").locator("..").locator("header").first();
// 記事ヘッダー内に日付が表示される(main内のarticle > header
const articleHeader = page.locator("main article > header").first();

Copilot uses AI. Check for mistakes.
Comment on lines +54 to +58
test("存在しない記事は404を表示する", async ({ page }) => {
await page.goto("/articles/non-existent-article-slug");

// 404表示を確認(div要素内の404テキスト)
await expect(page.locator("div").filter({ hasText: /^404$/ })).toBeVisible();
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

存在しない記事のテストで404ページの表示を確認していますが、正しいHTTPステータスコード(404)が返されているかの検証も追加することをお勧めします。これにより、ページの表示だけでなく、サーバーの応答が正しいことも確認できます。

Copilot uses AI. Check for mistakes.

// 記事ヘッダー内に日付が表示される(main内のheader)
const articleHeader = page.locator("main").locator("..").locator("header").first();
await expect(articleHeader).toContainText("2023-11-09");
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

テストで使用している日付「2023-11-09」がハードコードされています。この日付が記事のメタデータ(publishedAt)と一致することを確認してください。また、日付のフォーマットが変更された場合にテストが壊れる可能性があるため、より柔軟なアサーション(例:日付形式のパターンマッチング)を検討してください。

Suggested change
await expect(articleHeader).toContainText("2023-11-09");
await expect(articleHeader).toContainText(/\d{4}-\d{2}-\d{2}/);

Copilot uses AI. Check for mistakes.
"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"
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test:e2e:serverスクリプトが長く複雑です。このスクリプトを複数のステップに分割するか、専用のシェルスクリプトファイルに移動することで、可読性と保守性が向上します。また、各コマンドのエラーハンドリングが不明確です。

Suggested change
"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"

Copilot uses AI. Check for mistakes.
command: "pnpm test:e2e:server",
url: "http://localhost:8787",
reuseExistingServer: !process.env.CI,
timeout: 180 * 1000,
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

webServerのtimeoutが180秒(3分)に設定されていますが、この長いタイムアウトが必要な理由を検討してください。もし実際のサーバー起動時間が短い場合は、より短いタイムアウト値を設定することで、テストの失敗をより早く検出できます。

Suggested change
timeout: 180 * 1000,
timeout: 60 * 1000,

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +15
// 最初の記事をクリック
const firstArticle = page.locator("main ul li").first();
await firstArticle.click();

// 記事ページに遷移したことを確認
await expect(page).toHaveURL(/\/articles\/.+/);
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

テストで「最初の記事」をクリックして遷移確認を行っていますが、記事が存在しない場合や記事の順序が変わった場合にテストが失敗する可能性があります。より堅牢なテストにするため、特定のslugを持つ記事へのリンクを明示的に選択することを検討してください。

Suggested change
// 最初の記事をクリック
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}`);

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +43
test("「もっと見る」リンクが存在する", async ({ page }) => {
const moreLink = page.locator("a", { hasText: "もっと見る" });
await expect(moreLink).toBeVisible();
await expect(moreLink).toHaveAttribute("href", "/tweets");
});
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「もっと見る」リンクの存在確認はしていますが、リンクをクリックして実際にツイート一覧ページ(/tweets)に遷移できるかのテストが含まれていません。実際の遷移動作もテストすることをお勧めします。

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,9 @@
-- テスト用ツイートデータ(既存データがあれば削除して挿入)
DELETE FROM tweets;
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

テスト用シードデータでDELETE FROM tweets;を実行していますが、これは既存のデータを削除します。テスト環境が適切に分離されていることを確認してください。また、テスト後のクリーンアップ処理が必要かどうかも検討してください。

Copilot uses AI. Check for mistakes.
export default defineConfig({
testDir: "./e2e",
timeout: 30 * 1000,
retries: process.env.CI ? 2 : 0,
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

現在のテスト設定では1つのワーカー(workers: 1)のみが使用されていますが、この制限が必要な理由をコメントで説明することをお勧めします。もしデータベースの競合を避けるためであれば、その旨を明記すると他の開発者の理解が深まります。

Suggested change
retries: process.env.CI ? 2 : 0,
retries: process.env.CI ? 2 : 0,
// NOTE: テスト並列実行によるデータベースや共有リソースの競合を避けるため、ワーカー数を 1 に固定している

Copilot uses AI. Check for mistakes.
@claude
Copy link

claude bot commented Jan 10, 2026

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

sh1ma and others added 2 commits January 10, 2026 16:59
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sh1ma sh1ma enabled auto-merge January 10, 2026 08:03
@sh1ma sh1ma merged commit e49e91b into main Jan 10, 2026
4 checks passed
@sh1ma sh1ma deleted the chore/add-playwright-e2e branch January 10, 2026 08:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore 何かの設定ファイルなどの変更関連など、雑多な変更につけるタグ

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants