Skip to content

Commit

Permalink
Implement VAR for C24_WMDE_iPad_DE_01
Browse files Browse the repository at this point in the history
- The average donation should be changed from 22,25 € to 22,49 €
- Added space between 99% -> 99 %
- The third option below the two buttons "Ja, ich möchte jährlich spenden, aber einen anderen Betrag." can be removed from the 2nd form page.
- The first slide should show the data and time "{{ liveDateAndTime.currentDate }}, {{ liveDateAndTime.currentTime }} - An alle, die Wikipedia in Deutschland nutzen:" and end with "Unabhängigkeit von Wikipedia zu unterstützen."
- The headline of the variant banner is changed
- It has the progress bar
- It has the campaign day sentence
- It has the visitors-vs-donors sentence
- Update content repo

Ticket: https://phabricator.wikimedia.org/T376593

Co-authored-by: Abban Dunne <[email protected]>
  • Loading branch information
Sperling-0 and Abban committed Oct 25, 2024
1 parent 9b4daf9 commit 06d55bf
Show file tree
Hide file tree
Showing 4 changed files with 341 additions and 1 deletion.
2 changes: 1 addition & 1 deletion banners/pad/C24_WMDE_iPad_DE_01/banner_var.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createVueApp } from '@src/createVueApp';
import './styles/styles.scss';

import BannerConductor from '@src/components/BannerConductor/BannerConductor.vue';
import Banner from './components/BannerCtrl.vue';
import Banner from './components/BannerVar.vue';
import { UrlRuntimeEnvironment } from '@src/utils/RuntimeEnvironment';
import { WindowResizeHandler } from '@src/utils/ResizeHandler';
import PageWPORG from '@src/page/PageWPORG';
Expand Down
170 changes: 170 additions & 0 deletions banners/pad/C24_WMDE_iPad_DE_01/components/BannerVar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
<template>
<div class="wmde-banner-wrapper" :class="contentState">
<MainBanner
@close="onCloseMain"
@form-interaction="onFormInteraction"
v-if="contentState === ContentStates.Main"
:bannerState="bannerState"
>
<template #banner-slides="{ play }: any">
<div class="wmde-banner-content-headline">
<span class="wmde-banner-content-headline-text">Ist Ihnen Wikipedia 15 € wert?</span>
</div>
<KeenSlider :with-navigation="true" :play="play" :interval="5000">

<template #slides="{ currentSlide }: any">
<BannerSlides :currentSlide="currentSlide"/>
</template>

<template #left-icon>
<ChevronLeftIcon :fill="'#990a00'"/>
</template>

<template #right-icon>
<ChevronRightIcon :fill="'#990a00'"/>
</template>

</KeenSlider>
</template>

<template #progress>
<ProgressBar amount-to-show-on-right="TARGET"/>
</template>

<template #donation-form="{ formInteraction }: any">
<MultiStepDonation :step-controllers="stepControllers" @form-interaction="formInteraction">

<template #[FormStepNames.MainDonationFormStep]="{ pageIndex, submit, isCurrent, previous }: any">
<MainDonationForm :page-index="pageIndex" @submit="submit" :is-current="isCurrent" @previous="previous">

<template #label-payment-ppl>
<span class="wmde-banner-select-group-label with-logos paypal"><PayPalLogo/></span>
</template>

<template #label-payment-bez>
<span class="wmde-banner-select-group-label with-logos sepa"><SepaLogo/></span>
</template>

<template #label-payment-mcp>
<span class="wmde-banner-select-group-label with-logos credit-cards">
<VisaLogo/>
<MastercardLogo/>
</span>
</template>

</MainDonationForm>
</template>

<template #[FormStepNames.UpgradeToYearlyFormStep]="{ pageIndex, submit, isCurrent, previous }: any">
<UpgradeToYearlyButtonForm :page-index="pageIndex" :show-manual-upgrade-option="false" @submit="submit" :is-current="isCurrent" @previous="previous">
<template #back>
<ChevronLeftIcon/>
</template>
</UpgradeToYearlyButtonForm>
</template>

