mcpField
A
analytics-tracking-testing

analytics-tracking-testing

github.com/petrkindlmannテスト・品質2221.0k 回インストール6 日前に更新
リポジトリ

analytics-tracking-testing について

ブラウザーのネットワークビーコンと型付きトラッキングプランを使って分析イベントを検証するテストスキルです。QAや開発チームがCIでイベント欠落、パラメーター誤り、同意状態の問題、重複コンバージョンを検出できます。

主な機能

  1. 01分析ビーコンのインターセプト
  2. 02型付きプランによるイベント検証
  3. 03dataLayer.push の内容確認
  4. 04同意状態に応じたイベント制御のテスト
  5. 05ピクセルと CAPI の重複排除確認
  6. 06CIでトラッキング回帰を検出

活用シーン

  1. 01リファクタリング後の GA4 イベント欠落検出
  2. 02ECイベントの金額と商品データ確認
  3. 03同意・拒否時の動作テスト
  4. 04購入コンバージョンの二重計上防止

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/petrkindlmann/qa-skills --skill analytics-tracking-testing

インストール後、Claude Code で/analytics-tracking-testingを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
capture-fixture.md
ci-gating.md
consent-mode.md
datalayer-capture.md
ga4-interception.md
news-media.md
pixels-and-dedup.md
tracking-plan.md

詳細

GA4 DebugView では「問題なさそう」に見えるトラッキングも、リファクタリング後にイベントがひそかに欠落したり、誤った通貨を送信したり、購入を二重計上したりすることがあります。`window.dataLayer` を読み取ったり、ボタンが `toBeVisible()` であることをアサートしたりしても、何の証明にもなりません。ビーコンがブラウザーの外へ送信されていない可能性があるためです。このスキルでは、実際のネットワークビーコン(`google-analytics.com/g/collect`、`facebook.com/tr`、`analytics.tiktok.com`、`px.ads.linkedin.com`)をインターセプトし、リクエストからイベント名とパラメーターを解析して、型付きの契約であるトラッキングプランと照合してアサートします。さらに、その契約を CI のゲートとして設定し、イベントが欠落した場合にビルドを失敗させます。

クイックルート

状況移動先
GA4 イベントが正しいパラメーターで 1 件発火したことをアサートするGA4 ビーコンのインターセプト
トラッキングプランを検証済みの契約として扱うトラッキングプランが契約です
dataLayer.push の形式を検証する(ビーコンではない)dataLayer.push のアサート
ピクセルとサーバーサイド CAPI の重複排除(event_id)ピクセルとサーバーサイドの重複排除
同意状態に応じてイベントの発火を制御するConsent Mode v2 による制御
すべてのピクセルを再利用可能なフィクスチャーで取得するreferences/capture-fixture.md
ニュースメディア:article-view、scroll-depth、paywallニュースメディアのイベント
トラッキングのリグレッションでビルドを失敗させるCI でのリグレッションゲート
イベントが数百件、ドメインが多数、チームが少人数購入するか、構築するか

確認事項

まず、プロジェクトルートの .agents/qa-project-context.md を確認し、すでに回答されている項目(スタック、タグマネージャー、同意管理プラットフォーム、対象環境)は省略してください。

  • 稼働中のトラッキング先はどれですか? GA4(/g/collect)、Meta Pixel(facebook.com/tr)、TikTok(analytics.tiktok.com)、LinkedIn(px.ads.linkedin.com)、アドテクタグなどがあります。それぞれエンドポイントの形式が異なるため、キャプチャーヘルパーはすべてを把握する必要があります。
  • GTM を使っていますか、それとも gtag をハードコードしていますか? GTM の場合、データはまず window.dataLayer.push を通り、その後 GTM がビーコンを発火します。push 層(入力契約)とビーコン(出力契約)の両方をアサートできますが、これは別々のテストです。
  • トラッキングプランはありますか? なければ、まず作成してください。これは、ほかのすべての検証の基準となる契約です。プランがなければ、客観的に合否を判定できません。
  • 同意管理プラットフォームとデフォルトの同意状態は何ですか? Consent Mode v2 によって、同意前に発火できるビーコンが変わります。テストを実行するには、CMP の承認/拒否セレクターが必要です。
  • クライアントとサーバー(CAPI)の重複排除を行っていますか? 購入イベントをクライアントの Pixel とサーバーの Conversions API の両方から発火する場合、event_id が一致しないと二重計上されます。正しさを判断するのはこの性質であり、「fbq が実行されたか」ではありません。
  • ニュースメディア向けの画面はありますか? 記事ページでは、一般的な e コマースのプランでは見落とされる article-view、scroll-depth のしきい値(25/50/75/100)、paywall-meter イベントが加わります。

基本原則

  1. ビーコンを捕捉し、DOM や dataLayer だけを信頼しないでください。 DOM を更新するボタンクリックや、GTM が黙って破棄する dataLayer.push では、GA4 のヒットは残りません。イベントが送信されたことを証明できるのは、collect エンドポイントへの送信リクエストだけです。ネットワークビーコンの URL パラメーターを検証してください。page.evaluate で window.dataLayer を読み取っても、push が実行されたことしか証明できず、ブラウザーから何かが送信されたことは証明できません。

  2. トラッキングプランはコメントではなく、型付きの契約です。 期待されるすべてのイベントを、必須パラメーターとその型を定めた外部スキーマ(JSON/YAML/TS インターフェース)に記述します。テストでは捕捉したイベントをスキーマに照らして検証し、不足しているパラメーター(missing)と型の違反(violations)を報告します。期待値を 1 つインラインでハードコードしても、ほかの 20 個のパラメーターは検証されず、プランを変更した途端に陳腐化します。

  3. 購入において本当に重要な正しさの条件は、重複排除です。 fbevents.js が読み込まれたことを確認したり、fbq('track','Purchase') の実行回数を数えたりしても、二重計上を見逃してしまいます。重要なのは、ブラウザーの Pixel とサーバーの CAPI が同じ event_id/eventID を送信し、Meta がそれらを 1 件のコンバージョンにまとめることです。

  4. 同意状態は入力の次元です。 承認済みの地域ポリシーを、基本モードまたは詳細モードでテストします。アプリケーションの実際の 4 つのシグナルのデフォルト値と更新を観察し、テストからデフォルト値を与えないでください。基本モードでは同意前にタグがブロックされますが、詳細モードでは Cookie なしで許可された計測が送信される場合があります。計画された同意後のイベントと、関連するストレージをそれぞれ独立して検証してください。

  5. 実際のユーザー操作を行い、時間ではなくリクエストを待ってください。 スクロール深度イベントは、実際のスクロール(mouse.wheel、scrollIntoView、evaluate(scrollTo))によって発火させ、waitForTimeout ではなく waitForRequest でビーコンを待ちます。固定時間のスリープは不安定で、検出すべきタイミングの不具合を隠してしまいます。

  6. ビルドを失敗させられないトラッキングテストは、見せかけにすぎません。 「GA4 DebugView で確認する」や「本番環境を監視する」では、リグレッションを防げません。契約は CI で実行し、イベントが欠落した場合や必須パラメーターが不足した場合に、ゼロ以外の終了コードを返す必要があります。


GA4 ビーコンのインターセプト

GA4 のウェブタグは /g/collect リクエストを使用します。POST 本文に複数のイベントが含まれ、クエリに共通フィールドが含まれる場合もあります。以下のパーサーは、観測されたウェブタグ形式に対応するものであり、公開されている JSON Measurement Protocol には対応していません。デプロイ済みのタグバージョンで取得したキャプチャを保持してください。ファーストパーティプロキシやサーバーサイドの収集には、明示的なアダプターが必要です。リクエストによって確認できるのはブラウザーからの送信であり、その後の取り込みの成功ではありません。

