Skip to content

fix(web): stabilize reload and add E2E quality gates (#584) - #595

Merged
hmjn023 merged 4 commits into
developfrom
fix/issue-584-e2e-quality-gates
Jul 12, 2026
Merged

fix(web): stabilize reload and add E2E quality gates (#584)#595
hmjn023 merged 4 commits into
developfrom
fix/issue-584-e2e-quality-gates

Conversation

@hmjn023

@hmjn023 hmjn023 commented Jul 12, 2026

Copy link
Copy Markdown
Owner

概要

SSR/F5・CCIP反映を安定化し、#576 の後続となる Web/Chromium 品質ゲートを追加します。

変更内容

  • direct URL/F5/hydration と CCIP/SSE の回帰を修正
  • dev と fresh production の隔離E2E harness、ブラウザ健全性検査を追加
  • loading/error/offline/background refresh、代表 viewport、SSE再接続を検証
  • 実 CCIP 抽出から Find Similar、実 LanceDB の永続化・検索を検証
  • 個別メディア詳細の 503 からリロード復旧、および connection failed/refused/timed out/reset を検証
  • GitHub Actions のE2E workflowは削除し、apps/server のローカル test にE2Eを統合

ローカル検証

bun run --cwd apps/server test

このコマンドはunit、integration、dev E2E、fresh production E2Eを順に実行します。

実行結果

  • unit: 162 passed
  • integration: 66 passed
  • E2E: dev/production 各23 passed
  • server typecheck: passed

Fixes #584

Summary by CodeRabbit

  • 新機能

    • 検索、設定、管理、メディア画面の初期表示とリロード時の安定性を改善しました。
    • 検索画面で読み込み中のフォールバック表示を追加しました。
    • 開発環境・本番環境の両方でE2Eテストを実行できるようになりました。
  • バグ修正

    • CCIPベクトル抽出の古い応答による表示不整合を修正しました。
    • メディア切り替え時の抽出状態を正しく更新するよう改善しました。
    • ページ離脱時のイベントストリームを適切に停止するようにしました。
  • テスト

    • 画面遷移、リロード、レスポンシブ表示、通信失敗からの復旧、類似検索などのE2Eテストを拡充しました。

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8f28f48b-add4-46fa-8b44-bfa75eb6225e

📥 Commits

Reviewing files that changed from the base of the PR and between f40bba8 and e64787a.

📒 Files selected for processing (2)
  • apps/server/src/infrastructure/ai/lancedb-ccip-vector-store.ts
  • apps/server/src/tests/integration/ai/lancedb-ccip-vector-store.test.ts

📝 Walkthrough

Walkthrough

E2E実行基盤をdev/production対応に再構成し、動的ポート・隔離ランタイム・シードデータを導入しました。主要ルートのSSR/CSR描画、CCIP状態管理、イベント購読を更新し、通信障害・復旧・SSE・レスポンシブ表示などのテストを追加しました。

Changes

E2EとUI動作

Layer / File(s) Summary
E2EランタイムとCI
.gitignore, apps/server/package.json, apps/server/playwright.config.ts, apps/server/scripts/*, apps/server/vite.config.ts, apps/server/tsconfig.json, mise.toml
dev/production別のE2E実行、動的ポート、隔離ランタイム、テスト用DB・メディア・設定を構成しました。
ルートのSSR/CSR描画
apps/server/src/router.tsx, apps/server/src/routes/*
主要ルートにClientOnly、SSRフォールバック、マウント後描画を追加しました。
E2Eフィクスチャと回帰テスト
apps/server/src/tests/e2e/*
ローディング、通信失敗、復旧、SSE再接続、ルート再読み込み、SPA遷移、レスポンシブ表示を検証しました。
CCIP状態とベクトル検索
apps/server/src/components/media/media-sidebar.tsx, apps/server/src/infrastructure/ai/*, apps/server/src/infrastructure/api/*, apps/server/src/tests/integration/ai/*
CCIP状態の競合制御とエラーログを追加し、LanceDBの永続化・整合性・状態遷移・類似検索を検証しました。
イベント購読と検索パネル
packages/ui/src/event-stream.*, packages/ui/src/media-sidebar.tsx, packages/ui/src/screens/search-screen.tsx
pagehide時の購読中断、状態更新の失効判定、検索パネル生成を更新しました。

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant Playwright
  participant E2EApp
  participant Database
  Browser->>Playwright: ルート遷移・API操作
  Playwright->>E2EApp: 遅延・失敗・SSE応答を制御
  E2EApp->>Database: シードデータ・CCIP状態を取得
  Database-->>E2EApp: メディア・ベクトル情報を返却
  E2EApp-->>Browser: ローディング・復旧・検索結果を表示
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed タイトルはリロード安定化とE2E品質ゲート追加という変更の主旨を簡潔に表しています。
Linked Issues check ✅ Passed #584】320/375/768/desktopのプロジェクト、loading/error/offline、背景更新、SSE保持、横スクロール検出が追加されています。
Out of Scope Changes check ✅ Passed #584】E2E基盤・SSR/再接続安定化・CCIP検証に関連する変更が中心で、明らかな無関係変更は見当たりません。
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/issue-584-e2e-quality-gates

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
packages/ui/src/event-stream.test.ts (1)

44-59: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

BFCache時にストリームを維持する挙動を正しく検証。

persisted=true の場合に abort されないこと、unsubscribe() 呼び出し時には abort されることを確認できています。ただし window.removeEventListener が実際に呼ばれたかまでは検証していません(event-stream.ts 側の 90-92 行目のクリーンアップ処理)。vi.spyOn(page, "removeEventListener") などで呼び出しを確認するテストを追加すると、リスナーリーク回帰の検出力が上がります。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/event-stream.test.ts` around lines 44 - 59, Extend the test
for BFCache handling around subscribeToEventStream by spying on
page.removeEventListener before subscribing, then assert it is called during
unsubscribe(). Keep the existing assertions that persisted=true does not abort
the stream immediately and that unsubscribe() aborts it.
apps/server/src/routes/sources/$mediaSourceId/$mediaId/index.tsx (1)

46-55: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

MediaRouteContent 内の ClientOnly は冗長な可能性があります

Media()isMounted/Show によって MediaRouteContent はすでにクライアント側マウント後にのみ描画されます。その内側で再度 ClientOnly fallback={<MediaRouteFallback />} を挟んでいますが、search.tsx の同種パターン(SearchRouteContent はマウントゲートのみで ClientOnly を使わない)とは異なり、二重のガードになっています。動作上の問題はありませんが、両ルートでパターンを揃えると保守性が上がります。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/server/src/routes/sources/`$mediaSourceId/$mediaId/index.tsx around
lines 46 - 55, MediaRouteContent 内の冗長な ClientOnly ガードを削除し、MediaContent
を直接レンダリングしてください。Media() の isMounted/Show によるマウント後の描画は維持し、SearchRouteContent
と同じ単一のマウントゲートパターンに揃えてください。
apps/server/playwright.config.ts (1)

3-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

E2eMode型と環境変数スナップショット処理の重複。

E2eMode型定義とgetE2eMode/getEnvironment相当のロジックが、本ファイルとrun-e2e.tscreateEnvironmente2e-server.tsgetMode/serverEnvironmentにほぼ同一の実装で重複しています。すでにgetE2eModee2e-server.tsgetModeはエラーメッセージが異なるなど僅かに乖離しており、今後さらに分岐する恐れがあります。共通モジュール(例: fixture.tsや新規e2e-env.ts)に集約することを推奨します。

♻️ 共通化の方向性
// apps/server/src/tests/e2e/support/e2e-env.ts (新規)
export type E2eMode = "dev" | "production";

export function getE2eMode(): E2eMode {
	const mode = process.env.E2E_MODE;
	if (mode === "dev" || mode === "production") return mode;
	throw new Error("E2E_MODE must be set to dev or production.");
}

export function snapshotEnv(): Record<string, string> {
	return Object.fromEntries(
		Object.entries(process.env).flatMap(([key, value]) =>
			value === undefined ? [] : [[key, value]],
		),
	);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/server/playwright.config.ts` around lines 3 - 21,
重複しているE2eMode定義と環境変数処理を共通モジュールへ集約し、playwright.config.tsのgetE2eMode/getEnvironment、run-e2e.tsのcreateEnvironment、e2e-server.tsのgetMode/serverEnvironmentをその共有実装へ置き換えてください。モード検証と環境スナップショットの既存動作を維持し、エラーメッセージも共通化してください。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/e2e.yml:
- Line 21: Update the actions/checkout@v4 step in the workflow to explicitly
disable persisted Git credentials by setting persist-credentials to false, while
preserving the existing checkout behavior.

In `@apps/server/scripts/e2e-server.ts`:
- Around line 251-260: Update linkProductionDependencies to handle an existing
outputDir/node_modules path without failing on symlink’s EEXIST error. Preserve
the current symlink behavior when the destination is absent, and use an
existence check or equivalent force-safe handling so production E2E startup
continues when Nitro already created the directory.

In `@apps/server/vite.config.ts`:
- Around line 16-17: Update the E2E port initialization near e2ePort and
e2eHmrPort to obtain E2E_PORT and E2E_HMR_PORT through
getRequiredE2eEnvironment, matching the validation used for E2E_ROUTE_TREE_PATH,
E2E_OUTPUT_DIR, and E2E_RUNTIME_DIR. Remove the silent 3100/3101 fallbacks while
preserving numeric parsing of the validated values.

---

Nitpick comments:
In `@apps/server/playwright.config.ts`:
- Around line 3-21:
重複しているE2eMode定義と環境変数処理を共通モジュールへ集約し、playwright.config.tsのgetE2eMode/getEnvironment、run-e2e.tsのcreateEnvironment、e2e-server.tsのgetMode/serverEnvironmentをその共有実装へ置き換えてください。モード検証と環境スナップショットの既存動作を維持し、エラーメッセージも共通化してください。

In `@apps/server/src/routes/sources/`$mediaSourceId/$mediaId/index.tsx:
- Around line 46-55: MediaRouteContent 内の冗長な ClientOnly ガードを削除し、MediaContent
を直接レンダリングしてください。Media() の isMounted/Show によるマウント後の描画は維持し、SearchRouteContent
と同じ単一のマウントゲートパターンに揃えてください。

In `@packages/ui/src/event-stream.test.ts`:
- Around line 44-59: Extend the test for BFCache handling around
subscribeToEventStream by spying on page.removeEventListener before subscribing,
then assert it is called during unsubscribe(). Keep the existing assertions that
persisted=true does not abort the stream immediately and that unsubscribe()
aborts it.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 30f65b89-e573-4757-9733-1b3e11007378

📥 Commits

Reviewing files that changed from the base of the PR and between c19c328 and 1d441be.

📒 Files selected for processing (30)
  • .github/workflows/e2e.yml
  • .gitignore
  • apps/server/package.json
  • apps/server/playwright.config.ts
  • apps/server/scripts/e2e-server.ts
  • apps/server/scripts/run-e2e.ts
  • apps/server/src/components/media/media-sidebar.tsx
  • apps/server/src/infrastructure/api/routers/ai-router.ts
  • apps/server/src/router.tsx
  • apps/server/src/routes/config.tsx
  • apps/server/src/routes/manager.tsx
  • apps/server/src/routes/search.tsx
  • apps/server/src/routes/sources/$mediaSourceId/$mediaId/index.tsx
  • apps/server/src/routes/sources/index.tsx
  • apps/server/src/tests/e2e/ccip-flow.spec.ts
  • apps/server/src/tests/e2e/loading-recovery.spec.ts
  • apps/server/src/tests/e2e/pages.spec.ts
  • apps/server/src/tests/e2e/realtime-preservation.spec.ts
  • apps/server/src/tests/e2e/route-reload.spec.ts
  • apps/server/src/tests/e2e/search.responsive.spec.ts
  • apps/server/src/tests/e2e/support/fixture.ts
  • apps/server/src/tests/e2e/support/test.ts
  • apps/server/src/tests/integration/ai/lancedb-ccip-vector-store.test.ts
  • apps/server/tsconfig.json
  • apps/server/vite.config.ts
  • mise.toml
  • packages/ui/src/event-stream.test.ts
  • packages/ui/src/event-stream.ts
  • packages/ui/src/media-sidebar.tsx
  • packages/ui/src/screens/search-screen.tsx
💤 Files with no reviewable changes (1)
  • apps/server/src/tests/e2e/pages.spec.ts

Comment thread .github/workflows/e2e.yml Outdated
Comment thread apps/server/scripts/e2e-server.ts
Comment thread apps/server/vite.config.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant