Skip to content

Commit

Permalink
Merge pull request #6713 from guardian/pd/landing-page-abtest-benefit…
Browse files Browse the repository at this point in the history
…-reset

Landing Page :  abtest benefits reset test
  • Loading branch information
paul-daniel-dempsey authored Jan 22, 2025
2 parents de60a81 + e79ad09 commit 526d7ac
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ const listCss = (style: CheckListStyle) => css`
}
}
`;
const opaqueCss = css`
opacity: 0;
`;

export type BenefitsCheckListData = {
isChecked: boolean;
Expand All @@ -91,15 +94,13 @@ export type BenefitsCheckListProps = {
function ChecklistItemIcon({
checked,
style,
hideBullet,
}: {
checked: boolean;
style: CheckListStyle;
hideBullet?: boolean;
}): JSX.Element {
const styleSize = style === 'standard' ? 'small' : 'xsmall';
return style === 'bullet' ? (
<BulletSvg opacity={hideBullet ? 0 : 1} />
<BulletSvg />
) : checked ? (
<SvgTickRound isAnnouncedByScreenReader size={styleSize} />
) : (
Expand Down Expand Up @@ -129,12 +130,13 @@ export function BenefitsCheckList({
item.maybeGreyedOut,
]}
>
<div css={style === 'standard' ? iconContainerCss : css``}>
<ChecklistItemIcon
checked={item.isChecked}
style={style}
hideBullet={item.hideBullet}
/>
<div
css={[
style === 'standard' ? iconContainerCss : css``,
item.hideBullet ? opaqueCss : css``,
]}
>
<ChecklistItemIcon checked={item.isChecked} style={style} />
</div>
</div>
)}
Expand Down
15 changes: 2 additions & 13 deletions support-frontend/assets/components/checkoutBenefits/bulletSvg.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { palette } from '@guardian/source/foundations';

type BulletSvgProps = {
opacity?: number;
};
export default function BulletSvg({
opacity = 1,
}: BulletSvgProps): JSX.Element {
export default function BulletSvg(): JSX.Element {
return (
<svg
width="16"
Expand All @@ -14,13 +9,7 @@ export default function BulletSvg({
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle
cx="8"
cy="8"
r="4"
fill={`${palette.neutral[60]}`}
fill-opacity={opacity}
/>
<circle cx="8" cy="8" r="4" fill={`${palette.neutral[60]}`} />
</svg>
);
}
24 changes: 24 additions & 0 deletions support-frontend/assets/helpers/abTests/abtestDefinitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,28 @@ export const tests: Tests = {
targetPage: pageUrlRegexes.contributions.allLandingPagesAndThankyouPages,
excludeContributionsOnlyCountries: false,
},
benefitsReset: {
variants: [
{
id: 'control',
},
{
id: 'v1',
},
{
id: 'v2',
},
],
audiences: {
ALL: {
offset: 0,
size: 1,
},
},
isActive: true,
referrerControlled: false, // ab-test name not needed to be in paramURL
seed: 4,
targetPage: pageUrlRegexes.contributions.allLandingPagesAndThankyouPages,
excludeContributionsOnlyCountries: true,
},
};
121 changes: 121 additions & 0 deletions support-frontend/assets/helpers/productCatalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export type { ActiveProductKey };

export const productCatalog = window.guardian.productCatalog;

export type SupporterPlusVariants = 'control' | 'v1' | 'v2';
export type ContributionVariants = 'control' | 'v1' | 'v2Annual' | 'v2Monthly';

type ProductBenefit = {
copy: string;
tooltip?: string;
Expand Down Expand Up @@ -94,16 +97,32 @@ export function isProductKey(val: unknown): val is ActiveProductKey {
return productKeys.includes(val as ActiveProductKey);
}

const appBenefitControlV2 = {
copy: 'Unlimited access to the Guardian app',
tooltip: `Read beyond our 20 article-per-month limit, enjoy offline access and personalised recommendations, and access our full archive of journalism. Never miss a story with the Guardian News app – a beautiful, intuitive reading experience.`,
};
const appBenefit = {
copy: 'Full access to the Guardian app',
tooltip: `Read beyond our 20 article-per-month limit, enjoy offline access and personalised recommendations, and access our full archive of journalism. Never miss a story with the Guardian News app – a beautiful, intuitive reading experience.`,
};
const addFreeBenefit = {
copy: 'Ad-free reading on all your devices',
};

const newsletterBenefitControl = {
copy: 'Exclusive newsletter for supporters, sent every week from the Guardian newsroom',
};
const newsletterBenefit = {
copy: 'Regular dispatches from the newsroom to see the impact of your support',
};
const newsletterBenefitMonthlyV2 = {
copy: 'Give to the Guardian every month with Support',
hideBullet: true,
};
const newsletterBenefitAnnualV2 = {
copy: 'Give to the Guardian every year with Support',
hideBullet: true,
};
const fewerAsksBenefit = {
copy: 'Far fewer asks for support',
tooltip: `You'll see far fewer financial support asks at the bottom of articles or in pop-up banners.`,
Expand All @@ -118,6 +137,17 @@ const guardianWeeklyBenefit = {
copy: 'Guardian Weekly print magazine delivered to your door every week ',
tooltip: `Guardian Weekly is a beautifully concise magazine featuring a handpicked selection of in-depth articles, global news, long reads, opinion and more. Delivered to you every week, wherever you are in the world.`,
};
const newspaperArchiveBenefitUK = {
copy: `Unlimited access to the Guardian's 200-year newspaper archive`,
isNew: true,
tooltip: `Look back on more than 200 years of world history with the Guardian newspaper archive. Get digital access to every front page, article and advertisement, as it was printed in the UK, since 1821.`,
};
const newspaperArchiveBenefitROW = {
copy: `Unlimited access to the Guardian's 200-year newspaper archive`,
isNew: true,
tooltip: `Look back on more than 200 years of world history with the Guardian newspaper archive. Get digital access to every front page, article and advertisement, as it was printed, since 1821.`,
};

const feastBenefit = {
copy: 'Unlimited access to the Guardian Feast app',
isNew: true,
Expand All @@ -133,6 +163,45 @@ const supporterPlusBenefits = [
partnerOffersBenefit,
feastBenefit,
];
const supporterPlusBenefitsList: Record<
SupporterPlusVariants,
ProductBenefit[]
> = {
control: [
appBenefitControlV2,
addFreeBenefit,
newsletterBenefitControl,
fewerAsksBenefit,
partnerOffersBenefit,
feastBenefit,
],
v1: supporterPlusBenefits,
v2: [
appBenefitControlV2,
addFreeBenefit,
fewerAsksBenefit,
partnerOffersBenefit,
feastBenefit,
],
};

const contributionBenefitsList: Record<ContributionVariants, ProductBenefit[]> =
{
control: [newsletterBenefitControl],
v1: [newsletterBenefit],
v2Monthly: [newsletterBenefitMonthlyV2],
v2Annual: [newsletterBenefitAnnualV2],
};

const tierThreeBenefits = [guardianWeeklyBenefit];
const tierThreeInclArchiveBenefitsUK = [
guardianWeeklyBenefit,
newspaperArchiveBenefitUK,
];
const tierThreeInclArchiveBenefitsROW = [
guardianWeeklyBenefit,
newspaperArchiveBenefitROW,
];

const guardianAdLiteBenefits = [
{
Expand Down Expand Up @@ -389,6 +458,58 @@ export const productCatalogDescription: Record<
},
};

function supporterPlusVariant(variant?: string): SupporterPlusVariants {
switch (variant) {
case 'v1':
case 'v2':
return variant;
default:
return 'control';
}
}
function contributionVariant(
period: 'Monthly' | 'Annual',
variant?: string,
): ContributionVariants {
switch (variant) {
case 'v1':
return variant;
case 'v2':
return `v2${period}`;
default:
return 'control';
}
}

export function productCatalogDescriptionResetAndNewspaperArchive(
period: 'Monthly' | 'Annual',
resetVariant?: string,
countryGroupId?: CountryGroupId,
) {
const newsPaperArchiveBenefit = countryGroupId
? countryGroupId === 'GBPCountries'
? tierThreeInclArchiveBenefitsUK
: tierThreeInclArchiveBenefitsROW
: tierThreeBenefits;

return {
...productCatalogDescription,
SupporterPlus: {
...productCatalogDescription.SupporterPlus,
benefits: supporterPlusBenefitsList[supporterPlusVariant(resetVariant)],
},
Contribution: {
...productCatalogDescription.Contribution,
benefits:
contributionBenefitsList[contributionVariant(period, resetVariant)],
},
TierThree: {
...productCatalogDescription.TierThree,
benefits: newsPaperArchiveBenefit,
},
};
}

export function productCatalogDescriptionNewBenefits(
countryGroupId: CountryGroupId,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ export function ThreeTierCard({
price,
promotion,
ctaCopy,
lozengeText,
abParticipations,
}: ThreeTierCardProps): JSX.Element {
const currency = currencies[currencyId];
Expand All @@ -227,7 +228,9 @@ export function ThreeTierCard({
{isRecommended && !isUserSelected && (
<ThreeTierLozenge
subdue={isRecommendedSubdued}
title={promotion?.landingPage?.roundel ?? 'Highest impact'}
title={
promotion?.landingPage?.roundel ?? lozengeText ?? 'Highest impact'
}
/>
)}
<h2 css={titleCss}>{label}</h2>
Expand Down Expand Up @@ -301,6 +304,7 @@ export function ThreeTierCard({
isChecked: true,
toolTip: benefit.tooltip,
isNew: benefit.isNew,
hideBullet: benefit.hideBullet,
};
})}
style={'compact'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type ThreeTierCardsProps = {
price: number;
promotion?: Promotion;
ctaCopy: string;
lozengeText?: string;
}>;
currencyId: IsoCurrency;
countryGroupId: CountryGroupId;
Expand Down Expand Up @@ -89,6 +90,7 @@ export function ThreeTierCards({
countryGroupId={countryGroupId}
paymentFrequency={paymentFrequency}
ctaCopy={cardContent.ctaCopy}
lozengeText={cardContent.lozengeText}
abParticipations={abParticipations}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,8 @@ import {
} from 'helpers/internationalisation/countryGroup';
import { currencies } from 'helpers/internationalisation/currency';
import {
productCatalogDescription as canonicalProductCatalogDescription,
productCatalog,
productCatalogDescriptionNewBenefits,
productCatalogDescriptionResetAndNewspaperArchive,
} from 'helpers/productCatalog';
import type { BillingPeriod } from 'helpers/productPrice/billingPeriods';
import type { Promotion } from 'helpers/productPrice/promotions';
Expand Down Expand Up @@ -374,11 +373,16 @@ export function ThreeTierLanding({
const selectedContributionRatePlan =
contributionType === 'ANNUAL' ? 'Annual' : 'Monthly';

const productCatalogDescription = ['v1', 'v2'].includes(
const inResetBenefits = abParticipations.benefitsReset; // all variants
const inNewsPaperArchiveBenefit = ['v1', 'v2'].includes(
abParticipations.newspaperArchiveBenefit ?? '',
)
? productCatalogDescriptionNewBenefits(countryGroupId)
: canonicalProductCatalogDescription;
);
const productCatalogDescription =
productCatalogDescriptionResetAndNewspaperArchive(
selectedContributionRatePlan,
inResetBenefits,
inNewsPaperArchiveBenefit ? countryGroupId : undefined,
);

/**
* Tier 1: Contributions
Expand Down Expand Up @@ -448,6 +452,9 @@ export function ThreeTierLanding({
urlSearchParamsProduct === 'SupporterPlus' ||
isCardUserSelected(tier2Pricing, promotionTier2?.discount?.amount),
ctaCopy: 'Support',
lozengeText: ['control', 'v2'].includes(inResetBenefits ?? '')
? 'Recommended'
: 'Highest impact',
};

/**
Expand Down

0 comments on commit 526d7ac

Please sign in to comment.