検証対象となる GA4 /g/collect URL の文法:

Param意味例
v=2観測されたウェブタグのトランスポートにおけるバージョンフィールドv=2
tid=G-XXXXXXX測定 IDtid=G-ABC123
en=イベント名en=add_to_cart
ep.<name>=カスタムイベントパラメーター、型は 文字列ep.campaign_label=spring
epn.<name>=イベントパラメーター、型は 数値epn.value=49.99
gcs= / gcd=同意状態(Consent Mode v2 のセクションを参照)gcs=G111

ワイヤー上の型情報を保持してください。カスタムパラメーターには ep. または epn. を使用できますが、予約済みの e コマースフィールドと商品アイテムには、それぞれ独自のウェブタグエンコーディングがあります。標準の通貨が ep.currency である、または商品アイテム ID がフラットな ep.item_id であると決めつけないでください。Google の論理的な e コマース仕様では、イベントレベルの currency とネストされた items[] が使用されます。その仕様を検証する前に、キャプチャでテスト済みのアダプターを介して、観測されたトランスポートをデコードしてください。

単一のイベントを想定する場合は page.waitForRequest を、複数のイベントを収集する場合は page.on('request', ...) を使用してインターセプトします。アクションの前にリスナーを設定してください。完全一致する /g/collect パスと、承認済みのホスト名で照合します。references/ga4-interception.md の parseGA4 を使い、各 POST イベントのパラメーターを URL クエリにマージしてください。URL だけの照合では、バッチ処理されたイベントを見落とします。テスト用プロパティまたはローカルコレクターを使用して、本番のアナリティクスを汚染しないようにしてください。

以下は、下記のパーサーと、アプリケーションで検証済みの e コマースデコーダーおよび論理トラッキングプランを組み合わせるパターンです。decodeEcommerceWebEvent はプロジェクトで実装が必要なアダプターであり、このスキルが提供するパッケージには含まれません。サポートされていないワイヤーフィールドや欠落したワイヤーフィールドがあれば、失敗させる必要があります。references/ga4-interception.md と references/tracking-plan.md を参照してください。

test('add_to_cart fires with correct params', async ({ page }) => {
  await page.goto('/product/42');
  const [request] = await Promise.all([
    page.waitForRequest(r => parseGA4(r).some(event => event.name === 'add_to_cart')),
    page.getByRole('button', { name: 'Add to cart' }).click(),
  ]);
  const events = parseGA4(request).filter(event => event.name === 'add_to_cart');
  expect(events).toHaveLength(1);
  const params = events[0].params;
  expect(params.tid).toBe('G-TEST'); // use the test property's exact measurement ID
  // Application adapter, checked against redacted captures from the deployed tag.
  const payload = decodeEcommerceWebEvent(params);
  expect(validateEvent(plan, 'add_to_cart', payload)).toEqual([]);
  expect(payload).toMatchObject({
    currency: 'USD', value: 49.99,
    items: [{ item_id: 'SKU-42', price: 49.99, quantity: 1 }],
  });
});

唯一のアサーションとして page.evaluate(() => window.dataLayer) に置き換えたり、ボタンに対する toBeVisible() や、「ビーコンの送信を待つ」ための waitForTimeout() を使用したりしないでください。バッチイベントの解析(GA4 は複数のイベントを 1 つの POST 本文にまとめることがあります)とリージョンエンドポイントの処理については、references/ga4-interception.md を参照してください。


トラッキングプランが契約です

トラッキングプランが信頼できる情報源です。各イベントについて、名前、必須パラメーター、および各パラメーターの型を定めます。アプリチームとテストの両方がインポートするバージョン管理されたファイル(tracking-plan.json / .yaml、または TS の interface / Zod スキーマ)として保持してください。テストではキャプチャしたイベントを読み込み、プランと照合して検証します。つまり、スキーマと既知のシナリオ値をチェックします。

