Skip to content

Commit 0c80a46

Browse files
committed
feat: implement Homepage Perps pills empty state AB test logic and analytics
1 parent d1d7312 commit 0c80a46

16 files changed

Lines changed: 408 additions & 31 deletions

app/components/Views/Homepage/Sections/Perpetuals/HomepagePerpsHomeSlot.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { forwardRef, useEffect, useMemo, useState } from 'react';
22
import { useABTest } from '../../../../../hooks';
33
import {
44
HOMEPAGE_PERPS_PILLS_EMPTY_AB_KEY,
5+
HOMEPAGE_PERPS_PILLS_EMPTY_AB_TEST_EXPOSURE_OPTIONS,
56
HOMEPAGE_PERPS_PILLS_EMPTY_VARIANTS,
67
} from '../../abTestConfig';
78
import {
@@ -82,13 +83,7 @@ const HomepagePerpsHomeSlot = forwardRef<
8283
const { variant: perpsPillsEmptyAbVariant } = useABTest(
8384
HOMEPAGE_PERPS_PILLS_EMPTY_AB_KEY,
8485
HOMEPAGE_PERPS_PILLS_EMPTY_VARIANTS,
85-
{
86-
experimentName: 'Homepage Perps empty state pills',
87-
variationNames: {
88-
control: 'Tile carousel empty state',
89-
treatment: 'Explore Perps Movers pills empty state',
90-
},
91-
},
86+
HOMEPAGE_PERPS_PILLS_EMPTY_AB_TEST_EXPOSURE_OPTIONS,
9287
);
9388

9489
const emptyStateUsesExplorePills =

app/components/Views/Homepage/Sections/Perpetuals/HomepagePerpsMoversSection.test.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import useHomeViewedEvent, {
1414
HomeSectionNames,
1515
} from '../../hooks/useHomeViewedEvent';
1616
import { useSectionPerformance } from '../../hooks/useSectionPerformance';
17+
import { HOMEPAGE_PERPS_PILLS_AB_EXPOSED_ANALYTICS_PROPERTY } from '../../abTestConfig';
1718
import HomepagePerpsMoversSection from './HomepagePerpsMoversSection';
1819

1920
const mockNavigate = jest.fn();
@@ -57,6 +58,19 @@ jest.mock('../../hooks/useSectionPerformance', () => ({
5758
useSectionPerformance: jest.fn(),
5859
}));
5960

61+
jest.mock('../../hooks/useHomepageTrendingTransactionActiveAbTests', () => ({
62+
useHomepageTrendingTransactionActiveAbTests: jest.fn(() => undefined),
63+
}));
64+
65+
jest.mock(
66+
'../../hooks/useHomepagePerpsPillsEmptyTransactionActiveAbTests',
67+
() => ({
68+
useHomepagePerpsPillsEmptyTransactionActiveAbTests: jest.fn(
69+
() => undefined,
70+
),
71+
}),
72+
);
73+
6074
jest.mock('../../../TrendingView/feeds/perps/PerpsPillItem', () => {
6175
const ReactLib = jest.requireActual('react');
6276
const RN = jest.requireActual('react-native');
@@ -193,6 +207,7 @@ describe('HomepagePerpsMoversSection', () => {
193207
PERPS_EVENT_VALUE.BUTTON_CLICKED.OPEN_POSITION,
194208
[PERPS_EVENT_PROPERTY.BUTTON_LOCATION]:
195209
PERPS_EVENT_VALUE.BUTTON_LOCATION.WALLET_HOME,
210+
[HOMEPAGE_PERPS_PILLS_AB_EXPOSED_ANALYTICS_PROPERTY]: true,
196211
},
197212
);
198213
});
@@ -213,6 +228,7 @@ describe('HomepagePerpsMoversSection', () => {
213228
totalSectionsLoaded: 6,
214229
isEmpty: false,
215230
itemCount: 1,
231+
additionalProperties: undefined,
216232
}),
217233
);
218234
});
@@ -225,6 +241,9 @@ describe('HomepagePerpsMoversSection', () => {
225241
expect(mockedUseHomeViewedEvent).toHaveBeenCalledWith(
226242
expect.objectContaining({
227243
sectionName: HomeSectionNames.PERPS,
244+
additionalProperties: {
245+
[HOMEPAGE_PERPS_PILLS_AB_EXPOSED_ANALYTICS_PROPERTY]: true,
246+
},
228247
}),
229248
);
230249
});

