添付ファイルテストの競合状態をsrc確定待ちで解消

basecamp/lexxy

添付ファイルのギャラリーテストで発生していた断続的な失敗(フレーキーテスト)を、画像の src 属性が確定するまで待機する関数を導入することで解消しました。

背景

src スワッピングの導入により、画像アップロード後に src 属性が非同期で切り替わるタイミングで競合状態が生じていました。具体的には、src の切り替えが発生すると選択状態(selection)がクリアされてしまうため、クリック直後に要素を操作するテストが不安定になっていました。

この問題は複数の添付ファイルテストに影響しており、gallery.test.js 内でアタッチメントをクリックしてから2枚目の画像をアップロードするシナリオで特に頻繁に再現していました。

技術的な変更

競合状態を回避するために、selectAttachment というヘルパー関数が追加され、直接の click() 呼び出しを置き換えました。

変更前:

await page.locator("figure.attachment img").click()

変更後:

await selectAttachment(page)

追加された selectAttachment 関数は以下の3ステップで構成されています:

async function selectAttachment(page) {
  await page.locator("figure.attachment img[src*='/blobs/']").waitFor()
  await page.locator("figure.attachment img").click()
  await expect(page.locator("figure.attachment")).toHaveClass(/node--selected/)
}

まず img[src*='/blobs/'] セレクタで /blobs/ を含む最終的な src が確定するまで待機し、その後クリックを実行し、最後に node--selected クラスが付与されたことを確認します。この3ステップにより、src スワッピング完了前にクリックが走る競合状態と、クリック後に選択状態が確立されていない状態での次操作への進行、双方を防ぎます。この変更は gallery.test.js 内の2箇所の呼び出し元に適用されています。

設計判断

セレクタによる状態確認を待機条件として活用するアプローチが採用されました。

単純に固定の遅延(waitForTimeout)を挿入するのではなく、img[src*='/blobs/'] というセレクタで「最終的なBlobストレージURLへの切り替え完了」という具体的な状態をポーリングしています。また、クリック後には toHaveClass(/node--selected/) によるアサーションを挿入することで、次のテストステップへ進む前に選択状態の確立を保証しています。これらを単一のヘルパー関数にカプセル化した点も重要で、同じ操作パターンが必要な将来のテストで再利用できるようになっています。

まとめ

本PRは、非同期な src スワッピングという実装の副作用に起因する競合状態を、テスト側で状態遷移を明示的に待機することで解消した変更です。固定遅延ではなくセレクタベースの待機とアサーションを組み合わせたヘルパー関数として実装することで、テストの信頼性と再利用性を同時に高めています。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
f31dd3c9

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文・背景・技術的変更・設計判断・まとめの「総論→各論→結論」構成が明確に守られており、理想的な記事構成です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(```javascript:test/...```)およびPR番号のリンク記法([PR #957](URL))が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

「フレーキーテスト」「競合状態」「srcスワッピング」といった専門用語を適切に用いており、専門知識を持つエンジニアという対象読者に適合しています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論から始まる構成になっており、各段落もトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が守られています。可読性が非常に高いです。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内で引用されている変更前・変更後のコード、および追加されたヘルパー関数のコードは、提供されたDiff情報と完全に一致しています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「競合状態」「セレクタ」「アサーション」「ヘルパー関数」などの技術用語が、文脈に沿って正確に使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

「srcスワッピングによる競合状態」という問題の原因と、「状態待機を含むヘルパー関数」という解決策の説明が、PRのDescriptionおよびDiffの内容と一致しており、技術的に正確です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内のすべての主張は、PRのDescriptionやDiff内のコードで裏付けられています。特に「設計判断」セクションは、コードから読み取れる設計思想を的確に言語化しており、ハルシネーションは見られません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号「#957」が正確に記載・リンクされています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

「添付ファイルテストの競合状態をsrc確定待ちで解消」というタイトルは、PRの「Fix flaky attachment tests」という内容をより具体的に、かつ正確に要約しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事の内容はPR情報に完全に準拠しており、バージョンサポート状況やリリース予定など、PR外の知識を持ち込んでいる箇所はありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「発生していた」「生じていました」といった過去形の表現が、既存の問題を修正したというPRの文脈と一致しており、時間表現は正確です。