in support-frontend/assets/helpers/abTests/abtest.ts [224:396]
function getAmountsTestVariant(
country: IsoCountry,
countryGroupId: CountryGroupId,
settings: Settings,
path: string = window.location.pathname,
mvt: number = getMvtId(),
acquisitionDataTests: AcquisitionABTest[] = getTestFromAcquisitionData() ??
[],
): GetAmountsTestVariantResult {
const { amounts } = settings;
if (!amounts) {
return {
selectedAmountsVariant: getFallbackAmounts(countryGroupId),
};
}
const buildParticipation = (
test: AmountsTest,
testName: string,
variantName: string,
): Participations | undefined => {
// Check if we actually want to track this test
const pathMatches = targetPageMatches(
path,
'/??/checkout|one-time-checkout|contribute|thankyou(/.*)?$',
);
if (pathMatches && test.variants.length > 1 && test.isLive) {
return {
[testName]: variantName,
};
}
return;
};
const contribOnlyAmounts = amounts.find((t) => {
return (
t.isLive &&
t.testName === contributionsOnlyAmountsTestName &&
t.targeting.targetingType === 'Country' &&
t.targeting.countries.includes(country)
);
});
if (contribOnlyAmounts?.variants[0]) {
const amountsParticipation = buildParticipation(
contribOnlyAmounts,
contributionsOnlyAmountsTestName,
contribOnlyAmounts.variants[0].variantName,
);
return {
selectedAmountsVariant: {
...contribOnlyAmounts.variants[0],
testName: contributionsOnlyAmountsTestName,
},
amountsParticipation,
};
}
// Is an amounts test defined in the url?
const urlTest = getAmountsTestFromURL(acquisitionDataTests);
if (urlTest) {
// Attempt to find urlTest in the configured amounts tests
const candidate = amounts.find((t) => {
if (t.isLive) {
return t.liveTestName === urlTest.name;
} else {
return t.testName === urlTest.name;
}
});
if (candidate) {
const variants = candidate.variants;
if (variants.length) {
const variant =
variants.find((variant) => variant.variantName === urlTest.variant) ??
variants[0];
if (variant) {
const amountsParticipation = buildParticipation(
candidate,
urlTest.name,
variant.variantName,
);
return {
selectedAmountsVariant: {
...variant,
testName: urlTest.name,
},
amountsParticipation,
};
}
}
}
}
// No url test was found, use targeting
let targetedTest: AmountsTest | undefined;
// First try country-targeted tests
const source = getSourceFromAcquisitionData() ?? '';
const enableCountryTargetedTests = !['APPLE_NEWS', 'GOOGLE_AMP'].includes(
source,
);
if (enableCountryTargetedTests) {
const countryTargetedTests = amounts
.filter(
(t) =>
t.isLive &&
t.targeting.targetingType === 'Country' &&
t.targeting.countries.includes(country),
)
.sort((a, b) => a.order - b.order);
if (countryTargetedTests[0]) {
targetedTest = countryTargetedTests[0];
}
}
// Then try region-targeted tests
if (!targetedTest) {
targetedTest = amounts.find(
(t) =>
t.targeting.targetingType === 'Region' &&
t.targeting.region === countryGroupId,
);
}
if (!targetedTest) {
return {
selectedAmountsVariant: getFallbackAmounts(countryGroupId),
};
}
const { testName, liveTestName, seed, variants, isLive } = targetedTest;
const selectVariant = (
isLive: boolean,
variants: AmountsVariant[],
): AmountsVariant | undefined => {
if (isLive && variants.length > 1) {
const assignmentIndex = randomNumber(mvt, seed) % variants.length;
return variants[assignmentIndex];
}
// For regional AmountsTests, if the test is not live then we use the control
return variants[0];
};
const currentTestName = isLive && liveTestName ? liveTestName : testName;
const variant = selectVariant(isLive, variants);
const amountsParticipation = buildParticipation(
targetedTest,
currentTestName,
variant?.variantName ?? '',
);
if (!variant) {
return {
selectedAmountsVariant: getFallbackAmounts(countryGroupId),
};
}
return {
selectedAmountsVariant: {
...variant,
testName: currentTestName,
},
amountsParticipation,
};
}