Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DON-888 – A/B testing setup + proof of concept #1322

Merged
merged 6 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {APP_BASE_HREF, isPlatformBrowser} from '@angular/common';
import {AfterViewInit, Component, HostListener, Inject, OnInit, PLATFORM_ID, ViewChild} from '@angular/core';
import {Event as RouterEvent, NavigationEnd, NavigationStart, Router,} from '@angular/router';
import {BiggiveMainMenu} from '@biggive/components-angular';
import {MatomoTracker} from "ngx-matomo";
import {filter} from 'rxjs/operators';

import {DonationService} from './donation.service';
Expand All @@ -17,7 +18,6 @@ import {
CookiePreferences,
CookiePreferenceService
} from "./cookiePreference.service";
import {MatomoTracker} from "ngx-matomo";

@Component({
selector: 'app-root',
Expand Down
2 changes: 1 addition & 1 deletion src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const matomoTrackers = environment.matomoSiteId ? [
routeTracking: {
enable: true,
},
requireCookieConsent: flags.cookieBannerEnabled,
requireCookieConsent: flags.cookieBannerEnabled,
}),
RouterModule.forRoot(routes, {
bindToComponentInputs: true,
Expand Down
6 changes: 6 additions & 0 deletions src/app/donation-complete/donation-complete.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,14 @@ export class DonationCompleteComponent implements OnInit {
});

if (donation && this.donationService.isComplete(donation)) {
// This is linked to the Donation Complete goal in Matomo, so we don't need to separately
// `trackGoal()` for that.
this.matomoTracker.trackEvent('donate', 'thank_you_fully_loaded', `Donation to campaign ${donation.projectId}`);

if (donation.tipAmount > 0 && environment.matomoNonZeroTipGoalId && donation.currencyCode === 'GBP') {
this.matomoTracker.trackGoal(environment.matomoNonZeroTipGoalId, donation.tipAmount);
}

this.cardChargedAmount = donation.donationAmount + donation.feeCoverAmount + donation.tipAmount;
this.giftAidAmount = donation.giftAid ? 0.25 * donation.donationAmount : 0;
this.totalValue = donation.donationAmount + this.giftAidAmount + donation.matchedAmount;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,13 @@

<h2 class="b-rt-0 b-m-0 b-bold">Tip Big Give</h2>
<p *ngIf="!campaign.feePercentage && creditPenceToUse === 0">
Big Give doesn't charge platform fees. That means we're only able to continue offering our services thanks to
the generosity of donors who leave an optional tip amount here.
<span *ngIf="!alternateCopy">
Big Give doesn't charge platform fees. That means we're only able to continue offering our services thanks to
the generosity of donors who leave a tip.
</span>
<span *ngIf="alternateCopy">
Big Give is a registered charity (1136547), and since 2008, our aim has been to help thousands of charities double the difference of their donations. Thanks to the generosity of people like you who leave a tip, we can continue providing a match funding platform for the charities and causes you care about.
</span>
</p>

<div *ngIf="campaign.feePercentage && creditPenceToUse === 0">
Expand Down Expand Up @@ -104,6 +109,8 @@ <h2 class="b-rt-0 b-m-0 b-bold">Tip Big Give</h2>
slot="input"
/>
</biggive-text-input>

<p>Did you know Big Give is a charity, too? Tips help us provide a platform that doubles the difference of your donation to the causes closest to your heart. We truly appreciate any tip you can give - no matter the size.</p>
</div>

<div
Expand Down Expand Up @@ -152,32 +159,45 @@ <h2 class="b-rt-0 b-m-0 b-bold">Tip Big Give</h2>
<mat-expansion-panel-header>
</mat-expansion-panel-header>
</mat-expansion-panel>
<mat-expansion-panel (opened)="panelOpenState = true"
(closed)="panelOpenState = false">
<mat-expansion-panel
(opened)="panelOpenState = true"
(closed)="panelOpenState = false"
>
<mat-expansion-panel-header>
<h3 class="b-rt-0 b-m-0 b-bold"><span class="span-hr"></span>How does Big Give use tips?</h3>

</mat-expansion-panel-header>
<p>
Big Give is a registered charity, no 1136547. We don’t charge charities for using our platform; we rely on the generosity of people who donate to leave a Voluntary Tip, which helps us run our match funding campaigns.
</p>
<p>Your tips will be going to:</p>
<ul>
<li>Supporting our website and team, allowing charities to double their
donations to good causes.
</li>
<li>Providing match funds. Through tips, charities can receive funds from Big Give to launch their own campaign.
<a href="https://biggive.org/anchor-match-fund/" target="_blank"><mat-icon class="b-va-bottom" aria-hidden="false" aria-label="Open in new tab">open_in_new</mat-icon>
Read more about the Anchor Match fund.
</a>
</li>
</ul>

<p>
Thank you for your generosity! Your tips ensure that we can continue to support charities and causes that are important to you.

</p>
<div *ngIf="!alternateCopy">
<p>
Big Give is a registered charity, no 1136547. We don't charge charities for using our platform; we rely on the generosity of people who donate to leave a Voluntary Tip, which helps us run our match funding campaigns.
</p>
<p>Your tips will be going to:</p>
<ul>
<li>Supporting our website and team, allowing charities to double their
donations to good causes.
</li>
<li>Providing match funds. Through tips, charities can receive funds from Big Give to launch their own campaign.
<a href="https://biggive.org/anchor-match-fund/" target="_blank"><mat-icon class="b-va-bottom" aria-hidden="false" aria-label="Open in new tab">open_in_new</mat-icon>
Read more about the Anchor Match fund.
</a>
</li>
</ul>
<p>
Thank you for your generosity! Your tips ensure that we can continue to support charities and causes that are important to you.
</p>
</div>

<div *ngIf="alternateCopy">
<p>
We don't charge charities for using our platform; instead, we rely on the generosity of people who donate to leave a Voluntary Tip, which helps us run our match funding campaigns.
</p>
<p>Everything we make goes back into supporting charities. Your tips will be:</p>
<ul>
<li>Doubling the difference onwards by providing match funding. Through tips, charities will receive funding in our <a href="https://biggive.org/anchor-match-fund/" target="_blank"><mat-icon class="b-va-bottom" aria-hidden="false" aria-label="Open in new tab">open_in_new</mat-icon> Anchor Match fund</a> to help launch their campaigns.</li>
<li>Helping us maintain our website and support our team, so we can keep working with your favourite charities for many years to come.</li>
</ul>
<p>Thank you! If you have any questions about tips, please contact us at [email protected].</p>
</div>
</mat-expansion-panel>
</div>
<div aria-live="polite">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ import {sanitiseCurrency} from "../sanitiseCurrency";
import {DonationTippingSliderComponent} from "./donation-tipping-slider/donation-tipping-slider.component";
import {MatomoTracker} from 'ngx-matomo';

declare var _paq: {
push: (args: Array<string|object>) => void,
};

@Component({
selector: 'app-donation-start-form',
templateUrl: './donation-start-form.component.html',
Expand All @@ -78,6 +82,8 @@ export class DonationStartFormComponent implements AfterContentChecked, AfterCon
@ViewChild('stepper') private stepper: MatStepper;
@ViewChild('donationTippingSlider') private donationTippingSlider: DonationTippingSliderComponent|undefined;

alternateCopy = false; // Varies tip copy for A/B test.

stripePaymentElement: StripePaymentElement | undefined;
cardHandler = this.onStripeCardChange.bind(this);

Expand Down Expand Up @@ -269,6 +275,38 @@ export class DonationStartFormComponent implements AfterContentChecked, AfterCon
ngOnInit() {
if (isPlatformBrowser(this.platformId)) {
this.stripeService.init();

// ngx-matomo sets up window._paq internally, and doesn't have
// A/B test methods, so we work with the global ourselves.
if (environment.matomoAbTest && globalThis.hasOwnProperty('_paq')) {
_paq.push(['AbTesting::create', {
name: environment.matomoAbTest.name,
percentage: 100,
includedTargets: [{"attribute":"url","inverted":"0","type":"any","value":""}],
excludedTargets: [],
startDateTime: environment.matomoAbTest.startDate,
endDateTime: environment.matomoAbTest.endDate,
variations: [
{
name: 'original',
activate: (_event: any) => {
// No change from the original form.
console.log('Original test variant active!');
}
},
{
name: environment.matomoAbTest.variantName,
activate: (_event: any) => {
this.alternateCopy = true;
console.log('Copy B test variant active!');
}
Comment on lines +292 to +302
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
activate: (_event: any) => {
// No change from the original form.
console.log('Original test variant active!');
}
},
{
name: environment.matomoAbTest.variantName,
activate: (_event: any) => {
this.alternateCopy = true;
console.log('Copy B test variant active!');
}
activate: (_event: unknown) => {
// No change from the original form.
}
},
{
name: environment.matomoAbTest.variantName,
activate: (_event: unknown) => {
this.alternateCopy = true;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned on Jira, I think I'd rather keep browser logs on activation, at least for now, to make sure we can diagnose any behaviour we're not expecting.

},
],
trigger: () => {
return true;
},
}]);
}
}

this.setCampaignBasedVars();
Expand Down
9 changes: 8 additions & 1 deletion src/environments/environment.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,21 @@ export interface Environment {
/** Domain for cookies to be shared between donate-frontend, wordpress etc.
* Currently, ".biggive.org" in production.
*/
sharedCookieDomain: string;
sharedCookieDomain: string;

/** Prefix for pages served by the SF Experience Cloud */
experienceUriPrefix: string,
donationsApiPrefix: string,
getSiteControlId: string,
identityApiPrefix: string,
matomoSiteId: number | null, // null for no Matomo tracking.
matomoNonZeroTipGoalId: number | null, // Only tracks GBP campaigns; sends tip as value in £.
matomoAbTest?: {
name: string,
variantName: string, // The one that's not 'original'.
startDate: string,
endDate?: string, // Typically omit for dev/staging evaluation.
},
minimumCreditAmount: number,
maximumCreditAmount: number,
postcodeLookupKey: string,
Expand Down
7 changes: 7 additions & 0 deletions src/environments/environment.production.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ export const environment: Environment = {
getSiteControlId: '97792',
identityApiPrefix: 'https://identity-production.thebiggive.org.uk/v1',
matomoSiteId: 2,
matomoNonZeroTipGoalId: 11,
matomoAbTest: {
name: 'new_tip_copy_wgmf_2023',
variantName: 'test_b',
startDate: '2023/10/10 11:00:00 UTC',
endDate: '2023/10/18 12:00:00 UTC',
},
minimumCreditAmount: 500,
maximumCreditAmount: 500_000,
postcodeLookupKey: 'gq9-k9zYakORdv2uoY_yVw33182',
Expand Down
1 change: 1 addition & 0 deletions src/environments/environment.regression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const environment: Environment = {
getSiteControlId: '97792',
identityApiPrefix: 'https://identity-regression.thebiggivetest.org.uk/v1',
matomoSiteId: null,
matomoNonZeroTipGoalId: null,
minimumCreditAmount: 500,
maximumCreditAmount: 500_000,
postcodeLookupKey: 'gq9-k9zYakORdv2uoY_yVw33182',
Expand Down
6 changes: 6 additions & 0 deletions src/environments/environment.staging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ export const environment: Environment = {
getSiteControlId: '97792',
identityApiPrefix: 'https://identity-staging.thebiggivetest.org.uk/v1',
matomoSiteId: 4,
matomoNonZeroTipGoalId: 1,
matomoAbTest: {
name: 'new_tip_copy_2023_10_02_b',
startDate: '2023/10/02 18:30:11 UTC',
variantName: 'copy_b',
},
minimumCreditAmount: 500,
maximumCreditAmount: 500_000,
postcodeLookupKey: 'gq9-k9zYakORdv2uoY_yVw33182',
Expand Down
6 changes: 6 additions & 0 deletions src/environments/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ export const environment: Environment = {
getSiteControlId: '97792',
identityApiPrefix: 'http://localhost:30050/v1',
matomoSiteId: 4,
matomoNonZeroTipGoalId: 1,
matomoAbTest: {
name: 'new_tip_copy_2023_10_02_b',
startDate: '2023/10/02 18:30:11 UTC',
variantName: 'copy_b',
},
minimumCreditAmount: 500,
maximumCreditAmount: 500_000,
postcodeLookupKey: 'gq9-k9zYakORdv2uoY_yVw33182',
Expand Down
Loading