app/components/Views/Homepage/Sections/Perpetuals/HomepagePerpsMoversSection.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, {
22
forwardRef,
33
useCallback,
44
useImperativeHandle,
5+
useMemo,
56
useRef,
67
} from 'react';
78
import { View } from 'react-native';
@@ -21,6 +22,10 @@ import useHomeViewedEvent, {
2122
HomeSectionNames,
2223
} from '../../hooks/useHomeViewedEvent';
2324
import { useSectionPerformance } from '../../hooks/useSectionPerformance';
25+
import { useHomepageTrendingTransactionActiveAbTests } from '../../hooks/useHomepageTrendingTransactionActiveAbTests';
26+
import { useHomepagePerpsPillsEmptyTransactionActiveAbTests } from '../../hooks/useHomepagePerpsPillsEmptyTransactionActiveAbTests';
27+
import { mergeActiveAbTestAssignmentLists } from '../../../../../util/analytics/activeABTestAssignments';
28+
import { HOMEPAGE_PERPS_PILLS_AB_EXPOSED_ANALYTICS_PROPERTY } from '../../abTestConfig';
2429
import type { PerpsSectionProps } from './PerpsSectionWithProvider';
2530
import PillScrollList from '../../../TrendingView/components/PillScrollList';
2631
import PerpsPillItem from '../../../TrendingView/feeds/perps/PerpsPillItem';
@@ -51,6 +56,22 @@ const HomepagePerpsMoversSection = forwardRef<
5156
const analyticsName = sectionNameOverride ?? HomeSectionNames.PERPS;
5257
const title = strings('trending.perps_movers');
5358

59+
const trendingTransactionActiveAbTests =
60+
useHomepageTrendingTransactionActiveAbTests();
61+
const perpsPillsEmptyTransactionActiveAbTests =
62+
useHomepagePerpsPillsEmptyTransactionActiveAbTests(true);
63+
const transactionActiveAbTestsForPillsNavigation = useMemo(
64+
() =>
65+
mergeActiveAbTestAssignmentLists(
66+
trendingTransactionActiveAbTests,
67+
perpsPillsEmptyTransactionActiveAbTests,
68+
),
69+
[
70+
trendingTransactionActiveAbTests,
71+
perpsPillsEmptyTransactionActiveAbTests,
72+
],
73+
);
74+
5475
const perps = usePerpsFeed({
5576
variant: 'all',
5677
withTileExtras: false,
@@ -89,6 +110,10 @@ const HomepagePerpsMoversSection = forwardRef<
89110
totalSectionsLoaded,
90111
isEmpty,
91112
itemCount,
113+
additionalProperties:
114+
analyticsName === HomeSectionNames.PERPS
115+
? { [HOMEPAGE_PERPS_PILLS_AB_EXPOSED_ANALYTICS_PROPERTY]: true }
116+
: undefined,
92117
});
93118

94119
useSectionPerformance({
@@ -106,6 +131,7 @@ const HomepagePerpsMoversSection = forwardRef<
106131
PERPS_EVENT_VALUE.BUTTON_CLICKED.OPEN_POSITION,
107132
[PERPS_EVENT_PROPERTY.BUTTON_LOCATION]:
108133
PERPS_EVENT_VALUE.BUTTON_LOCATION.WALLET_HOME,
134+
[HOMEPAGE_PERPS_PILLS_AB_EXPOSED_ANALYTICS_PROPERTY]: true,
109135
});
110136
}, [track]);
111137

