Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const experimentsForPageMetrics: ExperimentsForPageTypeMetrics = [
'newswb_ws_article_account_promo_banner',
// enable page metrics after this experiment is activated
'newswb_ws_oj_order_referrer_search',
'newswb_ws_oj_order_referrer_search_aa_test',
],
},
{
Expand Down
1 change: 0 additions & 1 deletion src/app/hooks/useClickTrackerHandler/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ const OJ_COMPONENT_NAMES = [
const OJ_OPTIMIZELY_EXPERIMENTS = [
'test_page_views_aa_3',
'newswb_ws_oj_order_referrer_search',
'newswb_ws_oj_order_referrer_search_aa_test',
];

const OJ_OPTIMIZELY_CLICK_EVENTS = ['oj_clicks'];
Expand Down
83 changes: 15 additions & 68 deletions src/app/pages/ArticlePage/ArticlePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,61 +116,15 @@ import {
import TopStoriesSection from './PagePromoSections/TopStoriesSection';
import SearchOjExperiment from './SearchOjExperiment';
import {
isSearchOjAaVariant,
isSearchOjVariant,
MID_ARTICLE_OJ_EXPERIMENT_TRIGGER_ID,
SEARCH_OJ_AA_ACTIVATION_EVENT_NAME,
SEARCH_OJ_AA_EXPERIMENT_NAME,
SEARCH_OJ_ACTIVATION_EVENT_NAME,
SEARCH_OJ_EXPERIMENT_NAME,
SearchOjAaVariant,
SearchOjVariant,
} from './SearchOjExperiment/config';

// keep the flag name with the variation so tracking knows which experiment was chosen
type SearchOjExperimentDecision = {
experimentName:
| typeof SEARCH_OJ_EXPERIMENT_NAME
| typeof SEARCH_OJ_AA_EXPERIMENT_NAME;
experimentVariant: SearchOjVariant | SearchOjAaVariant;
searchVariant: SearchVariant | null;
};

type ActivateSearchOjExperimentProps = {
onDecision: (decision: SearchOjExperimentDecision) => void;
};

const ActivateSearchOjAaExperiment = ({
onDecision,
}: ActivateSearchOjExperimentProps) => {
const variation = useOptimizelyVariation({
experimentName: SEARCH_OJ_AA_EXPERIMENT_NAME,
experimentType: ExperimentType.CLIENT_SIDE,
});
const trackActivation = useCustomEventTracker({
eventName: SEARCH_OJ_AA_ACTIVATION_EVENT_NAME,
experimentName: SEARCH_OJ_AA_EXPERIMENT_NAME,
experimentVariant: variation ?? undefined,
});
const hasTrackedActivation = useRef(false);

useEffect(() => {
if (isSearchOjAaVariant(variation)) {
onDecision({
experimentName: SEARCH_OJ_AA_EXPERIMENT_NAME,
experimentVariant: variation,
// both aa groups keep the normal page layout
searchVariant: null,
});

if (!hasTrackedActivation.current) {
hasTrackedActivation.current = true;
trackActivation();
}
}
}, [onDecision, trackActivation, variation]);

return null;
onDecision: (variation: SearchOjVariant | null) => void;
};

const ActivateSearchOjExperiment = ({
Expand All @@ -190,26 +144,18 @@ const ActivateSearchOjExperiment = ({
const hasTrackedActivation = useRef(false);

useEffect(() => {
if (isSearchOjVariant(variation)) {
onDecision({
experimentName: SEARCH_OJ_EXPERIMENT_NAME,
experimentVariant: variation,
searchVariant: variation === 'control' ? null : variation,
});

if (!hasTrackedActivation.current) {
if (variation !== null) {
const validVariation = isSearchOjVariant(variation) ? variation : null;

onDecision(validVariation);

if (validVariation && !hasTrackedActivation.current) {
hasTrackedActivation.current = true;
trackActivation();
}
}
}, [onDecision, trackActivation, variation]);

// only check the aa flag after optimizely says the real flag is off
// this lets the dashboard choose which experiment runs without another deployment
if (variation === 'off') {
return <ActivateSearchOjAaExperiment onDecision={onDecision} />;
}

return null;
};

Expand Down Expand Up @@ -363,13 +309,13 @@ const ArticlePage = ({ pageData }: { pageData: Article }) => {
const [isDesktopViewport, setIsDesktopViewport] = useState(false);
const [hasExpandedContinueReading, setHasExpandedContinueReading] =
useState(false);
const [experimentDecision, setExperimentDecision] =
useState<SearchOjExperimentDecision | null>(null);
const [experimentVariant, setExperimentVariant] =
useState<SearchOjVariant | null>(null);
const searchOjExperimentProps: ComponentExperimentProps | undefined =
experimentDecision
experimentVariant
? {
experimentName: experimentDecision.experimentName,
experimentVariant: experimentDecision.experimentVariant,
experimentName: SEARCH_OJ_EXPERIMENT_NAME,
experimentVariant,
sendOptimizelyEvents: true,
}
: undefined;
Expand Down Expand Up @@ -595,7 +541,8 @@ const ArticlePage = ({ pageData }: { pageData: Article }) => {
promoImageRawBlock?.model as { locator?: string } | undefined
)?.locator;

const searchVariant = experimentDecision?.searchVariant ?? null;
const searchVariant: SearchVariant | null =
experimentVariant === 'control' ? null : experimentVariant;
const mobileOJOrder = useMobileOJComponentOrder(searchVariant);

const componentsToRender = {
Expand Down Expand Up @@ -812,7 +759,7 @@ const ArticlePage = ({ pageData }: { pageData: Article }) => {
<AccountPromotionalBannerExperiment />

{(isNearMidArticleOj || hasExpandedContinueReading) && (
<ActivateSearchOjExperiment onDecision={setExperimentDecision} />
<ActivateSearchOjExperiment onDecision={setExperimentVariant} />
)}

<ATIAnalytics />
Expand Down
19 changes: 0 additions & 19 deletions src/app/pages/ArticlePage/SearchOjExperiment/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@ export const SEARCH_OJ_EXPERIMENT_NAME = 'newswb_ws_oj_order_referrer_search';
export const SEARCH_OJ_ACTIVATION_EVENT_NAME =
'newswb_ws_oj_order_referrer_search';

// this temporary flag checks bucketing and tracking before the real experiment starts
// remove the aa setup after the production check is complete
export const SEARCH_OJ_AA_EXPERIMENT_NAME =
'newswb_ws_oj_order_referrer_search_aa_test';

export const SEARCH_OJ_AA_ACTIVATION_EVENT_NAME =
'newswb_ws_oj_order_referrer_search_aa_test';

// these values must match the variation keys in optimizely
export const SEARCH_OJ_VARIANTS = [
'control',
Expand All @@ -25,24 +17,13 @@ export const SEARCH_OJ_VARIANTS = [

export type SearchOjVariant = (typeof SEARCH_OJ_VARIANTS)[number];

// both groups use the normal page so their results can be compared like for like
export const SEARCH_OJ_AA_VARIANTS = ['control_a', 'control_b'] as const;

export type SearchOjAaVariant = (typeof SEARCH_OJ_AA_VARIANTS)[number];

// unknown values keep the existing control experience
export const isSearchOjVariant = (
variation: string | null,
): variation is SearchOjVariant =>
variation !== null &&
SEARCH_OJ_VARIANTS.includes(variation as SearchOjVariant);

export const isSearchOjAaVariant = (
variation: string | null,
): variation is SearchOjAaVariant =>
variation !== null &&
SEARCH_OJ_AA_VARIANTS.includes(variation as SearchOjAaVariant);

// this id is added to the real oj that triggers the experiment
export const MID_ARTICLE_OJ_EXPERIMENT_TRIGGER_ID =
'search-oj-experiment-trigger';
Loading