feat: increate minimum challenge requirement AB test (#44764)
* feat: increate minimum challenge requirement AB test * fix: adjust tests Co-authored-by: ahmad abdolsaheb <home@mac-16.local>
This commit is contained in:
@ -358,7 +358,7 @@
|
||||
"one-time": "If you'd prefer to make one-time donations, you can support freeCodeCamp's mission whenever you have cash to spare. You can use <0>this link to donate whatever amount feels right through PayPal</0>.",
|
||||
"wire-transfer": "You can also send money to freeCodeCamp directly through a wire transfer. If you need our wire details, email Quincy at quincy@freecodecamp.org",
|
||||
"does-crypto": "Does freeCodeCamp accept donations in Bitcoin or other cryptocurrencies?",
|
||||
"yes-crypto": "Yes, and we would welcome your cryptocurrency donations. Here are our wallet details:",
|
||||
"yes-cryptocurrency": "Yes. Please email Quincy at quincy@freecodecamp.org and he can send you freeCodeCamp's wallet information. He can also provide you with a donation receipt if you need one for your taxes.",
|
||||
"can-check": "Can I mail a physical check?",
|
||||
"yes-check": "Yes, we would welcome a check. You can mail it to us at:",
|
||||
"how-matching-gift": "How can I set up matching gifts from my employer, or payroll deductions?",
|
||||
|
@ -2,24 +2,6 @@ import React, { useState } from 'react';
|
||||
import { useTranslation, Trans } from 'react-i18next';
|
||||
import Caret from '../../assets/icons/caret';
|
||||
|
||||
const WALLETS = (
|
||||
<>
|
||||
<code>Bitcoin: 3B4QShnJawtzBd1FFzHPpVCpxBpVbcbPRg</code>
|
||||
<br />
|
||||
<code>Ethereum: 0x1ee753faa97BE3C4b9b1dE775dB44c9Bfac0EC91</code>
|
||||
<br />
|
||||
<code>Litecoin: MVDLr18spSjd9nDyKG2Y94BFmgzbjXgfCD</code>
|
||||
<br />
|
||||
<code>Bitcoin Cash: qqw8lhpnu635za8f5c22ghynl6yz5zelp52t25lmnm</code>
|
||||
<br />
|
||||
<code>USD Coin: 0xad4f0c8363fE733DdbfEDBdAf6600E2b6dF2900d</code>
|
||||
<br />
|
||||
<code>DAI: 0xad4f0c8363fE733DdbfEDBdAf6600E2b6dF2900d</code>
|
||||
<br />
|
||||
<code>Dash: XyRp67PQVBRaZu2LJU6Ndc5kp3AaRaHnXt</code>
|
||||
</>
|
||||
);
|
||||
|
||||
const POBOX = (
|
||||
<>
|
||||
<code>Free Code Camp, Inc.</code>
|
||||
@ -156,8 +138,7 @@ export const DonationFaqText = (): JSX.Element => {
|
||||
Q: t('donate.does-crypto'),
|
||||
A: (
|
||||
<>
|
||||
<p>{t('donate.yes-crypto')}</p>
|
||||
<p>{WALLETS}</p>
|
||||
<p>{t('donate.yes-cryptocurrency')}</p>
|
||||
</>
|
||||
)
|
||||
},
|
||||
|
@ -12,19 +12,12 @@ import DonateForm from '../components/Donation/donate-form';
|
||||
import {
|
||||
DonationText,
|
||||
DonationOptionsAlertText,
|
||||
DonationSupportText,
|
||||
DonationOptionsText,
|
||||
DonationFaqText
|
||||
} from '../components/Donation/donation-text-components';
|
||||
|
||||
import { Spacer, Loader } from '../components/helpers';
|
||||
import CampersImage from '../components/landing/components/campers-image';
|
||||
import {
|
||||
signInLoadingSelector,
|
||||
userSelector,
|
||||
executeGA,
|
||||
isAVariantSelector
|
||||
} from '../redux';
|
||||
import { signInLoadingSelector, userSelector, executeGA } from '../redux';
|
||||
|
||||
export interface ExecuteGaArg {
|
||||
type: string;
|
||||
@ -40,22 +33,15 @@ interface DonatePageProps {
|
||||
executeGA: (arg: ExecuteGaArg) => void;
|
||||
isDonating?: boolean;
|
||||
showLoading: boolean;
|
||||
isAVariant: boolean;
|
||||
t: TFunction;
|
||||
}
|
||||
|
||||
const mapStateToProps = createSelector(
|
||||
userSelector,
|
||||
signInLoadingSelector,
|
||||
isAVariantSelector,
|
||||
(
|
||||
{ isDonating }: { isDonating: boolean },
|
||||
showLoading: boolean,
|
||||
isAVariant: boolean
|
||||
) => ({
|
||||
({ isDonating }: { isDonating: boolean }, showLoading: boolean) => ({
|
||||
isDonating,
|
||||
showLoading,
|
||||
isAVariant
|
||||
showLoading
|
||||
})
|
||||
);
|
||||
|
||||
@ -67,7 +53,6 @@ function DonatePage({
|
||||
executeGA = () => {},
|
||||
isDonating = false,
|
||||
showLoading,
|
||||
isAVariant,
|
||||
t
|
||||
}: DonatePageProps) {
|
||||
useEffect(() => {
|
||||
@ -94,34 +79,6 @@ function DonatePage({
|
||||
});
|
||||
}
|
||||
|
||||
const donationSupport = (
|
||||
<>
|
||||
<Row className='donate-support'>
|
||||
<Col xs={12}>
|
||||
<hr />
|
||||
<DonationOptionsText />
|
||||
<DonationSupportText />
|
||||
</Col>
|
||||
</Row>
|
||||
</>
|
||||
);
|
||||
|
||||
const donationFaq = (
|
||||
<>
|
||||
<Spacer size={3} />
|
||||
<Row className='donate-support' id='FAQ'>
|
||||
<Col className={'text-center'} xs={12}>
|
||||
<hr />
|
||||
<h2>{t('donate.faq')}</h2>
|
||||
<Spacer />
|
||||
</Col>
|
||||
<Col xs={12}>
|
||||
<DonationFaqText />
|
||||
</Col>
|
||||
</Row>
|
||||
</>
|
||||
);
|
||||
|
||||
return showLoading ? (
|
||||
<Loader fullScreen={true} />
|
||||
) : (
|
||||
@ -155,7 +112,17 @@ function DonatePage({
|
||||
<DonateForm handleProcessing={handleProcessing} />
|
||||
</Col>
|
||||
</Row>
|
||||
{isAVariant ? donationSupport : donationFaq}
|
||||
<Spacer size={3} />
|
||||
<Row className='donate-support' id='FAQ'>
|
||||
<Col className={'text-center'} xs={12}>
|
||||
<hr />
|
||||
<h2>{t('donate.faq')}</h2>
|
||||
<Spacer />
|
||||
</Col>
|
||||
<Col xs={12}>
|
||||
<DonationFaqText />
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col lg={6}>
|
||||
<CampersImage pageName='donate' />
|
||||
|
@ -231,6 +231,7 @@ export const shouldRequestDonationSelector = state => {
|
||||
const canRequestProgressDonation = state[MainApp].canRequestProgressDonation;
|
||||
const isDonating = isDonatingSelector(state);
|
||||
const recentlyClaimedBlock = recentlyClaimedBlockSelector(state);
|
||||
const isAVariant = isAVariantSelector(state);
|
||||
|
||||
// don't request donation if already donating
|
||||
if (isDonating) return false;
|
||||
@ -243,9 +244,17 @@ export const shouldRequestDonationSelector = state => {
|
||||
|
||||
// donations only appear after the user has completed ten challenges (i.e.
|
||||
// not before the 11th challenge has mounted)
|
||||
// the follwoing is an AB test for increasing the completed challenge requirement to 20
|
||||
if (isAVariant) {
|
||||
if (completedChallenges.length < 10) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (completedChallenges.length < 20) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// this will mean we have completed 3 or more challenges this browser session
|
||||
// and enough challenges overall to not be new
|
||||
return completionCount >= 3;
|
||||
|
@ -94,7 +94,7 @@ const patreonDefaultPledgeAmount = 500;
|
||||
|
||||
const aBTestConfig = {
|
||||
isTesting: true,
|
||||
type: 'AddDonateFAQ'
|
||||
type: 'increaceChallengesCompleted'
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
|
@ -1,13 +1,3 @@
|
||||
const selectors = {
|
||||
donateSupport: {
|
||||
firstTitle: '.donate-support h4:first-of-type b',
|
||||
secondTitle: '.donate-support h4:last-of-type b',
|
||||
firstText: '.donate-support p:first-of-type',
|
||||
secondText: '.donate-support p:last-of-type',
|
||||
link: '.donate-support a'
|
||||
}
|
||||
};
|
||||
|
||||
describe('Donate page', () => {
|
||||
before(() => {
|
||||
cy.clearCookies();
|
||||
@ -24,40 +14,31 @@ describe('Donate page', () => {
|
||||
cy.contains('Confirm your donation of $5 / month:').should('be.visible');
|
||||
});
|
||||
|
||||
it('Should have support section', () => {
|
||||
it('Should have FAQ section', () => {
|
||||
cy.contains('Frequently asked questions');
|
||||
cy.contains('How can I get help with my donations?');
|
||||
cy.contains('How transparent is freeCodeCamp.org?');
|
||||
cy.contains('How efficient is freeCodeCamp?');
|
||||
cy.contains('How can I make a one-time donation?');
|
||||
cy.contains(
|
||||
'Want to make a bigger one-time donation, mail us a check, or give in other ways?'
|
||||
).should('be.visible');
|
||||
});
|
||||
|
||||
it('Support section should have support text', () => {
|
||||
'Does freeCodeCamp accept donations in Bitcoin or other cryptocurrencies?'
|
||||
);
|
||||
cy.contains('Can I mail a physical check?');
|
||||
cy.contains(
|
||||
selectors.donateSupport.firstTitle,
|
||||
'Want to make a bigger one-time donation, mail us a check, or give in other ways?'
|
||||
'How can I set up matching gifts from my employer, or payroll deductions?'
|
||||
);
|
||||
cy.contains('How can I set up an Endowment Gift to freeCodeCamp.org?');
|
||||
cy.contains('How can I set up a Legacy gift to freeCodeCamp.org?').should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.contains('How can I donate stock to freeCodeCamp.org?').should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.contains(
|
||||
selectors.donateSupport.secondTitle,
|
||||
'Need help with your current or past donations?'
|
||||
'I set up a monthly donation, but I need to update or pause the monthly recurrence. How can I do this?'
|
||||
);
|
||||
cy.contains(
|
||||
selectors.donateSupport.firstText,
|
||||
"Here are many other ways you can support our non-profit's mission."
|
||||
);
|
||||
cy.contains(
|
||||
selectors.donateSupport.secondText,
|
||||
'Forward a copy of your donation receipt to donors@freecodecamp.org and tell us how we can help.'
|
||||
'Is there anything else I can learn about donating to freeCodeCamp.org?'
|
||||
);
|
||||
});
|
||||
|
||||
it('Support section should have donation link', () => {
|
||||
cy.get(selectors.donateSupport.link).should(
|
||||
'have.attr',
|
||||
'href',
|
||||
'https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp'
|
||||
);
|
||||
});
|
||||
|
||||
it('Donor alert should not be visible for non-donor', () => {
|
||||
cy.get('.alert-info').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user