diff --git a/src/app/components/ATIAnalytics/atiUrl/index.ts b/src/app/components/ATIAnalytics/atiUrl/index.ts index 6b2bcda0ab6..ecb8e88afb2 100644 --- a/src/app/components/ATIAnalytics/atiUrl/index.ts +++ b/src/app/components/ATIAnalytics/atiUrl/index.ts @@ -45,6 +45,7 @@ export const buildATIPageTrackPath = ({ categoryName, campaigns, nationsProducer, + experimentVariant, }: ATIPageTrackingProps) => { const href = getHref(platform); const referrer = getReferrer(platform, origin, previousPath); @@ -214,6 +215,22 @@ export const buildATIPageTrackPath = ({ value: getATIMarketingString(href, campaignType), wrap: false, }, + ...(experimentVariant + ? [ + { + key: 'mv_test', + description: 'Article page banner experiment', + value: `Election Banner Experiment`, + wrap: false, + }, + { + key: 'mv_creation', + description: 'Article page banner variant', + value: `${experimentVariant}`, + wrap: false, + }, + ] + : []), ...getRSSMarketingString(href, campaignType), ...(onOnionTld() ? [ diff --git a/src/app/components/ATIAnalytics/params/genericPage/buildParams.ts b/src/app/components/ATIAnalytics/params/genericPage/buildParams.ts index 1c0cf86f44d..96b5e492473 100644 --- a/src/app/components/ATIAnalytics/params/genericPage/buildParams.ts +++ b/src/app/components/ATIAnalytics/params/genericPage/buildParams.ts @@ -25,6 +25,7 @@ export const buildPageATIParams = ({ producerId, timePublished, timeUpdated, + experimentVariant, } = atiData; return { @@ -49,6 +50,7 @@ export const buildPageATIParams = ({ statsDestination, timePublished, timeUpdated, + ...(experimentVariant && { experimentVariant }), }; }; diff --git a/src/app/components/ATIAnalytics/types.ts b/src/app/components/ATIAnalytics/types.ts index a5f438cec35..5e3f67700dd 100644 --- a/src/app/components/ATIAnalytics/types.ts +++ b/src/app/components/ATIAnalytics/types.ts @@ -30,6 +30,7 @@ export interface ATIData { producerName?: string | null; timePublished?: string | null; timeUpdated?: string | null; + experimentVariant?: string | null; } export interface PageData { @@ -131,6 +132,7 @@ export interface ATIPageTrackingProps { categoryName?: string | null; campaigns?: { campaignId?: string; campaignName?: string }[] | null; nationsProducer?: string | null; + experimentVariant?: string | null; } export interface ATIProps { diff --git a/src/app/hooks/useOptimizelyMvtVariation/index.jsx b/src/app/hooks/useOptimizelyMvtVariation/index.jsx index af80b2f2129..0335acf9abe 100644 --- a/src/app/hooks/useOptimizelyMvtVariation/index.jsx +++ b/src/app/hooks/useOptimizelyMvtVariation/index.jsx @@ -1,11 +1,13 @@ import { useContext } from 'react'; import { OptimizelyContext } from '@optimizely/react-sdk'; import { RequestContext } from '#contexts/RequestContext'; +import useToggle from '#hooks/useToggle'; import activateExperiment from './activateExperiment'; const useOptimizelyMvtVariation = id => { const { optimizely } = useContext(OptimizelyContext); const { mvtExperiments } = useContext(RequestContext); + const { enabled: electionBannerEnabled } = useToggle('electionBanner'); if (!mvtExperiments || mvtExperiments.length === 0 || id === null) { return null; @@ -15,7 +17,7 @@ const useOptimizelyMvtVariation = id => { ({ experimentName }) => experimentName === id, ); - if (!experiment) return null; + if (!experiment || !electionBannerEnabled) return null; const isEnabled = experiment.enabled; const variation = isEnabled && experiment.variation; diff --git a/src/app/hooks/useOptimizelyMvtVariation/index.test.jsx b/src/app/hooks/useOptimizelyMvtVariation/index.test.jsx index 75e8a4cb5b1..3412b2d6259 100644 --- a/src/app/hooks/useOptimizelyMvtVariation/index.test.jsx +++ b/src/app/hooks/useOptimizelyMvtVariation/index.test.jsx @@ -1,6 +1,7 @@ import React from 'react'; import { renderHook } from '#app/components/react-testing-library-with-providers'; import { RequestContextProvider } from '#contexts/RequestContext'; +import { ToggleContextProvider } from '#contexts/ToggleContext'; import useOptimizelyMvtVariation from '.'; import * as activateExperiment from './activateExperiment'; @@ -22,7 +23,11 @@ describe('useOptimizelyMvtVariation custom hook', () => { pathname: 'bar', }; const wrapper = ({ children }) => ( - {children} + + + {children} + + ); return renderHook(() => useOptimizelyMvtVariation(flagId), { wrapper, diff --git a/src/app/hooks/useOptimizelyVariation/index.jsx b/src/app/hooks/useOptimizelyVariation/index.jsx index 6fc745815c4..7d522c301dc 100644 --- a/src/app/hooks/useOptimizelyVariation/index.jsx +++ b/src/app/hooks/useOptimizelyVariation/index.jsx @@ -2,7 +2,7 @@ import { useState, useEffect } from 'react'; import { useDecision } from '@optimizely/react-sdk'; -const isClientSide = true; +const isClientSide = false; // ALTHOUGH THIS FUNCTION BREAKS REACT RULES BY USING CONDITIONAL HOOKS, // WE CAN SAFELY DO SO SINCE isClientSide IS A CONSTANT AND THEREFORE GUARANTEES THAT diff --git a/src/app/pages/ArticlePage/ArticlePage.tsx b/src/app/pages/ArticlePage/ArticlePage.tsx index 61243f9ccfd..6e38ce2c167 100644 --- a/src/app/pages/ArticlePage/ArticlePage.tsx +++ b/src/app/pages/ArticlePage/ArticlePage.tsx @@ -1,8 +1,9 @@ /** @jsx jsx */ - -import { useContext } from 'react'; +/** @jsxFrag React.Fragment */ +import React, { useContext } from 'react'; import { jsx, useTheme } from '@emotion/react'; import useToggle from '#hooks/useToggle'; +import useOptimizelyMvtVariation from '#hooks/useOptimizelyMvtVariation'; import { singleTextBlock } from '#app/models/blocks'; import ArticleMetadata from '#containers/ArticleMetadata'; import { RequestContext } from '#contexts/RequestContext'; @@ -39,6 +40,8 @@ import CpsRecommendations from '#containers/CpsRecommendations'; import InlinePodcastPromo from '#containers/PodcastPromo/Inline'; import { Article, OptimoBylineBlock } from '#app/models/types/optimo'; import ScrollablePromo from '#components/ScrollablePromo'; +import OptimizelyArticleCompleteTracking from '#app/legacy/containers/OptimizelyArticleCompleteTracking'; +import OptimizelyPageViewTracking from '#app/legacy/containers/OptimizelyPageViewTracking'; import ElectionBanner from './ElectionBanner'; import ImageWithCaption from '../../components/ImageWithCaption'; @@ -87,6 +90,10 @@ const ArticlePage = ({ pageData }: { pageData: Article }) => { palette: { GREY_2, WHITE }, } = useTheme(); + const experimentVariant = useOptimizelyMvtVariation( + 'newswb_01_ap_banner_election', + ); + const allowAdvertising = pageData?.metadata?.allowAdvertising ?? false; const adcampaign = pageData?.metadata?.adCampaignKeyword; const isTransliterated = @@ -137,6 +144,7 @@ const ArticlePage = ({ pageData }: { pageData: Article }) => { const atiData = { ...atiAnalytics, ...(isCPS && { pageTitle: `${atiAnalytics.pageTitle} - ${brandName}` }), + ...(experimentVariant && { experimentVariant }), }; const topStoriesContent = pageData?.secondaryColumn?.topStories; @@ -305,6 +313,12 @@ const ArticlePage = ({ pageData }: { pageData: Article }) => { mobileDivider={showTopics} /> )} + {experimentVariant && ( + <> + + + + )} ); }; diff --git a/src/app/pages/ArticlePage/ElectionBanner/index.tsx b/src/app/pages/ArticlePage/ElectionBanner/index.tsx index 55952f5c0a9..2f7e7bedd5a 100644 --- a/src/app/pages/ArticlePage/ElectionBanner/index.tsx +++ b/src/app/pages/ArticlePage/ElectionBanner/index.tsx @@ -7,6 +7,7 @@ import AmpIframe from '#app/components/AmpIframe'; import useToggle from '#app/hooks/useToggle'; import { Tag } from '#app/components/Metadata/types'; import { ServiceContext } from '#app/contexts/ServiceContext'; +import useOptimizelyMvtVariation from '#app/hooks/useOptimizelyMvtVariation'; import { getEnvConfig } from '#app/lib/utilities/getEnvConfig'; import { MetadataTaggings } from '#app/models/types/metadata'; import { Services } from '#app/models/types/global'; @@ -35,6 +36,8 @@ export default function ElectionBanner({ aboutTags, taggings }: Props) { const { enabled: electionBannerEnabled }: { enabled: boolean | null } = useToggle('electionBanner'); + const variation = useOptimizelyMvtVariation('newswb_01_ap_banner_election'); + if (isLite) return null; const { @@ -57,6 +60,7 @@ export default function ElectionBanner({ aboutTags, taggings }: Props) { !isEditoriallySensitive && validAboutTag && electionBannerEnabled; if (!showBanner) return null; + if (variation === 'off') return null; const { SIMORGH_APP_ENV, diff --git a/src/app/pages/ArticlePage/index.tsx b/src/app/pages/ArticlePage/index.tsx index 116c11b5248..1e48edc5215 100644 --- a/src/app/pages/ArticlePage/index.tsx +++ b/src/app/pages/ArticlePage/index.tsx @@ -1,4 +1,7 @@ +import withOptimizelyProvider from '#app/legacy/containers/PageHandlers/withOptimizelyProvider'; import ArticlePage from './ArticlePage'; import applyBasicPageHandlers from '../utils/applyBasicPageHandlers'; -export default applyBasicPageHandlers(ArticlePage); +const OptimizelyArticle = withOptimizelyProvider(ArticlePage); + +export default applyBasicPageHandlers(OptimizelyArticle); diff --git a/src/server/utilities/mvtHeader/enabledExperimentsList.js b/src/server/utilities/mvtHeader/enabledExperimentsList.js index ddc954c7b85..a171f6d5e04 100644 --- a/src/server/utilities/mvtHeader/enabledExperimentsList.js +++ b/src/server/utilities/mvtHeader/enabledExperimentsList.js @@ -9,8 +9,8 @@ Add enabled experiments objects inside this array in this format: */ const enabledExperimentList = [ { - name: 'test_2', - services: ['pidgin'], + name: 'newswb_01_ap_banner_election', + services: ['mundo', 'portuguese'], pageTypes: ['article'], }, ];