正規化された論理ペイロードを検証し、欠落フィールドと型違反をすべて返します。references/tracking-plan.md のヘルパーは、有限数、空でない文字列、ネストされた空でない商品アイテム配列をチェックします。サポートされていないスキーマや空のスキーマは拒否します。0 は有効な数値です。フィールドの欠落、空文字列、null、Infinity、数値文字列は、型付きの 0 ではありません。スキーマのチェック後に、シナリオ固有の期待値を追加してください。

const payload = decodeEcommerceWebEvent(capturedGA4Event.params); // capture-tested project adapter
expect(validateEvent(plan, 'add_to_cart', payload)).toEqual([]);
expect(payload.currency).toBe('USD');
expect(payload.value).toBe(49.99);
expect(payload.items).toEqual([{ item_id: 'SKU-42', price: 49.99, quantity: 1 }]);

スキーマが一致しても、価格が正しいことは証明できません。ペイロードを既知のテスト用カートと照合し、アプリケーションのトラッキング完了時点でイベント数を検証してください。デコーダーが欠落フィールド、タグの変換、または購入イベントの重複を隠せないよう、生の入力イベントと生の出力レコードを保持してください。


dataLayer.push のアサーション

質問が GTM の入力、つまり「ページの読み込み時に、正しいオブジェクトが dataLayer にプッシュされるか」である場合は、GA4 のビーコンではなくプッシュをアサートします。これはビーコンの傍受とは逆です。ここでは dataLayer のプッシュそのものが対象です。

ナビゲーションの前に、references/datalayer-capture.md のパッシブオブザーバーをインストールします。 data layer が存在しない場合はそのままにし、アプリケーションによる最初の代入を監視して、 プッシュの動作を維持し、後から置き換えられたり監視できなくなったりした場合はフラグを立てます。 アプリケーションのセットアップを計測するテストでは、アプリケーションのキューを初期化したり 修復したりしないでください。キャプチャしたオブジェクトを調べる前に、アプリケーションからの完了シグナルを使用します。

GTM の ecommerce オブジェクトイベントでは、各商品の想定 ID、価格、数量とともに、 ecommerce.currency、ecommerce.value、ecommerce.items[] をアサートします。Google の ecommerce 契約では、通貨はイベントレベルです。 件数と構造の両方を確認してください。最初に一致したイベントだけを選ぶと、重複が隠れてしまいます。 直接の gtag コマンド配列には、オブジェクトイベントパーサーではなく、対応するコマンドアダプターが必要です。

このリファレンスには、オブザーバーと完全な例が記載されています。トラッキング経路全体が対象となる場合は、 観測した入力とネットワーク出力の両方を使用し、それぞれの観測で何が確認できるかを記録します。


ピクセルとサーバーサイドの重複排除

マーケティングピクセルは独自のビーコンを送信します。傍受するエンドポイントは次のとおりです。

宛先エンドポイントイベントパラメーター重複排除キー
Meta Pixelfacebook.com/tr(/tr? も)ev=PageView、ev=Purchaseeid / event_id
TikTokanalytics.tiktok.com本文/パラメーター内のイベントevent_id
LinkedInpx.ads.linkedin.comコンバージョン ID—

Meta の場合、connect.facebook.net/en_US/fbevents.js が読み込まれたことや、fbq('track','Purchase') が実行されたことをアサートするのは、読み込み/回数の確認にすぎません。正しさの証明にはなりません。クライアント側(Pixel)とサーバー側(Conversions API / CAPI)の両方で発火する Purchase の正しさを保証するのは、重複排除です。両方に同じ event_id が含まれている必要があります。そうすれば Meta は両者を 1 件のコンバージョンとして統合し、二重計上を防げます。

テストでは、ブラウザーの facebook.com/tr ビーコンから ev=Purchase をキャプチャして event_id を読み取り、サーバーが CAPI に送信した event_id(モック/キャプチャしたサーバー呼び出し、または既知のフィクスチャ値)と一致することをアサートします。ひな形:

