From 12d7c6aa027a9741cb00d2f4de91a19ce02f55ea Mon Sep 17 00:00:00 2001 From: Abban Dunne Date: Wed, 25 Oct 2023 09:11:48 +0200 Subject: [PATCH] Implement VAR for C23_WMDE_iPad_01 - VAR has logo payment buttons - add comma in slides for both banners Ticket: https://phabricator.wikimedia.org/T349700 --- banners/pad/banner_var.ts | 6 +- banners/pad/components/BannerVar.vue | 167 ++++++++++++++++++ banners/pad/content/BannerSlides.vue | 4 +- banners/pad/form_items_var.ts | 20 +++ banners/pad/styles/MainBanner.scss | 18 +- banners/pad/styles/MainBannerVar.scss | 82 +++++++++ banners/pad/styles/styles.scss | 2 +- banners/pad/styles/styles_var.scss | 44 +++++ .../DonationForm/MultiStepDonation.vue | 7 +- .../SelectCustomAmountButton.scss | 3 +- .../SubComponents/SelectGroupButtons.scss | 5 +- .../SubComponents/SelectGroupImageLabel.scss | 46 +++++ test/banners/pad/components/BannerVar.spec.ts | 117 ++++++++++++ 13 files changed, 507 insertions(+), 14 deletions(-) create mode 100644 banners/pad/components/BannerVar.vue create mode 100644 banners/pad/form_items_var.ts create mode 100644 banners/pad/styles/MainBannerVar.scss create mode 100644 banners/pad/styles/styles_var.scss create mode 100644 src/themes/Treedip/DonationForm/SubComponents/SelectGroupImageLabel.scss create mode 100644 test/banners/pad/components/BannerVar.spec.ts diff --git a/banners/pad/banner_var.ts b/banners/pad/banner_var.ts index acbbd2f92..9c55ce596 100644 --- a/banners/pad/banner_var.ts +++ b/banners/pad/banner_var.ts @@ -1,9 +1,9 @@ import { createVueApp } from '@src/createVueApp'; -import './styles/styles.scss'; +import './styles/styles_var.scss'; import BannerConductor from '@src/components/BannerConductor/BannerConductor.vue'; -import Banner from './components/BannerCtrl.vue'; +import Banner from './components/BannerVar.vue'; import getBannerDelay from '@src/utils/getBannerDelay'; import { WindowResizeHandler } from '@src/utils/ResizeHandler'; import PageWPORG from '@src/page/PageWPORG'; @@ -18,7 +18,7 @@ import DynamicTextPlugin from '@src/DynamicTextPlugin'; import { LocalImpressionCount } from '@src/utils/LocalImpressionCount'; // Channel specific form setup -import { createFormItems } from './form_items'; +import { createFormItems } from './form_items_var'; import { createFormActions } from '@src/createFormActions'; // Content diff --git a/banners/pad/components/BannerVar.vue b/banners/pad/components/BannerVar.vue new file mode 100644 index 000000000..6244e8064 --- /dev/null +++ b/banners/pad/components/BannerVar.vue @@ -0,0 +1,167 @@ + + + diff --git a/banners/pad/content/BannerSlides.vue b/banners/pad/content/BannerSlides.vue index 87d41fb5a..3cbf0d6f2 100644 --- a/banners/pad/content/BannerSlides.vue +++ b/banners/pad/content/BannerSlides.vue @@ -3,13 +3,13 @@

An alle, die Wikipedia in Deutschland nutzen: Vielleicht kommen wir gerade ungelegen, - aber dennoch: Klicken Sie jetzt bitte nicht weg! Am heutigen {{ currentDayName }} den {{ currentDate }} bitten wir Sie + aber dennoch: Klicken Sie jetzt bitte nicht weg! Am heutigen {{ currentDayName }}, den {{ currentDate }}, bitten wir Sie bescheiden, die Unabhängigkeit von Wikipedia zu sichern.

{{ campaignDaySentence }} Insgesamt spenden 99% nichts – sie übergehen diesen Aufruf. Wikipedia wird - durch Spenden von durchschnittlich 22,66 € finanziert.

