Skip to content

Commit

Permalink
feat: track impressions for web experiments (#127)
Browse files Browse the repository at this point in the history
  • Loading branch information
bgiori authored Oct 15, 2024
1 parent a6570eb commit fef53e5
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 23 deletions.
25 changes: 22 additions & 3 deletions packages/experiment-browser/src/integration/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down
44 changes: 24 additions & 20 deletions packages/experiment-browser/test/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
21 changes: 21 additions & 0 deletions packages/experiment-browser/test/integration/manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
},
},
});
});
});
});

Expand Down

0 comments on commit fef53e5

Please sign in to comment.