</MultiStepDonation>
</template>

<template #footer>
<BannerFooter @showFundsModal="isFundsModalVisible = true"/>
</template>
</MainBanner>

<SoftClose
v-if="contentState === ContentStates.SoftClosing"
@close="() => onClose( 'SoftClose', CloseChoices.Close )"
@maybe-later="() => onClose( 'SoftClose', CloseChoices.MaybeLater )"
@time-out-close="() => onClose( 'SoftClose', CloseChoices.TimeOut )"
/>

<FundsModal
:content="useOfFundsContent"
:is-funds-modal-visible="isFundsModalVisible"
@hideFundsModal="isFundsModalVisible = false"
/>

</div>
</template>

<script setup lang="ts">
import { BannerStates } from '@src/components/BannerConductor/StateMachine/BannerStates';
import { nextTick, ref, watch } from 'vue';
import { UseOfFundsContent as useOfFundsContentInterface } from '@src/domain/UseOfFunds/UseOfFundsContent';
import SoftClose from '@src/components/SoftClose/SoftClose.vue';
import MainBanner from './MainBanner.vue';
import FundsModal from '@src/components/UseOfFunds/FundsModal.vue';
import BannerSlides from '../content/BannerSlidesVar.vue';
import ProgressBar from '@src/components/ProgressBar/ProgressBar.vue';
import MultiStepDonation from '@src/components/DonationForm/MultiStepDonation.vue';
import MainDonationForm from '@src/components/DonationForm/Forms/MainDonationForm.vue';
import ChevronRightIcon from '@src/components/Icons/ChevronRightIcon.vue';
import KeenSlider from '@src/components/Slider/KeenSlider.vue';
import ChevronLeftIcon from '@src/components/Icons/ChevronLeftIcon.vue';
import UpgradeToYearlyButtonForm from '@src/components/DonationForm/Forms/UpgradeToYearlyButtonForm.vue';
import { useFormModel } from '@src/components/composables/useFormModel';
import {
createSubmittableMainDonationForm
} from '@src/components/DonationForm/StepControllers/SubmittableMainDonationForm';
import {
createSubmittableUpgradeToYearly
} from '@src/components/DonationForm/StepControllers/SubmittableUpgradeToYearly';
import { CloseChoices } from '@src/domain/CloseChoices';
import { CloseEvent } from '@src/tracking/events/CloseEvent';
import { TrackingFeatureName } from '@src/tracking/TrackingEvent';
import MastercardLogo from '@src/components/PaymentLogos/MastercardLogo.vue';
import SepaLogo from '@src/components/PaymentLogos/SepaLogo.vue';
import VisaLogo from '@src/components/PaymentLogos/VisaLogo.vue';
import PayPalLogo from '@src/components/PaymentLogos/PayPalLogo.vue';
import BannerFooter from '@src/components/Footer/BannerFooter.vue';
enum ContentStates {
Main = 'wmde-banner-wrapper--main',
SoftClosing = 'wmde-banner-wrapper--soft-closing'
}
enum FormStepNames {
MainDonationFormStep = 'MainDonationForm',
UpgradeToYearlyFormStep = 'UpgradeToYearlyForm'
}
interface Props {
bannerState: BannerStates;
useOfFundsContent: useOfFundsContentInterface;
remainingImpressions: number;
}
const props = defineProps<Props>();
const emit = defineEmits( [ 'bannerClosed', 'bannerContentChanged' ] );
const isFundsModalVisible = ref<boolean>( false );
const contentState = ref<ContentStates>( ContentStates.Main );
const formModel = useFormModel();
const stepControllers = [
createSubmittableMainDonationForm( formModel, FormStepNames.UpgradeToYearlyFormStep ),
createSubmittableUpgradeToYearly( formModel, FormStepNames.MainDonationFormStep, FormStepNames.MainDonationFormStep )
];
watch( contentState, async () => {
emit( 'bannerContentChanged' );
} );
function onFormInteraction(): void {
nextTick( () => {
emit( 'bannerContentChanged' );
} );
}
function onCloseMain(): void {
if ( props.remainingImpressions > 0 ) {
contentState.value = ContentStates.SoftClosing;
} else {
onClose( 'MainBanner', CloseChoices.Close );
}
}
function onClose( feature: TrackingFeatureName, userChoice: CloseChoices ): void {
emit( 'bannerClosed', new CloseEvent( feature, userChoice ) );
}
</script>
48 changes: 48 additions & 0 deletions banners/pad/C24_WMDE_iPad_DE_01/content/BannerSlidesVar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<template>
<KeenSliderSlide :is-current="currentSlide === 0">
<p>
<InfoIcon/>
{{ currentDayName }}, {{ currentDate }} - An alle, die Wikipedia in Deutschland nutzen:
Unabhängigkeit von Wikipedia zu unterstützen.
</p>
</KeenSliderSlide>
<KeenSliderSlide :is-current="currentSlide === 1">
<p>
{{ campaignDaySentence }}
Insgesamt spenden 99&nbsp;% nichts – sie übergehen diesen Aufruf. Wikipedia wird
durch Spenden von durchschnittlich 22,49&nbsp;€ finanziert.
</p>
</KeenSliderSlide>
<KeenSliderSlide :is-current="currentSlide === 2">
<p>
Doch schon mit einer Spende von 5&nbsp;€ kann Wikipedia sich auch in Zukunft erfolgreich
entwickeln. <AnimatedText :content="visitorsVsDonorsSentence"/>
</p>
</KeenSliderSlide>
<KeenSliderSlide :is-current="currentSlide === 3">
<p>Die meisten Menschen spenden, weil sie Wikipedia nützlich finden. Hat Wikipedia Ihnen in diesem
Jahr Wissen im Wert einer Tasse Kaffee geschenkt? Dann nehmen Sie sich doch bitte eine Minute
Zeit und geben Sie etwas zurück. Vielen Dank!</p>
</KeenSliderSlide>
</template>

