Commit 4ecc55da authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch...

Merge branch '334719-include-all-gitlab_experiment-contexts-in-initial-trackpageview-event' into 'master'

Include all gitlab_experiment contexts in initial trackPageView event

See merge request gitlab-org/gitlab!64957
parents b4830cc6 766e72d7
// This file only applies to use of experiments through https://gitlab.com/gitlab-org/gitlab-experiment // This file only applies to use of experiments through https://gitlab.com/gitlab-org/gitlab-experiment
import { get } from 'lodash'; import { get, pick } from 'lodash';
import { DEFAULT_VARIANT, CANDIDATE_VARIANT, TRACKING_CONTEXT_SCHEMA } from './constants'; import { DEFAULT_VARIANT, CANDIDATE_VARIANT, TRACKING_CONTEXT_SCHEMA } from './constants';
function getExperimentsData() {
return get(window, ['gon', 'experiment'], {});
}
function convertExperimentDataToExperimentContext(experimentData) {
return { schema: TRACKING_CONTEXT_SCHEMA, data: experimentData };
}
export function getExperimentData(experimentName) { export function getExperimentData(experimentName) {
return get(window, ['gon', 'experiment', experimentName]); return getExperimentsData()[experimentName];
} }
export function getExperimentContexts(...experimentNames) { export function getExperimentContexts(...experimentNames) {
return experimentNames return Object.values(pick(getExperimentsData(), experimentNames)).map(
.map((name) => { convertExperimentDataToExperimentContext,
const data = getExperimentData(name); );
return data && { schema: TRACKING_CONTEXT_SCHEMA, data }; }
})
.filter((context) => context); export function getAllExperimentContexts() {
return Object.values(getExperimentsData()).map(convertExperimentDataToExperimentContext);
} }
export function isExperimentVariant(experimentName, variantName) { export function isExperimentVariant(experimentName, variantName) {
......
import { getAllExperimentContexts } from '~/experimentation/utils';
import { DEFAULT_SNOWPLOW_OPTIONS } from './constants'; import { DEFAULT_SNOWPLOW_OPTIONS } from './constants';
import getStandardContext from './get_standard_context'; import getStandardContext from './get_standard_context';
import Tracking from './tracking'; import Tracking from './tracking';
...@@ -41,7 +42,8 @@ export function initDefaultTrackers() { ...@@ -41,7 +42,8 @@ export function initDefaultTrackers() {
window.snowplow('enableActivityTracking', 30, 30); window.snowplow('enableActivityTracking', 30, 30);
// must be after enableActivityTracking // must be after enableActivityTracking
const standardContext = getStandardContext(); const standardContext = getStandardContext();
window.snowplow('trackPageView', null, [standardContext]); const experimentContexts = getAllExperimentContexts();
window.snowplow('trackPageView', null, [standardContext, ...experimentContexts]);
if (window.snowplowOptions.formTracking) { if (window.snowplowOptions.formTracking) {
Tracking.enableFormTracking(opts.formTrackingConfig); Tracking.enableFormTracking(opts.formTrackingConfig);
......
...@@ -37,6 +37,50 @@ describe('experiment Utilities', () => { ...@@ -37,6 +37,50 @@ describe('experiment Utilities', () => {
}); });
}); });
describe('getAllExperimentContexts', () => {
const schema = TRACKING_CONTEXT_SCHEMA;
let origGon;
beforeEach(() => {
origGon = window.gon;
});
afterEach(() => {
window.gon = origGon;
});
it('collects all of the experiment contexts into a single array', () => {
const experiments = [
{ experiment: 'abc', variant: 'candidate' },
{ experiment: 'def', variant: 'control' },
{ experiment: 'ghi', variant: 'blue' },
];
window.gon = {
experiment: experiments.reduce((collector, { experiment, variant }) => {
return { ...collector, [experiment]: { experiment, variant } };
}, {}),
};
expect(experimentUtils.getAllExperimentContexts()).toEqual(
experiments.map((data) => ({ schema, data })),
);
});
it('returns an empty array if there are no experiments', () => {
window.gon.experiment = {};
expect(experimentUtils.getAllExperimentContexts()).toEqual([]);
});
it('includes all additional experiment data', () => {
const experiment = 'experimentWithCustomData';
const data = { experiment, variant: 'control', color: 'blue', style: 'rounded' };
window.gon.experiment[experiment] = data;
expect(experimentUtils.getAllExperimentContexts()).toContainEqual({ schema, data });
});
});
describe('isExperimentVariant', () => { describe('isExperimentVariant', () => {
describe.each` describe.each`
gon | input | output gon | input | output
......
import { setHTMLFixture } from 'helpers/fixtures'; import { setHTMLFixture } from 'helpers/fixtures';
import { TRACKING_CONTEXT_SCHEMA } from '~/experimentation/constants'; import { TRACKING_CONTEXT_SCHEMA } from '~/experimentation/constants';
import { getExperimentData } from '~/experimentation/utils'; import { getExperimentData, getAllExperimentContexts } from '~/experimentation/utils';
import Tracking, { initUserTracking, initDefaultTrackers } from '~/tracking'; import Tracking, { initUserTracking, initDefaultTrackers } from '~/tracking';
import getStandardContext from '~/tracking/get_standard_context'; import getStandardContext from '~/tracking/get_standard_context';
jest.mock('~/experimentation/utils', () => ({ getExperimentData: jest.fn() })); jest.mock('~/experimentation/utils', () => ({
getExperimentData: jest.fn(),
getAllExperimentContexts: jest.fn(),
}));
describe('Tracking', () => { describe('Tracking', () => {
let standardContext; let standardContext;
...@@ -29,6 +32,7 @@ describe('Tracking', () => { ...@@ -29,6 +32,7 @@ describe('Tracking', () => {
beforeEach(() => { beforeEach(() => {
getExperimentData.mockReturnValue(undefined); getExperimentData.mockReturnValue(undefined);
getAllExperimentContexts.mockReturnValue([]);
window.snowplow = window.snowplow || (() => {}); window.snowplow = window.snowplow || (() => {});
window.snowplowOptions = { window.snowplowOptions = {
...@@ -100,6 +104,31 @@ describe('Tracking', () => { ...@@ -100,6 +104,31 @@ describe('Tracking', () => {
initDefaultTrackers(); initDefaultTrackers();
expect(trackLoadEventsSpy).toHaveBeenCalled(); expect(trackLoadEventsSpy).toHaveBeenCalled();
}); });
describe('when there are experiment contexts', () => {
const experimentContexts = [
{
schema: TRACKING_CONTEXT_SCHEMA,
data: { experiment: 'experiment1', variant: 'control' },
},
{
schema: TRACKING_CONTEXT_SCHEMA,
data: { experiment: 'experiment_two', variant: 'candidate' },
},
];
beforeEach(() => {
getAllExperimentContexts.mockReturnValue(experimentContexts);
});
it('includes those contexts alongside the standard context', () => {
initDefaultTrackers();
expect(snowplowSpy).toHaveBeenCalledWith('trackPageView', null, [
standardContext,
...experimentContexts,
]);
});
});
}); });
describe('.event', () => { describe('.event', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment