vielleicht kommen wir gerade ungelegen, aber dennoch: Klicken Sie jetzt bitte nicht weg! Am
- heutigen {{ currentDayName }}, den {{ currentDate }}, bitten wir Sie bescheiden, die Unabhängigkeit
- von Wikipedia zu unterstützen.
+ heutigen {{ currentDayName }}, den {{ currentDateTime }}, bitten wir Sie bescheiden,
+ die Unabhängigkeit von Wikipedia zu unterstützen.
@@ -39,22 +39,34 @@
diff --git a/banners/mobile/content/BannerText.vue b/banners/mobile/content/BannerText.vue
index dbf9d1b80..669e20e53 100644
--- a/banners/mobile/content/BannerText.vue
+++ b/banners/mobile/content/BannerText.vue
@@ -6,7 +6,7 @@
vielleicht kommen wir gerade ungelegen, aber dennoch: Klicken Sie jetzt bitte nicht weg! Am heutigen
- {{ currentDayName }}, den {{ currentDate }}, bitten wir Sie bescheiden, die Unabhängigkeit von
+ {{ currentDayName }}, den {{ currentDateTime }}, bitten wir Sie bescheiden, die Unabhängigkeit von
Wikipedia zu unterstützen. Insgesamt spenden 99% nichts - sie übergehen diesen Aufruf. Die
durchschnittliche Spende beträgt 22,25 €, doch bereits 10 € helfen uns weiter.
Die meisten Menschen spenden, weil sie Wikipedia nützlich finden. Hat
@@ -18,14 +18,31 @@
diff --git a/banners/mobile/content/messages/DynamicCampaignTextOverwrite.de.ts b/banners/mobile/content/messages/DynamicCampaignTextOverwrite.de.ts
new file mode 100644
index 000000000..33792ae8c
--- /dev/null
+++ b/banners/mobile/content/messages/DynamicCampaignTextOverwrite.de.ts
@@ -0,0 +1,19 @@
+import { TranslationMessages } from '@src/Translator';
+
+const Translations: TranslationMessages = {
+
+ 'date-month-time-1': '{{day}} Januar, um {{time}} Uhr',
+ 'date-month-time-2': '{{day}} Februar, um {{time}} Uhr',
+ 'date-month-time-3': '{{day}} März, um {{time}} Uhr',
+ 'date-month-time-4': '{{day}} April, um {{time}} Uhr',
+ 'date-month-time-5': '{{day}} Mai, um {{time}} Uhr',
+ 'date-month-time-6': '{{day}} Juni, um {{time}} Uhr',
+ 'date-month-time-7': '{{day}} Juli, um {{time}} Uhr',
+ 'date-month-time-8': '{{day}} August, um {{time}} Uhr',
+ 'date-month-time-9': '{{day}} September, um {{time}} Uhr',
+ 'date-month-time-10': '{{day}} Oktober, um {{time}} Uhr',
+ 'date-month-time-11': '{{day}} November, um {{time}} Uhr',
+ 'date-month-time-12': '{{day}} Dezember, um {{time}} Uhr'
+};
+
+export default Translations;
diff --git a/banners/mobile/event_map.ts b/banners/mobile/event_map.ts
index bbfe83649..7bb6ae360 100644
--- a/banners/mobile/event_map.ts
+++ b/banners/mobile/event_map.ts
@@ -20,6 +20,7 @@ export default new Map( [
[ BannerSubmitEvent.EVENT_NAME, ( e: BannerSubmitEvent ): WMDESizeIssueEvent => {
switch ( e.feature ) {
+ case 'MiniBanner':
case 'UpgradeToYearlyForm':
return new WMDESizeIssueEvent( `submit-${e.userChoice}`, createViewportInfo(), 1 );
default:
diff --git a/banners/mobile/messages.ts b/banners/mobile/messages.ts
index cf8be364c..81ce709dc 100644
--- a/banners/mobile/messages.ts
+++ b/banners/mobile/messages.ts
@@ -1,5 +1,6 @@
import CustomAmountFormDe from '@src/components/DonationForm/Forms/messages/CustomAmountForm.de';
import DynamicCampaignTextDe from '@src/utils/DynamicContent/messages/DynamicCampaignText.de';
+import DynamicCampaignTextDeOverwrite from './content/messages/DynamicCampaignTextOverwrite.de';
import { TranslationMessages } from '@src/Translator';
import UpgradeToYearlyDe from '@src/components/DonationForm/Forms/messages/UpgradeToYearly.de';
import SoftCloseDe from '@src/components/SoftClose/messages/SoftClose.de';
@@ -10,6 +11,7 @@ import MainDonationFormDe from '@src/components/DonationForm/Forms/messages/Main
const messages: TranslationMessages = {
...CustomAmountFormDe,
...DynamicCampaignTextDe,
+ ...DynamicCampaignTextDeOverwrite,
...UpgradeToYearlyDe,
...SoftCloseDe,
...AddressFormDe,
diff --git a/campaign_info.toml b/campaign_info.toml
index 2eff4e4b1..76ed6d0d3 100644
--- a/campaign_info.toml
+++ b/campaign_info.toml
@@ -33,9 +33,9 @@ resolution = ["800x600", "1024x768", "1280x960", "1600x1200", "1920x1200", "2560
[mobile]
name = "Mobile"
icon = "mobile"
-campaign = "C23_WMDE_Mobile_DE_10"
-description = "based on VAR 09, Use the word hi, informal text"
-campaign_tracking = "mob-de-10-ba-231123"
+campaign = "C23_WMDE_Mobile_DE_11_2"
+description = "based on ctrl 10, Var redirects users to the donation page with the amount button"
+campaign_tracking = "mob-de-11-ba-231201"
preview_link = "/mobile/wiki/Wikipedia:Hauptseite?devbanner={{banner}}&banner=B22_WMDE_local_prototype&useskin=minerva"
preview_url = 'https://de.m.wikipedia.org/wiki/Wikipedia:Hauptseite?banner={{banner}}&useskin=minerva&devMode'
wrapper_template = "wikipedia_org"
@@ -44,13 +44,13 @@ use_of_funds_source = "MediaWiki:WMDE_Fundraising/UseOfFunds_2023_DE"
# Banners of the campaign, key after "banners" can be anything
[mobile.banners.ctrl]
filename = "./banners/mobile/banner_ctrl.ts"
-pagename = "B23_WMDE_Mobile_DE_10_ctrl"
-tracking = "org-mob10-231123-ctrl"
+pagename = "B23_WMDE_Mobile_DE_11_2_ctrl"
+tracking = "org-mob11_2-231201-ctrl"
[mobile.banners.var]
filename = "./banners/mobile/banner_var.ts"
-pagename = "B23_WMDE_Mobile_DE_10_var"
-tracking = "org-mob10-231123-var"
+pagename = "B23_WMDE_Mobile_DE_11_2_var"
+tracking = "org-mob11_2-231201-var"
[mobile.test_matrix]
device = [ 'samsung_s10', 'iphone_xs_max', 'iphone_5s', 'iphone_se', "iphone_8", "iphone_12_mini", "iphone_7_plus", "iphone_11_pro_max"]
diff --git a/src/createDonationURL.ts b/src/createDonationURL.ts
new file mode 100644
index 000000000..e12a2c6e5
--- /dev/null
+++ b/src/createDonationURL.ts
@@ -0,0 +1,26 @@
+/* eslint-disable camelcase */
+import { TrackingParameters } from '@src/domain/TrackingParameters';
+import { ImpressionCount } from '@src/utils/ImpressionCount';
+
+const DONATE_LINK_URL = 'https://spenden.wikimedia.de';
+
+/**
+ * This function is used when a component (other than a donation form submit button) is supposed to link directly
+ * to the fundraising donation page and a URL with tracking information is needed for that.
+ *
+ * For creating the target URL for the banner donation form, see `createFormActions.ts` instead.
+ * @param {TrackingParameters} tracking
+ * @param {ImpressionCount} impressionCount
+ * @param {Record} extraUrlParameters
+ */
+export function createDonationURL( tracking: TrackingParameters, impressionCount: ImpressionCount, extraUrlParameters: Record = {} ): string {
+ const urlParameters = new URLSearchParams( {
+ piwik_kwd: tracking.keyword,
+ piwik_campaign: tracking.campaign,
+ impCount: String( impressionCount.overallCountIncremented ),
+ bImpCount: String( impressionCount.bannerCountIncremented ),
+ ...extraUrlParameters
+ } );
+
+ return `${DONATE_LINK_URL}?${urlParameters}`;
+}
diff --git a/src/createFallbackDonationLink.ts b/src/createFallbackDonationLink.ts
deleted file mode 100644
index 58fefe5fc..000000000
--- a/src/createFallbackDonationLink.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-/* eslint-disable camelcase */
-import { TrackingParameters } from '@src/domain/TrackingParameters';
-import { ImpressionCount } from '@src/utils/ImpressionCount';
-
-const DONATE_LINK_URL = 'https://spenden.wikimedia.de';
-
-export function createFallbackDonationLink( tracking: TrackingParameters, impressionCount: ImpressionCount, extraUrlParameters: Record = {} ): string {
- const urlParameters = new URLSearchParams( {
- piwik_kwd: tracking.keyword.replace( /(ctrl|var)/g, 'mini' ),
- piwik_campaign: tracking.campaign,
- impCount: String( impressionCount.overallCountIncremented ),
- bImpCount: String( impressionCount.bannerCountIncremented ),
- ...extraUrlParameters
- } );
-
- return `${DONATE_LINK_URL}?${urlParameters}`;
-}
diff --git a/src/createFallbackDonationURL.ts b/src/createFallbackDonationURL.ts
new file mode 100644
index 000000000..aadf91bcb
--- /dev/null
+++ b/src/createFallbackDonationURL.ts
@@ -0,0 +1,15 @@
+import { TrackingParameters } from '@src/domain/TrackingParameters';
+import { ImpressionCount } from '@src/utils/ImpressionCount';
+import { createDonationURL } from '@src/createDonationURL';
+
+/**
+ * This function is used for the fallback banner, as it replaces the usual tracking parameters with mini
+ *
+ * @param {TrackingParameters} tracking
+ * @param {ImpressionCount} impressionCount
+ * @param {Record} extraUrlParameters
+ */
+export function createFallbackDonationURL( tracking: TrackingParameters, impressionCount: ImpressionCount, extraUrlParameters: Record = {} ): string {
+ tracking.keyword = tracking.keyword.replace( /(ctrl|var)/g, 'mini' );
+ return createDonationURL( tracking, impressionCount, extraUrlParameters );
+}
diff --git a/src/createFormActions.ts b/src/createFormActions.ts
index 891271a37..fcd95a92e 100644
--- a/src/createFormActions.ts
+++ b/src/createFormActions.ts
@@ -6,6 +6,14 @@ import { ImpressionCount } from '@src/utils/ImpressionCount';
const DONATE_WITH_ADDRESS_URL = 'https://spenden.wikimedia.de/donation/new';
const DONATE_ANONYMOUSLY_URL = 'https://spenden.wikimedia.de/donation/add';
+/**
+ * This function is used to create the form action (target URL) explicitly for the donation form submit on the banner.
+ *
+ * For creating a generic link (incl. tracking information) to the fundraising donation page, see `createDonationURL.ts`
+ * @param {TrackingParameters} tracking
+ * @param {ImpressionCount} impressionCount
+ * @param {Record} extraUrlParameters
+ */
export function createFormActions( tracking: TrackingParameters, impressionCount: ImpressionCount, extraUrlParameters: Record = {} ): FormActions {
const urlParameters = new URLSearchParams( {
piwik_kwd: tracking.keyword,
diff --git a/test/banners/mobile/components/BannerCtrl.spec.ts b/test/banners/mobile/components/BannerCtrl.spec.ts
index 5d418cdce..a1fc16294 100644
--- a/test/banners/mobile/components/BannerCtrl.spec.ts
+++ b/test/banners/mobile/components/BannerCtrl.spec.ts
@@ -17,7 +17,7 @@ import { DynamicContent } from '@src/utils/DynamicContent/DynamicContent';
import { fullPageBannerFeatures } from '@test/features/FullPageBanner';
import { miniBannerPreselectFeatures } from '@test/features/MiniBannerPreselect';
import { Tracker } from '@src/tracking/Tracker';
-import { bannerContentAnimatedTextFeatures } from '@test/features/BannerContent';
+import { bannerContentAnimatedTextFeatures, bannerContentDateAndTimeFeatures } from '@test/features/BannerContent';
let pageScroller: PageScroller;
let tracker: Tracker;
@@ -84,6 +84,13 @@ describe( 'BannerCtrl.vue', () => {
] )( '%s', async ( testName: string ) => {
await bannerContentAnimatedTextFeatures[ testName ]( getWrapper );
} );
+
+ test.each( [
+ [ 'expectShowsLiveDateAndTimeInMiniBanner' ],
+ [ 'expectShowsLiveDateAndTimeInFullPageBanner' ]
+ ] )( '%s', async ( testName: string ) => {
+ await bannerContentDateAndTimeFeatures[ testName ]( getWrapper );
+ } );
} );
describe( 'Donation Form Happy Paths', () => {
diff --git a/test/banners/mobile/components/BannerVar.spec.ts b/test/banners/mobile/components/BannerVar.spec.ts
index c20a0f3fd..7a3ddb8ae 100644
--- a/test/banners/mobile/components/BannerVar.spec.ts
+++ b/test/banners/mobile/components/BannerVar.spec.ts
@@ -1,4 +1,4 @@
-import { afterEach, beforeEach, describe, test, vi } from 'vitest';
+import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
import { mount, VueWrapper } from '@vue/test-utils';
import Banner from '../../../../banners/mobile/components/BannerVar.vue';
import { BannerStates } from '@src/components/BannerConductor/StateMachine/BannerStates';
@@ -15,9 +15,9 @@ import { useFormModel } from '@src/components/composables/useFormModel';
import { resetFormModel } from '@test/resetFormModel';
import { DynamicContent } from '@src/utils/DynamicContent/DynamicContent';
import { fullPageBannerFeatures } from '@test/features/FullPageBanner';
-import { miniBannerPreselectFeatures } from '@test/features/MiniBannerPreselect';
import { Tracker } from '@src/tracking/Tracker';
-import { bannerContentAnimatedTextFeatures } from '@test/features/BannerContent';
+import { bannerContentAnimatedTextFeatures, bannerContentDateAndTimeFeatures } from '@test/features/BannerContent';
+import { BannerSubmitEvent } from '@src/tracking/events/BannerSubmitEvent';
let pageScroller: PageScroller;
let tracker: Tracker;
@@ -49,7 +49,8 @@ describe( 'BannerVar.vue', () => {
bannerState: BannerStates.Pending,
useOfFundsContent,
pageScroller,
- remainingImpressions: 10
+ remainingImpressions: 10,
+ donationURL: 'https://spenden.wikimedia.de'
},
global: {
mocks: {
@@ -84,6 +85,13 @@ describe( 'BannerVar.vue', () => {
] )( '%s', async ( testName: string ) => {
await bannerContentAnimatedTextFeatures[ testName ]( getWrapper );
} );
+
+ test.each( [
+ [ 'expectShowsLiveDateAndTimeInMiniBanner' ],
+ [ 'expectShowsLiveDateAndTimeInFullPageBanner' ]
+ ] )( '%s', async ( testName: string ) => {
+ await bannerContentDateAndTimeFeatures[ testName ]( getWrapper );
+ } );
} );
describe( 'Donation Form Happy Paths', () => {
@@ -140,12 +148,15 @@ describe( 'BannerVar.vue', () => {
await miniBannerFeatures[ testName ]( getWrapper() );
} );
- test.each( [
- [ 'expectShowsFullPageWhenPreselectIsClicked' ],
- [ 'expectPreselectsAmountWhenPreselectIsClicked' ],
- [ 'expectTrackingEventIsFiredWhenPreselectIsClicked' ]
- ] )( '%s', async ( testName: string ) => {
- await miniBannerPreselectFeatures[ testName ]( getWrapper(), tracker );
+ test( 'sends users directly to the donation form page with 10 euros preselected', async () => {
+ const location = { href: '' };
+ Object.defineProperty( window, 'location', { writable: true, configurable: true, value: location } );
+ const localWrapper = getWrapper();
+
+ await localWrapper.find( '.wmde-banner-mini-button-preselect' ).trigger( 'click' );
+
+ expect( tracker.trackEvent ).toHaveBeenCalledWith( new BannerSubmitEvent( 'MiniBanner', 'donate-10-euro' ) );
+ expect( location.href ).toStrictEqual( 'https://spenden.wikimedia.de' );
} );
} );
diff --git a/test/features/BannerContent.ts b/test/features/BannerContent.ts
index 612ec6ef9..8dfe97dd5 100644
--- a/test/features/BannerContent.ts
+++ b/test/features/BannerContent.ts
@@ -145,6 +145,50 @@ const expectShowsLiveTimeInSlideshow = async ( getWrapper: ( dynamicContent: Dyn
expect( wrapper.find( '.wmde-banner-slider' ).text() ).toContain( 'Third Date and Time' );
};
+const expectShowsLiveDateAndTimeInMiniBanner = async ( getWrapper: ( dynamicContent: DynamicContent ) => VueWrapper ): Promise => {
+ const dynamicContent = newDynamicContent();
+ // There are 2 live text elements mounted at the same time in the mobile banners meaning it will be initialised twice
+ dynamicContent.getCurrentDateAndTime = vi.fn().mockReturnValueOnce( 'Initial Date and Time' )
+ .mockReturnValueOnce( 'Initial Date and Time' )
+ .mockReturnValueOnce( 'Second Date and Time' )
+ .mockReturnValueOnce( 'Third Date and Time' );
+
+ const wrapper = getWrapper( dynamicContent );
+
+ expect( wrapper.find( '.wmde-banner-mini-slideshow' ).text() ).toContain( 'Initial Date and Time' );
+
+ await vi.advanceTimersByTimeAsync( 1000 );
+
+ expect( wrapper.find( '.wmde-banner-mini-slideshow' ).text() ).toContain( 'Second Date and Time' );
+
+ await vi.advanceTimersByTimeAsync( 1000 );
+
+ expect( wrapper.find( '.wmde-banner-mini-slideshow' ).text() ).toContain( 'Third Date and Time' );
+};
+
+const expectShowsLiveDateAndTimeInFullPageBanner = async ( getWrapper: ( dynamicContent: DynamicContent ) => VueWrapper ): Promise => {
+ const dynamicContent = newDynamicContent();
+ // There are 2 live text elements mounted at the same time in the mobile banners meaning it will be initialised twice
+ dynamicContent.getCurrentDateAndTime = vi.fn().mockReturnValueOnce( 'Initial Date and Time' )
+ .mockReturnValueOnce( 'Initial Date and Time' )
+ .mockReturnValueOnce( 'Second Date and Time' )
+ .mockReturnValueOnce( 'Third Date and Time' );
+
+ const wrapper = getWrapper( dynamicContent );
+
+ await wrapper.find( '.wmde-banner-mini-button' ).trigger( 'click' );
+
+ expect( wrapper.find( '.wmde-banner-message' ).text() ).toContain( 'Initial Date and Time' );
+
+ await vi.advanceTimersByTimeAsync( 1000 );
+
+ expect( wrapper.find( '.wmde-banner-message' ).text() ).toContain( 'Second Date and Time' );
+
+ await vi.advanceTimersByTimeAsync( 1000 );
+
+ expect( wrapper.find( '.wmde-banner-message' ).text() ).toContain( 'Third Date and Time' );
+};
+
export const bannerContentFeatures: Record ) => Promise> = {
expectSlideShowPlaysWhenBecomesVisible,
expectSlideShowStopsOnFormInteraction
@@ -166,5 +210,7 @@ export const bannerContentDateAndTimeFeatures: Record {
+ it( 'should create donation URL with tracking information', () => {
+ const extraParameters = { locale: 'de_DE', ast: '1' };
+ const ctrlLink = createDonationURL( { campaign: 'C1', keyword: 'banner-ctrl' }, new ImpressionCountStub(), extraParameters );
+ const varLink = createDonationURL( { campaign: 'C1', keyword: 'banner-var' }, new ImpressionCountStub(), extraParameters );
+
+ expect( ctrlLink ).toStrictEqual( 'https://spenden.wikimedia.de?piwik_kwd=banner-ctrl&piwik_campaign=C1&impCount=1&bImpCount=1&locale=de_DE&ast=1' );
+ expect( varLink ).toStrictEqual( 'https://spenden.wikimedia.de?piwik_kwd=banner-var&piwik_campaign=C1&impCount=1&bImpCount=1&locale=de_DE&ast=1' );
+ } );
+} );
diff --git a/test/unit/createFallbackDonationLink.spec.ts b/test/unit/createFallbackDonationLink.spec.ts
deleted file mode 100644
index fb4ba565b..000000000
--- a/test/unit/createFallbackDonationLink.spec.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { describe, expect, it } from 'vitest';
-import { ImpressionCountStub } from '@test/fixtures/ImpressionCountStub';
-import { createFallbackDonationLink } from '@src/createFallbackDonationLink';
-
-describe( 'createFallbackDonationLink', () => {
- it( 'should create fallback donation link', () => {
- const extraParameters = { locale: 'de_DE', ast: '1' };
- const ctrlLink = createFallbackDonationLink( { campaign: 'C1', keyword: 'banner-ctrl' }, new ImpressionCountStub(), extraParameters );
- const varLink = createFallbackDonationLink( { campaign: 'C1', keyword: 'banner-var' }, new ImpressionCountStub(), extraParameters );
- const expected = 'https://spenden.wikimedia.de?piwik_kwd=banner-mini&piwik_campaign=C1&impCount=1&bImpCount=1&locale=de_DE&ast=1';
-
- expect( ctrlLink ).toStrictEqual( expected );
- expect( varLink ).toStrictEqual( expected );
- } );
-} );
diff --git a/test/unit/createFallbackDonationURL.spec.ts b/test/unit/createFallbackDonationURL.spec.ts
new file mode 100644
index 000000000..3691dc732
--- /dev/null
+++ b/test/unit/createFallbackDonationURL.spec.ts
@@ -0,0 +1,15 @@
+import { describe, expect, it } from 'vitest';
+import { ImpressionCountStub } from '@test/fixtures/ImpressionCountStub';
+import { createFallbackDonationURL } from '@src/createFallbackDonationURL';
+
+describe( 'createFallbackDonationURL', () => {
+ it( 'should create donation URL with tracking information', () => {
+ const extraParameters = { locale: 'de_DE', ast: '1' };
+ const ctrlLink = createFallbackDonationURL( { campaign: 'C1', keyword: 'banner-ctrl' }, new ImpressionCountStub(), extraParameters );
+ const varLink = createFallbackDonationURL( { campaign: 'C1', keyword: 'banner-var' }, new ImpressionCountStub(), extraParameters );
+ const expected = 'https://spenden.wikimedia.de?piwik_kwd=banner-mini&piwik_campaign=C1&impCount=1&bImpCount=1&locale=de_DE&ast=1';
+
+ expect( ctrlLink ).toStrictEqual( expected );
+ expect( varLink ).toStrictEqual( expected );
+ } );
+} );