Skip to content

Commit 7a4f526

Browse files
authored
test: MMQA - 1711 - [Mobile] Update Predict e2e tests to enable features that were disabled due to feature flag updates (#29154)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. --> ## **Description** Brings Predict E2E test feature flag mocks into parity with production values. Two remote feature flag overrides in predict smoke tests diverged from production after a feature flag registry sync ([PR #28444](#28444)). This PR aligns the mocks: - **`exploreSectionsOrder`**: Replaced the explicit section ordering arrays with `{}` in 4 predict smoke specs. On production this flag is empty; the app falls back to hardcoded defaults which produce the same layout. The Homepage component does not consume this flag at all — it only affects TrendingView/Explore, which these tests don't exercise. - **`predictLiveSports`**: Added `'nba'` to the leagues list (now `['nfl', 'nba']`) to match production. This causes NBA markets (Spurs vs. Pelicans) to render via `PredictGameDetailsContent`, which uses a different cash-out button test ID (`predict-picks-cash-out-button-{positionId}`). Updated the `PredictDetailsPage` page object with a new `tapGameCashOutButton(positionId)` method and updated `predict-cash-out.spec.ts` to use it. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: [MMQA-1711](https://consensyssoftware.atlassian.net/browse/MMQA-1711) ## **Manual testing steps** <!-- Gherkin scenarios for this change --> **Feature: Predict E2E prod parity** **Scenario: Cash out on NBA game market uses correct button** - Given the predict smoke tests use production-parity feature flag mocks - When the predict-cash-out test runs against Spurs vs. Pelicans - Then the test taps the game-details cash-out button (PredictPickItem testID) - And the cash-out flow completes successfully **Scenario: Predict tests work without explicit exploreSectionsOrder** - Given exploreSectionsOrder is set to `{}` in all predict smoke specs - When any predict smoke test runs (cash-out, open-position, geo-restriction, withdraw) - Then the Homepage renders with the default section order - And the test navigates to predictions by test ID without issue ## **Screenshots/Recordings** ### **Before** N/A — test-only changes, no UI impact. ### **After** N/A — test-only changes, no UI impact. ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. [MMQA-1711]: https://consensyssoftware.atlassian.net/browse/MMQA-1711?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Test-only changes that adjust feature-flag mocks and E2E selectors; low product risk, but could affect Predict smoke test stability if testIDs/position IDs drift. > > **Overview** > Aligns Predict E2E remote feature-flag mocks with current production defaults by removing the `predictLiveSports` override from `remoteFeatureFlagPredictEnabled`. > > Updates Predict smoke specs to interact with the *game-details* UI: adds a shared `SPURS_PELICANS_POSITION_ID`, introduces `PredictDetailsPage.tapGameCashOutButton(positionId)` and `tapGameBetYesButton()`, and switches cash-out/position-opening tests to use the new testIDs for NBA/game markets. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f452736. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent b22424a commit 7a4f526

6 files changed

Lines changed: 50 additions & 22 deletions

File tree

tests/api-mocking/mock-responses/feature-flags-mocks.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,6 @@ export const remoteFeatureFlagPredictEnabled = (enabled = true) => ({
132132
enabled: false,
133133
minimumVersion: '7.60.0',
134134
},
135-
// Exclude 'nba' — NBA markets render PredictGameDetailsContent which uses a different cash-out testID not yet supported by E2E page objects
136-
predictLiveSports: {
137-
versions: {
138-
'7.67.0': { enabled: true, leagues: ['nfl'] },
139-
'7.70.0': { enabled: true, leagues: ['nfl'] },
140-
},
141-
},
142135
});
143136