const [pixel] = await Promise.all([
  page.waitForRequest(r => r.url().includes('facebook.com/tr') && r.url().includes('ev=Purchase')),
  completeCheckout(page),
]);
const clientEventId = new URL(pixel.url()).searchParams.get('eid'); // event_id on the wire
expect(clientEventId).toBe(serverCapiEventId); // deduplicates against the server CAPI event

TikTok/LinkedIn のペイロードの解析と、サーバー CAPI 呼び出しのキャプチャについては、references/pixels-and-dedup.md を参照してください。


Consent Mode v2 のゲーティング

ゲートを作成する前に、承認済みの地域別デフォルトと、ベーシックまたはアドバンスドの実装を選択してください。参考資料の例では、すべて拒否するデフォルトポリシーを使用しています。 Google の同意モードの概要を参照してください。

このポリシーに照らして、4 つのシグナルすべてを確認します。

シグナル対象
ad_storage広告 Cookie
analytics_storageアナリティクス Cookie
ad_user_data広告用に Google へ送信するユーザーデータ
ad_personalizationパーソナライズ広告/リマーケティング

すべてのテストで、ナビゲーション前にパッシブオブザーバーを設定してください。gtag を作成したり、同意コマンドを送信したり、置き換えられたデータレイヤーを修復したりしてはなりません。デフォルト設定の欠落、早すぎる計測コマンド、不正な中間状態があれば、テストを失敗させてください。

同意前: ベーシックモードでは、設定済みのタグリクエストをブロックします。アドバンスドモードでは、イベントプランの拒否状態の ping を送信できます。実際のアプリケーション完了シグナルと、宣言済みの観測間隔を確認してください。コレクターに何も記録されていないことや、networkidle は、遅延トラッキングが正しく動作している証拠にはなりません。ベーシックモードのデフォルトは、同意が得られた後に初期化できます。

同意後: 既存のコマンドとイベントをチェックポイントに記録し、CMP ボタンをクリックして、新たに一致する更新と新たに期待されるビーコンを必須にします。拒否、部分的な同意、撤回、同意の永続化についても、それぞれ独立して繰り返してください。

キャプチャしたウェブタグのトランスポートでは、gcs=G100 と gcs=G111 により、2 つのストレージシグナルを区別できます。gcd の存在は診断情報であり、4 つのシグナルすべてやペイロード識別子が正しいことの証明にはなりません。バージョン管理されたトランスポートのキャプチャを保持し、観測した 4 つの状態と承認済みのペイロード/ストレージ一覧を使用してください。文書化されていない gcd のプレフィックスには依存しないでください。実行可能なヘルパーとレシピについては、references/consent-mode.md を参照してください。

特定の同意状態でビーコンが法的に 許可されるかどうか は compliance-testing の対象です。このスキルでは、ビーコンが発火した 場合に、そのデータと同意パラメーターが正しいことを検証します。


ニュースメディアのイベント

ニュースサイトや出版社のサイトには、一般的な e コマースのプランでは見落とされるトラッキング対象があります。次の 3 つすべてをカバーしてください。

  • article_view(または article-view):記事の読み込み時に、記事のメタデータ(ID、セクション、著者)を含むビーコンが 1 回発火することを検証します。
  • スクロール深度:25/50/75/100 パーセントのしきい値で、実際のスクロールに基づいて各区分につき 1 つのイベントを発火させます。
  • ペイウォール/メーター:無料記事の閲覧上限に達したとき、paywall_hit(またはメーター)イベントを発火させます。

実際の操作(mouse.wheel、element.scrollIntoView、または page.evaluate(() => window.scrollTo(...))/scrollBy)でスクロールし、waitForTimeout ではなく、ビーコン(waitForRequest またはキャプチャ済みイベントのリスト)を待ってください。固定時間のスリープを使ったスクロールは、テストを不安定にするだけでなく、しきい値タイミングのバグを見逃す原因にもなります。