+ durch Spenden von durchschnittlich 22,25 € finanziert.

Doch schon mit einer Spende von 5 € kann Wikipedia sich auch in Zukunft erfolgreich diff --git a/banners/pad/form_items_var.ts b/banners/pad/form_items_var.ts new file mode 100644 index 000000000..b37f2304c --- /dev/null +++ b/banners/pad/form_items_var.ts @@ -0,0 +1,20 @@ +import FormItemsBuilder from '@src/utils/FormItemsBuilder/FormItemsBuilder'; +import { Translator } from '@src/Translator'; +import { DonationFormItems } from '@src/utils/FormItemsBuilder/DonationFormItems'; +import { Intervals } from '@src/utils/FormItemsBuilder/fields/Intervals'; +import { PaymentMethods } from '@src/utils/FormItemsBuilder/fields/PaymentMethods'; +import { NumberFormatter } from '@src/utils/DynamicContent/formatters/NumberFormatter'; + +export function createFormItems( translations: Translator, amountFormatter: NumberFormatter ): DonationFormItems { + return new FormItemsBuilder( translations, amountFormatter ) + .setIntervals( + Intervals.ONCE, + Intervals.MONTHLY, + Intervals.YEARLY + ) + .setAmounts( 5, 10, 20, 25, 50, 100 ) + .setPaymentMethods( + PaymentMethods.PAYPAL, + PaymentMethods.CREDIT_CARD + ).getItems(); +} diff --git a/banners/pad/styles/MainBanner.scss b/banners/pad/styles/MainBanner.scss index 96b84e1a6..f1e206403 100644 --- a/banners/pad/styles/MainBanner.scss +++ b/banners/pad/styles/MainBanner.scss @@ -1,12 +1,13 @@ @use 'src/themes/Treedip/variables/colors'; @use 'src/themes/Treedip/variables/fonts'; +@use 'src/themes/Treedip/variables/breakpoints'; $banner-height: 353px !default; $form-width: 256px !default; .wmde-banner { &-main { - min-height: $banner-height; + height: $banner-height; display: flex; flex-direction: column; padding: 12px 24px 0; @@ -22,18 +23,27 @@ $form-width: 256px !default; font-weight: bold; text-align: center; margin-top: 20px; - padding: 0 52px; + padding: 0 20px; position: relative; + @include breakpoints.medium-up { + padding: 0 52px; + } + &::before { content: ''; position: absolute; height: 1px; top: 50%; - left: 52px; - right: 52px; + left: 20px; + right: 20px; background: colors.$primary; z-index: 98; + + @include breakpoints.medium-up { + left: 52px; + right: 52px; + } } &-text { diff --git a/banners/pad/styles/MainBannerVar.scss b/banners/pad/styles/MainBannerVar.scss new file mode 100644 index 000000000..e485bc67e --- /dev/null +++ b/banners/pad/styles/MainBannerVar.scss @@ -0,0 +1,82 @@ +@use 'src/themes/Treedip/variables/colors'; +@use 'src/themes/Treedip/variables/fonts'; +@use 'src/themes/Treedip/variables/breakpoints'; + +$banner-height: 353px !default; +$form-width: 256px !default; + +.wmde-banner { + &-main { + height: $banner-height; + display: flex; + flex-direction: column; + padding: 12px 24px 0; + } + + &-content { + display: flex; + flex: 1 1 auto; + + &-headline { + font-family: fonts.$content; + font-size: 21px; + font-weight: bold; + text-align: center; + margin-top: 20px; + padding: 0 20px; + position: relative; + + @include breakpoints.medium-up { + padding: 0 52px; + } + + &::before { + content: ''; + position: absolute; + height: 1px; + top: 50%; + left: 20px; + right: 20px; + background: colors.$primary; + z-index: 98; + + @include breakpoints.medium-up { + left: 52px; + right: 52px; + } + } + + &-text { + position: relative; + display: inline-block; + z-index: 99; + padding: 0 10px; + line-height: 24px; + background: colors.$white; + } + } + } + + &-column-left { + display: flex; + flex-direction: column; + justify-content: space-between; + flex: 1 1 auto; + overflow-y: hidden; + margin-right: 20px; + + border: 5px solid colors.$primary; + border-radius: 9px; + padding: 20px 0; + } + + &-column-right { + flex: 1 1 $form-width; + width: $form-width; + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; + padding: 10px 16px 10px 0; + } +} diff --git a/banners/pad/styles/styles.scss b/banners/pad/styles/styles.scss index 6071a902c..c94d937c4 100644 --- a/banners/pad/styles/styles.scss +++ b/banners/pad/styles/styles.scss @@ -2,7 +2,7 @@ @use 'src/components/BannerConductor/banner-transition'; @use './Banner'; @use 'MainBanner' with ( - $banner-height: 353px, + $banner-height: 378px, $form-width: 256px ); @use 'src/themes/UseOfFunds/UseOfFunds'; diff --git a/banners/pad/styles/styles_var.scss b/banners/pad/styles/styles_var.scss new file mode 100644 index 000000000..35ed1c910 --- /dev/null +++ b/banners/pad/styles/styles_var.scss @@ -0,0 +1,44 @@ +// This is the file where we import the theme-specific component styles +@use 'src/components/BannerConductor/banner-transition'; +@use './Banner'; +@use './MainBannerVar' with ( + $banner-height: 378px, + $form-width: 35% +); +@use 'src/themes/UseOfFunds/UseOfFunds'; +@use 'src/themes/Treedip/defaults'; +@use 'src/themes/Treedip/ButtonClose/ButtonClose'; +@use 'src/themes/Treedip/ProgressBar/ProgressBar' with ( + $progress-bar-margin: 0 15px +); +@use 'src/themes/Treedip/DonationForm/DonationForm' with ( + $button-font-size: 12px +); +@use 'src/themes/Treedip/DonationForm/MultiStepDonation'; +@use 'src/themes/Treedip/DonationForm/SubComponents/SelectGroup' with ( + $interval-option-width: 33.3333% +); +@use 'src/themes/Treedip/DonationForm/SubComponents/SelectGroupImageLabel'; +@use 'src/themes/Treedip/DonationForm/SubComponents/SelectGroupButtons' with ( + $height: 42px, + $padding: 0 8px 8px +); +@use 'src/themes/Treedip/DonationForm/SubComponents/SelectCustomAmountButton' with ( + $height: 42px, + $padding: 0 8px 8px +); +@use 'src/themes/Treedip/DonationForm/SubComponents/SmsBox'; +@use 'src/themes/Treedip/DonationForm/Forms/MainDonationForm' with ( + $padding: 0 +); +@use 'src/themes/Treedip/DonationForm/Forms/UpgradeToYearlyButtonForm'; +@use 'src/themes/Treedip/DonationForm/Forms/CustomAmountForm'; +@use 'src/themes/Treedip/Footer/FooterAlreadyDonated'; +@use 'src/themes/Treedip/Footer/BannerFooter' with ( + $right-column-width: 35% +); +@use 'src/themes/Treedip/Footer/SelectionInput'; +@use 'src/themes/Treedip/Message/Message'; +@use 'src/themes/Treedip/Slider/KeenSlider'; +@use 'src/themes/Treedip/AlreadyDonatedModal/AlreadyDonatedModal'; +@use 'src/themes/Treedip/SoftClose/SoftClose'; diff --git a/src/components/DonationForm/MultiStepDonation.vue b/src/components/DonationForm/MultiStepDonation.vue index 2c6b9f6a9..8438235aa 100644 --- a/src/components/DonationForm/MultiStepDonation.vue +++ b/src/components/DonationForm/MultiStepDonation.vue @@ -18,7 +18,7 @@ diff --git a/src/themes/Treedip/DonationForm/SubComponents/SelectCustomAmountButton.scss b/src/themes/Treedip/DonationForm/SubComponents/SelectCustomAmountButton.scss index 860a5ae1d..2f90b6165 100644 --- a/src/themes/Treedip/DonationForm/SubComponents/SelectCustomAmountButton.scss +++ b/src/themes/Treedip/DonationForm/SubComponents/SelectCustomAmountButton.scss @@ -5,13 +5,14 @@ $font-size: 12px !default; $height: 36px !default; $border-color: #9aa0a7 !default; +$padding: 0 4px 8px !default; .wmde-banner { @include SelectCustomAmount.layout; &-select-custom-amount { position: relative; - padding: 0 4px 8px; + padding: $padding; &-input-container { width: 100%; diff --git a/src/themes/Treedip/DonationForm/SubComponents/SelectGroupButtons.scss b/src/themes/Treedip/DonationForm/SubComponents/SelectGroupButtons.scss index e91291359..ffb1e71bb 100644 --- a/src/themes/Treedip/DonationForm/SubComponents/SelectGroupButtons.scss +++ b/src/themes/Treedip/DonationForm/SubComponents/SelectGroupButtons.scss @@ -5,11 +5,12 @@ $font-size: 12px !default; $height: 30px !default; $border-color: #9aa0a7 !default; $background-color: #f8f9fa !default; +$padding: 0 4px 8px !default; .wmde-banner { &-select-group { &-option { - padding: 0 4px 8px; + padding: $padding; label { display: block; @@ -25,7 +26,7 @@ $background-color: #f8f9fa !default; background: $background-color; border: 1px solid $border-color; border-radius: 2px; - min-height: $height; + height: $height; cursor: pointer; text-align: center; font-size: $font-size; diff --git a/src/themes/Treedip/DonationForm/SubComponents/SelectGroupImageLabel.scss b/src/themes/Treedip/DonationForm/SubComponents/SelectGroupImageLabel.scss new file mode 100644 index 000000000..8e0f24cd8 --- /dev/null +++ b/src/themes/Treedip/DonationForm/SubComponents/SelectGroupImageLabel.scss @@ -0,0 +1,46 @@ +@use '@src/themes/Treedip/variables/colors'; +@use '@src/themes/Treedip/variables/breakpoints'; + +.wmde-banner { + &-select-group-label { + svg { + width: auto; + padding: 0 5px; + } + &.with-logos { + display: flex; + justify-content: center; + } + + .paypal-logo { + max-width: 90px; + } + + &.credit-cards { + padding: 10px 0; + + svg { + padding: 0 5px; + } + } + + .mastercard-logo { + transform: scale( 1.5 ); + } + } + + &-select-group-input:checked + .wmde-banner-select-group-label.with-logos { + svg path, + svg rect { + fill: colors.$white !important; // stylelint-disable-line + + &.highlight-transparent { + fill: transparent !important; // stylelint-disable-line + } + + &.highlight { + fill: colors.$secondary !important; // stylelint-disable-line + } + } + } +} diff --git a/test/banners/pad/components/BannerVar.spec.ts b/test/banners/pad/components/BannerVar.spec.ts new file mode 100644 index 000000000..7512d78f4 --- /dev/null +++ b/test/banners/pad/components/BannerVar.spec.ts @@ -0,0 +1,117 @@ +import { afterEach, beforeEach, describe, test } from 'vitest'; +import { mount, VueWrapper } from '@vue/test-utils'; +import Banner from '../../../../banners/pad/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( 'BannerVar.vue', () => { + let wrapper: VueWrapper; + beforeEach( () => { + resetFormModel( formModel ); + } ); + + const getWrapper = ( dynamicContent: DynamicContent = null ): VueWrapper => { + // 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 + }, + 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; + }; + + afterEach( () => { + wrapper.unmount(); + } ); + + 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' ] + ] )( '%s', async ( testName: string ) => { + await softCloseFeatures[ testName ]( getWrapper() ); + } ); + } ); + + describe( 'Use of Funds', () => { + test.each( [ + [ 'expectShowsUseOfFunds' ], + [ 'expectHidesUseOfFunds' ] + ] )( '%s', async ( testName: string ) => { + await useOfFundsFeatures[ testName ]( getWrapper() ); + } ); + } ); + +} );