@@ -130,6 +156,9 @@ const HomepagePerpsMoversSection = forwardRef<
130156
item={item}
131157
marketDetailsSource={PERPS_EVENT_VALUE.SOURCE.HOME_SECTION}
132158
onCardPress={trackPillWalletHome}
159+
transactionActiveAbTests={
160+
transactionActiveAbTestsForPillsNavigation
161+
}
133162
/>
134163
)}
135164
keyExtractor={(pillItem) => pillItem.market.symbol}

app/components/Views/Homepage/Sections/Perpetuals/PerpsSection.test.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
PERPS_EVENT_VALUE,
1010
} from '@metamask/perps-controller';
1111
import { selectIsFirstTimePerpsUser } from '../../../../UI/Perps/selectors/perpsController';
12+
import { HOMEPAGE_PERPS_PILLS_AB_EXPOSED_ANALYTICS_PROPERTY } from '../../abTestConfig';
1213

1314
const mockNavigate = jest.fn();
1415
const mockTrack = jest.fn();
@@ -23,6 +24,19 @@ jest.mock('../../hooks/useHomepageTrendingTransactionActiveAbTests', () => ({
2324
mockUseHomepageTrendingTransactionActiveAbTests(),
2425
}));
2526

27+
const mockUseHomepagePerpsPillsEmptyTransactionActiveAbTests = jest.fn<
28+
{ key: string; value: string; key_value_pair?: string }[] | undefined,
29+
[]
30+
>(() => undefined);
31+
32+
jest.mock(
33+
'../../hooks/useHomepagePerpsPillsEmptyTransactionActiveAbTests',
34+
() => ({
35+
useHomepagePerpsPillsEmptyTransactionActiveAbTests: () =>
36+
mockUseHomepagePerpsPillsEmptyTransactionActiveAbTests(),
37+
}),
38+
);
39+
2640
jest.mock('../../../../../selectors/preferencesController', () => ({
2741
...jest.requireActual('../../../../../selectors/preferencesController'),
2842
selectPrivacyMode: () => false,
@@ -298,6 +312,9 @@ describe('PerpsSection', () => {
298312
isRefreshing: false,
299313
});
300314
mockUseHomepageTrendingTransactionActiveAbTests.mockReturnValue(undefined);
315+
mockUseHomepagePerpsPillsEmptyTransactionActiveAbTests.mockReturnValue(
316+
undefined,
317+
);
301318
});
302319

303320
it('renders section title', () => {
@@ -735,6 +752,19 @@ describe('PerpsSection', () => {
735752

736753
fireEvent.press(screen.getByTestId('perps-market-tile-SOL'));
737754

755+
expect(mockTrack).toHaveBeenCalledWith(
756+
MetaMetricsEvents.PERPS_UI_INTERACTION,
757+
expect.objectContaining({
758+
[PERPS_EVENT_PROPERTY.INTERACTION_TYPE]:
759+
PERPS_EVENT_VALUE.INTERACTION_TYPE.BUTTON_CLICKED,
760+
[PERPS_EVENT_PROPERTY.BUTTON_CLICKED]:
761+
PERPS_EVENT_VALUE.BUTTON_CLICKED.OPEN_POSITION,
762+
[PERPS_EVENT_PROPERTY.BUTTON_LOCATION]:
763+
PERPS_EVENT_VALUE.BUTTON_LOCATION.WALLET_HOME,
764+
[HOMEPAGE_PERPS_PILLS_AB_EXPOSED_ANALYTICS_PROPERTY]: true,
765+
}),
766+
);
767+
738768
expect(mockNavigate).toHaveBeenCalledWith(Routes.PERPS.ROOT, {
739769
screen: Routes.PERPS.MARKET_DETAILS,
740770
params: { market, source: 'home_section' },

app/components/Views/Homepage/Sections/Perpetuals/PerpsSection.tsx

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,14 @@ import useHomeViewedEvent, {
5555
} from '../../hooks/useHomeViewedEvent';
5656
import { useSectionPerformance } from '../../hooks/useSectionPerformance';
5757
import type { PerpsSectionProps } from './PerpsSectionWithProvider';
58+
import { HOMEPAGE_PERPS_PILLS_AB_EXPOSED_ANALYTICS_PROPERTY } from '../../abTestConfig';
5859
import HomepageSectionUnrealizedPnlRow, {
5960
type HomepageUnrealizedPnlTone,
6061
} from '../../components/HomepageSectionUnrealizedPnlRow';
6162
import { useHomepageTrendingTransactionActiveAbTests } from '../../hooks/useHomepageTrendingTransactionActiveAbTests';
63+
import { useHomepagePerpsPillsEmptyTransactionActiveAbTests } from '../../hooks/useHomepagePerpsPillsEmptyTransactionActiveAbTests';
6264
import type { TransactionActiveAbTestEntry } from '../../../../../util/transactions/transaction-active-ab-test-attribution-registry';
65+
import { mergeActiveAbTestAssignmentLists } from '../../../../../util/analytics/activeABTestAssignments';
6366

6467
const MAX_ITEMS = 5;
6568
const MAX_TRENDING_MARKETS = 5;
@@ -70,17 +73,26 @@ interface UsePerpsTrendingCarouselDataArgs {
7073
}
7174

7275
interface UsePerpsNavigationHandlersArgs {
73-
isDedicatedTrendingSection?: boolean;
7476
trendingTransactionActiveAbTests?: TransactionActiveAbTestEntry[];
77+
extraTransactionActiveAbTests?: TransactionActiveAbTestEntry[];
7578
}
7679

7780
const usePerpsNavigationHandlers = ({
78-
isDedicatedTrendingSection = false,
7981
trendingTransactionActiveAbTests,
82+
extraTransactionActiveAbTests,
8083
}: UsePerpsNavigationHandlersArgs = {}) => {
8184
const navigation = useNavigation<NavigationProp<PerpsNavigationParamList>>();
8285
const isFirstTimePerpsUser = useSelector(selectIsFirstTimePerpsUser);
8386

87+
const marketDetailsTransactionActiveAbTests = useMemo(
88+
() =>
89+
mergeActiveAbTestAssignmentLists(
90+
trendingTransactionActiveAbTests,
91+
extraTransactionActiveAbTests,
92+
),
93+
[trendingTransactionActiveAbTests, extraTransactionActiveAbTests],
94+
);
95+
8496
const navigateToTutorialOrScreen = useCallback(
8597
(screen: string, params: Record<string, unknown>) => {
8698
if (isFirstTimePerpsUser) {
@@ -113,19 +125,14 @@ const usePerpsNavigationHandlers = ({
113125
navigateToTutorialOrScreen(Routes.PERPS.MARKET_DETAILS, {
114126
market,
115127
source: PERPS_EVENT_VALUE.SOURCE.HOME_SECTION,
116-
...(isDedicatedTrendingSection &&
117-
trendingTransactionActiveAbTests?.length
128+
...(marketDetailsTransactionActiveAbTests?.length
118129
? {
119-
transactionActiveAbTests: trendingTransactionActiveAbTests,
130+
transactionActiveAbTests: marketDetailsTransactionActiveAbTests,
120131
}
121132
: {}),
122133
});
123134
},
124-
[
125-
isDedicatedTrendingSection,
126-
navigateToTutorialOrScreen,
127-
trendingTransactionActiveAbTests,
128-
],
135+
[navigateToTutorialOrScreen, marketDetailsTransactionActiveAbTests],
129136
);
130137

131138
return {
@@ -263,12 +270,6 @@ const PerpsSectionMain = forwardRef<SectionRefreshHandle, PerpsSectionProps>(
263270
usePerpsConnection();
264271
const { track } = usePerpsEventTracking();
265272
const privacyMode = useSelector(selectPrivacyMode);
266-
const {
267-
navigateToTutorialOrScreen,
268-
handleViewAllPerps,
269-
handleViewMorePerps,
270-
handleTilePress,
271-
} = usePerpsNavigationHandlers();
272273

273274
const { positions, isInitialLoading: positionsLoading } =
274275
usePerpsLivePositions({
@@ -316,6 +317,37 @@ const PerpsSectionMain = forwardRef<SectionRefreshHandle, PerpsSectionProps>(
316317
);
317318

318319
const hasItems = displayPositions.length > 0 || displayOrders.length > 0;
320+
321+
const trendingTransactionActiveAbTests =
322+
useHomepageTrendingTransactionActiveAbTests();
323+
const perpsPillsEmptyTransactionActiveAbTests =
324+
useHomepagePerpsPillsEmptyTransactionActiveAbTests(!hasItems);
325+
const {
326+
navigateToTutorialOrScreen,
327+
handleViewAllPerps,
328+
handleViewMorePerps,
329+
handleTilePress,
330+
} = usePerpsNavigationHandlers({
331+
trendingTransactionActiveAbTests,
332+
extraTransactionActiveAbTests: perpsPillsEmptyTransactionActiveAbTests,
333+
});
334+
335+
const handleTrendingMarketPress = useCallback(
336+
(market: PerpsMarketData) => {
337+
track(MetaMetricsEvents.PERPS_UI_INTERACTION, {
338+
[PERPS_EVENT_PROPERTY.INTERACTION_TYPE]:
339+
PERPS_EVENT_VALUE.INTERACTION_TYPE.BUTTON_CLICKED,
340+
[PERPS_EVENT_PROPERTY.BUTTON_CLICKED]:
341+
PERPS_EVENT_VALUE.BUTTON_CLICKED.OPEN_POSITION,
342+
[PERPS_EVENT_PROPERTY.BUTTON_LOCATION]:
343+
PERPS_EVENT_VALUE.BUTTON_LOCATION.WALLET_HOME,
344+
[HOMEPAGE_PERPS_PILLS_AB_EXPOSED_ANALYTICS_PROPERTY]: true,
345+
});
346+
handleTilePress(market);
347+
},
348+
[handleTilePress, track],
349+
);
350+
319351
const hasFilledPositions = positions.length > 0;
320352

321353
// When user has no positions/orders, keep skeleton visible until markets load.
@@ -409,6 +441,10 @@ const PerpsSectionMain = forwardRef<SectionRefreshHandle, PerpsSectionProps>(
409441
totalSectionsLoaded,
410442
isEmpty,
411443
itemCount,
444+
additionalProperties:
445+
analyticsName === HomeSectionNames.PERPS && !hasItems
446+
? { [HOMEPAGE_PERPS_PILLS_AB_EXPOSED_ANALYTICS_PROPERTY]: true }
447+
: undefined,
412448
});
413449

414450
useSectionPerformance({
@@ -484,7 +520,7 @@ const PerpsSectionMain = forwardRef<SectionRefreshHandle, PerpsSectionProps>(
484520
markets={allCarouselMarkets}
485521
watchlistSymbolSet={watchlistSymbolSet}
486522
sparklines={sparklines}
487-
onPressMarket={handleTilePress}
523+
onPressMarket={handleTrendingMarketPress}
488524
onPressViewMore={handleViewMorePerps}
489525
/>
490526
)}
@@ -514,7 +550,6 @@ const PerpsSectionTrendingOnly = forwardRef<
514550
useHomepageTrendingTransactionActiveAbTests();
515551
const { handleViewAllPerps, handleViewMorePerps, handleTilePress } =
516552
usePerpsNavigationHandlers({
517-
isDedicatedTrendingSection: true,
518553
trendingTransactionActiveAbTests,
519554
});
520555
const { marketsLoading, allCarouselMarkets, watchlistSymbolSet } =

0 commit comments

Comments
 (0)