const buckets = [25, 50, 75, 100];
for (const pct of buckets) {
  const [req] = await Promise.all([
    page.waitForRequest(r => r.url().includes('/g/collect') && r.url().includes('en=scroll')),
    page.evaluate(p => window.scrollTo(0, document.body.scrollHeight * (p / 100)), pct),
  ]);
  expect(new URL(req.url()).searchParams.get('epn.percent_scrolled')).toBe(String(pct));
}

記事メタデータ、重複排除した 4 つのスクロール区分、ペイウォール/メーターイベントを含むフルスイートについては、references/news-media.md を参照してください。


複数ピクセルのキャプチャフィクスチャ

各テストでビーコンのキャプチャ処理を再実装しないでください。page.on('request', ...) でリッスンする再利用可能な Playwright フィクスチャ(test.extend)を作成し、すべての送信先エンドポイント(GA4 の /g/collect、facebook.com/tr、analytics.tiktok.com、px.ads.linkedin.com)に一致させ、各リクエストの new URL(...).searchParams と postData() を解析し、正規化した { destination, eventName, params } を collected 配列に追加して、テストから検証できるようにします。

重要な注意点:キャプチャヘルパーは観測するものでなければなりません。そのため、page.on('request')(または route.continue() を呼び出す page.route)を使い、page.route(...).abort() は決して使わないでください。中断すると、確認しようとしているビーコン自体がブロックされます。また、GA4 だけでなくピクセルもキャプチャしなければなりません。フィクスチャ全体については、references/capture-fixture.md を参照してください。


CI でのリグレッションゲート

このゲートでは、捕捉したイベントとトラッキングプランのベースラインを比較し、リリース後に以前発火していたイベントが発火しなくなった場合や、必須パラメーターが欠落した場合にビルドを失敗させます(終了コードはゼロ以外)。Playwright プロジェクトとして構成し、ジャーニーを実行してフィクスチャ経由ですべてのビーコンを捕捉し、それぞれをプランに照らして検証します。missing/ドロップされたイベントがあるとテストの expect が失敗し、Playwright はゼロ以外の終了コードで終了するため、GitHub Actions(または任意の CI)のジョブは失敗になります。

ゲートを「GA4 DebugView を手動で確認する」「本番トラフィックに対してのみ実行する」「警告だけ出して成功扱いにする」といった形にしないでください。いずれもリグレッションを防げません。ベースラインとの差分を確認する実行は、マージ前の PR CI に組み込みます。ワークフロー YAML、ベースライン差分スクリプト、ジョブのサマリーに必須パラメーターの欠落を表示する方法については、references/ci-gating.md を参照してください。


購入するか、構築するか

CI でゲートする重要なジャーニーが少数で、対象イベントが限られている場合は、Playwright による DIY のインターセプトが適しています。規模が大きくなると、効果は薄れます。イベントが数百件に及び、ドメインが多く、少人数のチームで、本番環境の継続的な/ドリフト監視(マージ前の CI ゲートでは検知できない、午前 2 時にマーケターが GTM で壊したタグを検知するなど)が必要な場合です。

観点構築(Playwright)購入
イベントが少数、重要なジャーニー、マージ前のゲート最適過剰
イベントが数百件、ドメインが多数メンテナンスの負担が大きい購入
24 時間 365 日の本番環境のドリフト監視CI の対象外購入
少人数のチーム、高いカバレッジの要求構築コストが高すぎる購入

現在、実際に利用できる有料サービスとして挙げる価値があるもの:

  • Trackingplan — Web、モバイル、サーバーサイドのライブトラフィックを常時/継続的に監視します。定期的なチェックよりもリアルタイムのドリフト検知が必要な場合に特に適しています。
  • ObservePoint — トラッキングプランに照らしたジャーニーの定期スキャン/監査を実施します。定期的なガバナンスにおいて実績があります。

