#testing (1)
Next.js → Astro 移行でPlaywright VRTを使い、33テストケース(11ページ×3BP)の差分を自動修正するループを回した。得られた知見。
アーキテクチャ: スキル(司令塔)+ エージェント(修正者)
/vrt スキル (orchestrator)
├── pnpm test:vrt → JSON結果パース
├── 失敗ページをグルーピング
├── vrt-fixer エージェント(ページ単位で並列起動)
├── 再テスト → 収束判定
└── 結果レポート
エージェントにはページ名・差分情報(高さ差・ratio)を渡し、Astro側のコードだけを修正させる。
実証済み差異パターン(頻度順)
| パターン | 症状 | 原因 | 修正 |
|---|---|---|---|
| scroll animation属性 | セクション全体が白 | data-anim="fadeUp" → Playwrightでopacity:0のまま | 属性削除 or CSS注入でopacity:1強制 |
Tailwind preflight height:auto | 画像の高さが数px違う | SVGのheight属性がpreflightで上書き | インラインstyleで固定 |
next/image vs <img> | コンテナサイズ差 | Image最適化ラッパーの有無 | CSS注入でvisibility:hidden |
| DOMPurify正規化 | リッチテキストの行間差 | Next.jsはDOMPurifyで空白除去、移行先は生HTML | normalizeRichEditorHtml()で空白除去 |
| alt属性の不一致 | CSS注入が片側のみ有効 | 移行時にalt文字列を変えてしまう | セレクターに両方のalt値を追加 |
whitespace-pre-line | テキスト行数が違う | 移行先でクラスを追加してしまった | 該当クラス削除 |
| クライアントUIの欠落 | インタラクティブ要素がない | Reactコンポーネント未移植 | vanilla JS or island で再実装 |
VRT CSS注入が必須
両サーバーのスクリーンショットに共通CSSを注入して動的要素を安定化する。これがないとテストが不安定になる。
const HIDE_CSS = `
[data-anim] { opacity: 1 !important; transform: none !important; }
.swiper-wrapper, time { visibility: hidden !important; }
`;
await page.addStyleTag({ content: HIDE_CSS });
高さクリッピング戦略
next/imageのsubpixel差が累積して数px〜数十pxの高さ差になる。MAX_HEIGHT_DIFF_PX以内なら短い方にクリップして比較する。これにより寸法不一致エラーを回避しつつ、大きな構造差異は検出できる。
学び
- 共通コンポーネントの差異を最初に潰す(Footer 3px差 → 全33テストに波及)
- 環境変数の設定漏れは最大の偽陽性源(CMS APIキー未設定 → 15テスト失敗)
display:nonevsvisibility:hidden— 前者はレイアウトフローを変える。画像非表示はvisibility:hiddenが安全- VRT CSS注入リストの更新も正当な修正手段。コード修正と並行して使う