From fef53e5737f3e7262beb35b6f575be804bac523f Mon Sep 17 00:00:00 2001 From: Brian Giori Date: Tue, 15 Oct 2024 14:23:08 -0700 Subject: [PATCH] feat: track impressions for web experiments (#127) --- .../src/integration/manager.ts | 25 +++++++++-- .../experiment-browser/test/client.test.ts | 44 ++++++++++--------- .../test/integration/manager.test.ts | 21 +++++++++ 3 files changed, 67 insertions(+), 23 deletions(-) diff --git a/packages/experiment-browser/src/integration/manager.ts b/packages/experiment-browser/src/integration/manager.ts index 2f4994e..d8508aa 100644 --- a/packages/experiment-browser/src/integration/manager.ts +++ b/packages/experiment-browser/src/integration/manager.ts @@ -96,11 +96,30 @@ export class IntegrationManager { */ track(exposure: Exposure): void { if (this.cache.shouldTrack(exposure)) { - this.queue.push({ - eventType: '$exposure', + const event = this.getExposureEvent(exposure); + this.queue.push(event); + } + } + + private getExposureEvent(exposure: Exposure): ExperimentEvent { + let event: ExperimentEvent = { + eventType: '$exposure', + eventProperties: exposure, + }; + if (exposure.metadata?.exposureEvent) { + // Metadata specifically passes the exposure event definition + event = { + eventType: exposure.metadata?.exposureEvent as string, + eventProperties: exposure, + }; + } else if (exposure.metadata?.deliveryMethod === 'web') { + // Web experiments track impression events by default + event = { + eventType: '$impression', eventProperties: exposure, - }); + }; } + return event; } } diff --git a/packages/experiment-browser/test/client.test.ts b/packages/experiment-browser/test/client.test.ts index 4e7a81f..235e9f5 100644 --- a/packages/experiment-browser/test/client.test.ts +++ b/packages/experiment-browser/test/client.test.ts @@ -676,26 +676,30 @@ describe('variant fallbacks', () => { expect(spy.mock.calls[0][0].variant).toBeUndefined(); }); - test('default variant returned when no other fallback is provided', async () => { - const user = {}; - const exposureTrackingProvider = new TestExposureTrackingProvider(); - const spy = jest.spyOn(exposureTrackingProvider, 'track'); - const client = new ExperimentClient(API_KEY, { - exposureTrackingProvider: exposureTrackingProvider, - source: Source.LocalStorage, - fetchOnStart: true, - }); - mockClientStorage(client); - // Start and fetch - await client.start(user); - const variant = client.variant('sdk-ci-test'); - expect(variant.key).toEqual('off'); - expect(variant.value).toBeUndefined(); - expect(variant.metadata?.default).toEqual(true); - expect(spy).toHaveBeenCalledTimes(1); - expect(spy.mock.calls[0][0].flag_key).toEqual('sdk-ci-test'); - expect(spy.mock.calls[0][0].variant).toBeUndefined(); - }); + test( + 'default variant returned when no other fallback is provided', + async () => { + const user = {}; + const exposureTrackingProvider = new TestExposureTrackingProvider(); + const spy = jest.spyOn(exposureTrackingProvider, 'track'); + const client = new ExperimentClient(API_KEY, { + exposureTrackingProvider: exposureTrackingProvider, + source: Source.LocalStorage, + fetchOnStart: true, + }); + mockClientStorage(client); + // Start and fetch + await client.start(user); + const variant = client.variant('sdk-ci-test'); + expect(variant.key).toEqual('off'); + expect(variant.value).toBeUndefined(); + expect(variant.metadata?.default).toEqual(true); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy.mock.calls[0][0].flag_key).toEqual('sdk-ci-test'); + expect(spy.mock.calls[0][0].variant).toBeUndefined(); + }, + 10 * 1000, + ); }); describe('initial variants source', () => { diff --git a/packages/experiment-browser/test/integration/manager.test.ts b/packages/experiment-browser/test/integration/manager.test.ts index f12f47d..e93fe8a 100644 --- a/packages/experiment-browser/test/integration/manager.test.ts +++ b/packages/experiment-browser/test/integration/manager.test.ts @@ -178,6 +178,27 @@ describe('IntegrationManager', () => { }, }); }); + test('web exposure tracked as impression', () => { + manager.track({ + flag_key: 'flag-key', + variant: 'treatment', + experiment_key: 'exp-1', + metadata: { + deliveryMethod: 'web', + }, + }); + expect(manager['queue']['inMemoryQueue'][0]).toEqual({ + eventType: '$impression', + eventProperties: { + flag_key: 'flag-key', + variant: 'treatment', + experiment_key: 'exp-1', + metadata: { + deliveryMethod: 'web', + }, + }, + }); + }); }); });