Segment Protocols を唯一の検証手段として推奨しないでください(Segment を経由するデータを管理するものであり、任意のクライアントビーコンを対象とするものではありません)。また、Google Tag Assistant を CI ゲートと呼ぶのは避けてください。これは対話型のデバッグツールであり、自動化された合否判定ツールではありません。判断は、規模、ドメインの多さ、メンテナンスの負担、継続的な監視といった、DIY の効果が薄れ始める要因に基づいてください。


アンチパターン

1. ビーコンではなく window.dataLayer(または DOM)をアサートする

page.evaluate(() => window.dataLayer) で確認できるのは push が発生したことだけで、GA4 が何かを送信したことではありません。toBeVisible() でトラッキングについて何かを証明することもできません。/g/collect リクエストをインターセプトし、その en= と ep./epn. パラメーターをアサートしてください。(唯一の例外は、push 自体が契約である場合です。dataLayer.push を参照してください。ただしその場合も、代わりに GA4 ビーコンを確認してはいけません。)

2. 「イベントの発火を待つ」ために waitForTimeout を使う

固定時間のスリープはテストを不安定にし、タイミングのバグを隠します。リクエストを待機してください:page.waitForRequest(r => r.url().includes('/g/collect'))。

3. イベント名だけをアサートする

イベント名だけのアサートでは、通貨、値、item_id が誤っていてもテストが成功します。トラッキングプランに照らして、すべての必須パラメーターとその型を検証してください。

4. プランファイルを使わず、期待値をインラインでハードコードする

信頼できる唯一の情報源が存在しないため、スイート全体でのパラメーター名の変更を検知できません。プランは外部ファイルとして保持し、それに照らして検証してください。

5. ピクセルの読み込み/回数を確認する(fbevents.js が読み込まれた、fbq が実行された)

どちらもコンバージョンが正しく記録されたことや、重複排除されたことを証明しません。Purchase では、クライアントとサーバーの event_id が一致することをアサートしてください。

6. テストで指定したデフォルト値を検証する

同意拒否をシードすると、アプリケーションが独自のデフォルト値を設定していないことが隠れる場合があります。選択したポリシーに照らして、実際の 4 つのシグナルすべてを確認し、基本モードと高度なモードを区別してください。

7. 捕捉ヘルパー内で page.route(...).abort() を使う

中断すると、観察するはずだったビーコンがブロックされます。page.on('request')(または route.continue())を使ってください。

8. ビルドを失敗させられない「ゲート」

GA4 DebugView、本番環境専用のモニタリング、警告だけで成功扱いにする仕組みでは、リグレッションを阻止できません。イベントが欠落した場合や必須パラメーターが不足した場合に、CI がゼロ以外の終了コードを返すようにしてください。


検証

まずは最小限のチェックから始めましょう。成功した実行結果をただ信頼するのではなく、テストスイートが実際にリグレッションを検出することを確認してください。

  • 1 つのイベント、1 つのビーコン: npx playwright test -g add_to_cart が成功し、トレース(--trace on)に en=add_to_cart を含むキャプチャ済みの /g/collect リクエストが表示されます。一致するリクエストがトレースにないのにテストが成功する場合は、誤った対象をアサートしています。
  • ゲートで失敗することを確認: ブランチ内で必須パラメーターの名前を変更し(例:アプリ内の value → amount)、CI プロジェクトを再実行します。ビルドは missing/違反を示すメッセージとともに、ゼロ以外の終了コードを返す必要があります。それでも成功するなら、そのゲートは見せかけです。
  • 同意ゲートが誤ったアプリ状態を検出することを確認: 実際のデフォルト値が選択したポリシーと一致していることを確認します。デフォルト値がない場合や、許可状態の場合は、すべて拒否するポリシー用のフィクスチャで失敗する必要があります。新しいアクションには、新しい更新と計画済みイベントが必要です。正常なフィクスチャと意図的に壊した基本・高度なフィクスチャの両方で、期待どおりの結果が得られることを確認します。
  • 重複排除が機能することを確認: facebook.com/tr?ev=Purchase のクライアント eid が、同じ注文のサーバー CAPI event_id と一致することを確認します。値が異なると、Meta で二重計上されます。