144137
export const remoteFeatureFlagHomepageSectionsV1Enabled = (enabled = true) => ({

tests/api-mocking/mock-responses/polymarket/polymarket-constants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ export const CONDITIONAL_TOKENS_CONTRACT_ADDRESS =
3939
export const POLYGON_EIP7702_CONTRACT_ADDRESS =
4040
'0x63c0c19a282a1B52b07dD5a65b58948A07DAE32B';
4141

42+
// Predict position ID for Spurs vs. Pelicans
43+
export const SPURS_PELICANS_POSITION_ID =
44+
'110743925263777693447488608878982152642205002490046349037358337248548507433643';
45+
4246
// EIP-7702 format: 0xef01 (magic byte) + 00 (padding) + 20-byte contract address
4347
// This format indicates an EOA is upgraded with EIP-7702
4448
export const EIP7702_CODE_FORMAT = (contractAddress: string): string => {

tests/page-objects/Predict/PredictDetailsPage.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ import {
1414
PredictMarketDetailsSelectorsIDs,
1515
PredictMarketDetailsSelectorsText,
1616
} from '../../../app/components/UI/Predict/Predict.testIds';
17+
import { PREDICT_PICK_ITEM_TEST_IDS } from '../../../app/components/UI/Predict/components/PredictPicks/PredictPickItem.testIds';
18+
import {
19+
PREDICT_GAME_DETAILS_FOOTER,
20+
PREDICT_GAME_DETAILS_FOOTER_TEST_IDS,
21+
} from '../../../app/components/UI/Predict/components/PredictGameDetailsFooter/PredictGameDetailsFooter.testIds';
22+
import { PREDICT_ACTION_BUTTONS_TEST_IDS } from '../../../app/components/UI/Predict/components/PredictActionButtons/PredictActionButtons.testIds';
23+
import { PREDICT_BET_BUTTONS_TEST_IDS } from '../../../app/components/UI/Predict/components/PredictActionButtons/PredictBetButtons.testIds';
1724

1825
class PredictDetailsPage {
1926
get container(): EncapsulatedElementType {
@@ -208,6 +215,14 @@ class PredictDetailsPage {
208215
});
209216
}
210217

218+
get gameBetYesButton(): EncapsulatedElementType {
219+
const testID = `${PREDICT_GAME_DETAILS_FOOTER}${PREDICT_GAME_DETAILS_FOOTER_TEST_IDS.ACTION_BUTTONS}${PREDICT_ACTION_BUTTONS_TEST_IDS.PREDICT_BET_BUTTON}${PREDICT_BET_BUTTONS_TEST_IDS.PREDICT_BET_BUTTON_YES}`;
220+
return encapsulated({
221+
detox: () => Matchers.getElementByID(testID),
222+
appium: () => PlaywrightMatchers.getElementById(testID, { exact: true }),
223+
});
224+
}
225+
211226
async waitForScreenToDisplay(): Promise<void> {
212227
await Assertions.expectElementToBeVisible(this.container, {
213228
description: 'Predict market details screen',
@@ -246,12 +261,32 @@ class PredictDetailsPage {
246261
});
247262
}
248263

264+
getGameCashOutButton(positionId: string): EncapsulatedElementType {
265+
const testID = `${PREDICT_PICK_ITEM_TEST_IDS.PREDICT_PICKS_CASH_OUT_BUTTON}-${positionId}`;
266+
return encapsulated({
267+
detox: () => Matchers.getElementByID(testID),
268+
appium: () => PlaywrightMatchers.getElementById(testID, { exact: true }),
269+
});
270+
}
271+
272+
async tapGameCashOutButton(positionId: string): Promise<void> {
273+
await UnifiedGestures.waitAndTap(this.getGameCashOutButton(positionId), {
274+
description: 'Game details cash out button',
275+
});
276+
}
277+
249278
async tapOpenPositionValue(): Promise<void> {
250279
await UnifiedGestures.waitAndTap(this.getOpenPositionValueButton(), {
251280
description: 'Celtics outcome button',
252281
});
253282
}
254283

284+
async tapGameBetYesButton(): Promise<void> {
285+
await UnifiedGestures.waitAndTap(this.gameBetYesButton, {
286+
description: 'Game bet yes button',
287+
});
288+
}
289+
255290
async tapPositionAmount(amount: string): Promise<void> {
256291
const digits = amount.split('');
257292

tests/smoke/predict/predict-cash-out.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import TabBarComponent from '../../page-objects/wallet/TabBarComponent';
2424
import ActivitiesView from '../../page-objects/Transactions/ActivitiesView';
2525
import PredictActivityDetails from '../../page-objects/Transactions/predictionsActivityDetails';
2626
import { predictCashOutFlowAnalyticsExpectations } from '../../helpers/analytics/expectations/predict-cash-out.analytics';
27+
import { SPURS_PELICANS_POSITION_ID } from '../../api-mocking/mock-responses/polymarket/polymarket-constants';
2728

2829
/*
2930
Test Scenario: Cash out on open position - Spurs vs. Pelicans
@@ -68,7 +69,9 @@ describe(SmokePredictions('Predictions'), () => {
6869
await Assertions.expectElementToBeVisible(PredictDetailsPage.container);
6970
await POLYMARKET_POST_CASH_OUT_MOCKS(mockServer);
7071

71-
await PredictDetailsPage.tapCashOutButton();
72+
await PredictDetailsPage.tapGameCashOutButton(
73+
SPURS_PELICANS_POSITION_ID,
74+
);
7275
await Assertions.expectElementToBeVisible(PredictCashOutPage.container);
7376

7477
await Assertions.expectElementToBeVisible(

tests/smoke/predict/predict-geo-restriction.spec.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import {
2222
POLYMARKET_GEO_BLOCKED_MOCKS,
2323
} from '../../api-mocking/mock-responses/polymarket/polymarket-mocks';
2424
import PredictAddFunds from '../../page-objects/Predict/PredictAddFunds';
25+
import { getEventsPayloads } from '../../helpers/analytics/helpers';
26+
import SoftAssert from '../../framework/SoftAssert';
27+
import { SPURS_PELICANS_POSITION_ID } from '../../api-mocking/mock-responses/polymarket/polymarket-constants';
2528
import {
2629
geoBlockedPredictActionExpectations,
2730
geoBlockedCashoutExpectations,
@@ -119,7 +122,9 @@ describe(
119122
await WalletView.scrollAndTapPredictionsPosition(
120123
'Spurs vs. Pelicans',
121124
);
122-
await PredictDetailsPage.tapCashOutButton();
125+
await PredictDetailsPage.tapGameCashOutButton(
126+
SPURS_PELICANS_POSITION_ID,
127+
);
123128

124129
await PredictUnavailableView.expectVisible();
125130
await PredictUnavailableView.tapGotIt();

tests/smoke/predict/predict-open-position.spec.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ describe(SmokePredictions('Predictions'), () => {
7878
positionDetails.category,
7979
positionDetails.marketIndex,
8080
);
81-
await PredictDetailsPage.tapOpenPositionValue();
81+
await PredictDetailsPage.tapGameBetYesButton();
8282

8383
await POLYMARKET_POST_OPEN_POSITION_MOCKS(mockServer);
8484

@@ -89,18 +89,6 @@ describe(SmokePredictions('Predictions'), () => {
8989

9090
await PredictDetailsPage.tapOpenPosition();
9191

92-
await Assertions.expectElementToBeVisible(
93-
PredictDetailsPage.positionsTab,
94-
{
95-
description:
96-
'Position tab should appear after opening a new position',
97-
},
98-
);
99-
100-
await Assertions.expectTextDisplayed(positionDetails.name, {
101-
description: 'Position card for Celtics vs. Nets should appear',
102-
});
103-
10492
await PredictDetailsPage.tapBackButton();
10593
await Assertions.expectTextDisplayed(positionDetails.newBalance, {
10694
description: `USDC balance should display ${positionDetails.newBalance} after opening position`,

0 commit comments

Comments
 (0)