<script setup lang="ts">
import { DynamicContent } from '@src/utils/DynamicContent/DynamicContent';
import { inject } from 'vue';
import InfoIcon from '@src/components/Icons/InfoIcon.vue';
import KeenSliderSlide from '@src/components/Slider/KeenSliderSlide.vue';
import AnimatedText from '@src/components/AnimatedText/AnimatedText.vue';
interface Props {
currentSlide: number
}
defineProps<Props>();
const {
currentDayName,
currentDate,
campaignDaySentence,
visitorsVsDonorsSentence
}: DynamicContent = inject( 'dynamicCampaignText' );
</script>
122 changes: 122 additions & 0 deletions test/banners/pad/components/BannerVar.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { afterEach, beforeEach, describe, test, vi } from 'vitest';
import { mount, VueWrapper } from '@vue/test-utils';
import Banner from '@banners/pad/C24_WMDE_iPad_DE_01/components/BannerVar.vue';
import { BannerStates } from '@src/components/BannerConductor/StateMachine/BannerStates';
import { newDynamicContent } from '@test/banners/dynamicCampaignContent';
import { useOfFundsContent } from '@test/banners/useOfFundsContent';
import { formItems } from '@test/banners/formItems';
import { CurrencyEn } from '@src/utils/DynamicContent/formatters/CurrencyEn';
import { TrackerStub } from '@test/fixtures/TrackerStub';
import { softCloseFeatures } from '@test/features/SoftCloseDesktop';
import { useOfFundsFeatures } from '@test/features/UseOfFunds';
import { bannerContentAnimatedTextFeatures, bannerContentFeatures } from '@test/features/BannerContent';
import { resetFormModel } from '@test/resetFormModel';
import { useFormModel } from '@src/components/composables/useFormModel';
import { donationFormFeatures } from '@test/features/forms/MainDonation_UpgradeToYearlyButton';
import { DynamicContent } from '@src/utils/DynamicContent/DynamicContent';
import { bannerMainFeatures } from '@test/features/MainBanner';