完了条件

  • 計測対象の各イベントについて、実際の収集エンドポイントのビーコン(/g/collect、facebook.com/tr など)をインターセプトし、searchParams/postData から en=/ev= とパラメーターを解析するテストがあります。DOM のみ、または dataLayer のみを対象とするアサーションは使いません。
  • 必須パラメーターと型を定義した、バージョン管理された計測プランファイル(JSON/YAML/TS)があります。テストではキャプチャしたイベントをこのファイルに照らして検証し、イベント名だけでなく missing/型の違反も報告します。
  • Purchase(またはクライアントとサーバーの両方で送信するイベント)には重複排除のアサーションがあります。クライアントのビーコン event_id がサーバー CAPI の event_id と一致します。
  • 同意テストでは実際の 4 つのシグナルをすべて確認し、設定されたイベントを必須としたうえで、ストレージの状態を承認済みの地域別/基本/高度なポリシーと照合します。検証対象の同意状態を事前に設定することはありません。トランスポートの診断には明示された制限があります。
  • 再利用可能なキャプチャフィクスチャ(test.extend)で GA4、Meta、TikTok、LinkedIn のビーコンを収集します。各テストでキャプチャを再実装せず、キャプチャヘルパーから route.abort() を呼び出すこともありません。
  • ニュースメディアのページ(該当する場合)では、article_view、実際のスクロール操作による 25/50/75/100 のスクロール深度、ペイウォール/メーターイベントを網羅します。いずれも waitForRequest を使用し、waitForTimeout は使用しません。
  • CI ジョブでテストスイートを実行し、キャプチャしたイベントと計測プランのベースラインを比較して、イベントが欠落した場合や必須パラメーターが不足した場合にゼロ以外の終了コードを返します。意図的に壊したタグによってビルドが失敗することを確認済みです。

関連スキル

  • compliance-testing — GDPR/CMP の同意法、Cookie 同意 UI、データ主体の権利に基づき、ビーコンの送信が許可されているかを扱います。このスキルではビーコンの送信が許可されていることを前提とし、データが正しいかを確認します。合法性の確認にはこちらを参照してください。
  • playwright-automation — ページオブジェクトモデル、フィクスチャ、設定、およびこのスキルがインターセプトの基盤とする一般的な E2E パターンを扱います。
  • api-testing — 重複排除のサーバー側を検証する必要がある場合に、サーバー側の Conversions API/Measurement Protocol 呼び出しを直接検証します(リクエスト本文、認証、レスポンス)。
  • qa-project-context — このスキルの調査時に最初に確認する、技術スタック、タグマネージャー、同意プラットフォーム、対象環境を扱います。

参照ファイル(references/ 内)

  • ga4-interception.md — GA4 /g/collect の完全なインターセプトヘルパー、バッチイベントの POST 本文の解析、リージョンエンドポイントの処理。
  • tracking-plan.md — JSON の E コマース契約、再利用可能な validateEvent ヘルパー、スキーマとシナリオ値それぞれのアサーション。
  • datalayer-capture.md — addInitScript による dataLayer.push ラッパーと、E コマースの items[] 形式のアサーション。
  • pixels-and-dedup.md — Meta/TikTok/LinkedIn のペイロード解析と、クライアント側とサーバー側の CAPI event_id 重複排除のキャプチャ。
  • consent-mode.md — 4 つのシグナルのパッシブな監視、基本および高度なレシピ、アクションのチェックポイント、完了シグナル、範囲を限定した gcs=/gcd= の診断。
  • news-media.md — article_view、重複排除された 25/50/75/100 のスクロール区分、ペイウォールのメーターイベントテスト。
  • capture-fixture.md — 再利用可能なマルチピクセルの test.extend キャプチャフィクスチャ。
  • ci-gating.md — GitHub Actions のワークフロー、ベースライン差分スクリプト、不足パラメーターの失敗の提示。

コメント