const formModel = useFormModel();
const translator = ( key: string ): string => key;

describe( 'BannerCtrl.vue', () => {
let wrapper: VueWrapper<any>;
beforeEach( () => {
resetFormModel( formModel );
vi.useFakeTimers();
} );

afterEach( () => {
wrapper.unmount();
vi.restoreAllMocks();
vi.useRealTimers();
} );

const getWrapper = ( dynamicContent: DynamicContent = null ): VueWrapper<any> => {
// attachTo the document body to fix an issue with Vue Test Utils where
// clicking a submit button in a form does not fire the submit event
wrapper = mount( Banner, {
attachTo: document.body,
props: {
bannerState: BannerStates.Pending,
useOfFundsContent,
remainingImpressions: 10
},
global: {
mocks: {
$translate: translator
},
provide: {
translator: { translate: translator },
dynamicCampaignText: dynamicContent ?? newDynamicContent(),
formActions: { donateWithAddressAction: 'https://example.com', donateWithoutAddressAction: 'https://example.com' },
currencyFormatter: new CurrencyEn(),
formItems,
tracker: new TrackerStub()
}
}
} );

return wrapper;
};

describe( 'Main Banner', () => {
test.each( [
[ 'expectDoesNotEmitCloseEvent' ]
] )( '%s', async ( testName: string ) => {
await bannerMainFeatures[ testName ]( getWrapper() );
} );
} );

describe( 'Content', () => {
test.each( [
[ 'expectSlideShowPlaysWhenBecomesVisible' ],
[ 'expectSlideShowStopsOnFormInteraction' ]
] )( '%s', async ( testName: string ) => {
await bannerContentFeatures[ testName ]( getWrapper() );
} );

test.each( [
[ 'expectHidesAnimatedVisitorsVsDonorsSentenceInSlideShow' ],
[ 'expectShowsAnimatedVisitorsVsDonorsSentenceInSlideShow' ]
] )( '%s', async ( testName: string ) => {
await bannerContentAnimatedTextFeatures[ testName ]( getWrapper );
} );
} );

describe( 'Donation Form Happy Paths', () => {
test.each( [
[ 'expectMainDonationFormSubmitsWhenSofortIsSelected' ],
[ 'expectMainDonationFormSubmitsWhenYearlyIsSelected' ],
[ 'expectMainDonationFormGoesToUpgrade' ],
[ 'expectUpgradeToYearlyFormSubmitsUpgrade' ],
[ 'expectUpgradeToYearlyFormSubmitsDontUpgrade' ],
[ 'expectUpgradeToYearlyFormGoesToMainDonation' ]
] )( '%s', async ( testName: string ) => {
await donationFormFeatures[ testName ]( getWrapper() );
} );
} );

describe( 'Soft Close', () => {
test.each( [
[ 'expectShowsSoftClose' ],
[ 'expectEmitsSoftCloseCloseEvent' ],
[ 'expectEmitsSoftCloseMaybeLaterEvent' ],
[ 'expectEmitsSoftCloseTimeOutEvent' ],
[ 'expectEmitsBannerContentChangedOnSoftClose' ],
[ 'expectDoesNotShowSoftCloseOnFinalBannerImpression' ]
] )( '%s', async ( testName: string ) => {
await softCloseFeatures[ testName ]( getWrapper() );
} );
} );

describe( 'Use of Funds', () => {
test.each( [
[ 'expectShowsUseOfFunds' ],
[ 'expectHidesUseOfFunds' ]
] )( '%s', async ( testName: string ) => {
await useOfFundsFeatures[ testName ]( getWrapper() );
} );
} );

} );

0 comments on commit 06d55bf

Please sign in to comment.