Skip to content

Commit 0fe8aaa

Browse files
authored
test: fix unmatched mocked polymarket mocks (#30194)
<!-- 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`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** > Prevents Polymarket E2E tests from leaking live requests by adding a default gamma-api.polymarket.com/events/{id} mock response and ensuring it matches any numeric event id. > > Updates the trending feed mock for event details to use the same generalized numeric-id matcher (instead of hard-coding /events/1), so prefetch/highlight flows don’t crash on unmatched ids. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] 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. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] 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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: changes are limited to E2E test mocks/fixtures and onboarding test flow, reducing flaky/unmocked network calls without touching production logic. > > **Overview** > Prevents Polymarket E2E tests from leaking live requests by adding a default `gamma-api.polymarket.com/events/{id}` mock and broadening existing trending-feed event-detail mocks to match any numeric event id. > > Updates onboarding E2E flows to proceed past the new `OnboardingInterestQuestionnaire` step when opting into MetaMetrics, adds a page-object wrapper for that screen, and seeds `onboarding-fixture.json` with a stable `@MetaMask:AnalyticsId`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 91267e4. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 6a897d1 commit 0fe8aaa

5 files changed

Lines changed: 97 additions & 4 deletions

File tree

tests/api-mocking/mock-responses/defaults/polymarket-apis.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,23 @@ export const POLYMARKET_API_MOCKS = {
3838
responseCode: 200,
3939
response: { events: [] },
4040
},
41+
{
42+
urlEndpoint: /^https:\/\/gamma-api\.polymarket\.com\/events\/\d+(\?.*)?$/,
43+
responseCode: 200,
44+
response: {
45+
id: '1',
46+
slug: 'mock-prediction-event',
47+
title: 'Mock prediction event',
48+
description: 'E2E mock event',
49+
icon: 'https://polymarket.com/icon.png',
50+
closed: false,
51+
series: [],
52+
markets: [],
53+
tags: [],
54+
liquidity: 0,
55+
volume: 0,
56+
},
57+
},
4158
// gamma-api: markets list
4259
{
4360
urlEndpoint: /^https:\/\/gamma-api\.polymarket\.com\/markets(\?.*)?$/,

tests/api-mocking/mock-responses/trending-api-mocks.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,9 @@ export const TRENDING_API_MOCKS: MockEventsObject = {
164164
{
165165
// Event details fetched when user taps a prediction row in the trending feed.
166166
// Returns the same Bitcoin event payload as /events/pagination so the detail
167-
// screen renders without crashing.
168-
urlEndpoint: /https:\/\/gamma-api\.polymarket\.com\/events\/1(\?.*)?$/,
167+
// screen renders without crashing. Matches any numeric event id (highlights,
168+
// prefetch) — not only id "1".
169+
urlEndpoint: /https:\/\/gamma-api\.polymarket\.com\/events\/\d+(\?.*)?$/,
169170
responseCode: 200,
170171
response: {
171172
id: '1',

tests/flows/wallet.flow.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import PlaywrightUtilities from '../framework/PlaywrightUtilities';
4040
import AccountListBottomSheet from '../page-objects/wallet/AccountListBottomSheet';
4141
import MetaMetricsOptInView from '../page-objects/Onboarding/MetaMetricsOptInView';
4242
import PredictModalView from '../page-objects/Predict/PredictModalView';
43-
43+
import OnboardingInterestQuestionnaireView from '../page-objects/Onboarding/OnboardingInterestQuestionnaireView';
4444
const logger = createLogger({
4545
name: 'WalletFlow',
4646
});
@@ -231,6 +231,9 @@ export const importWalletWithRecoveryPhrase = async ({
231231

232232
await MetaMetricsOptInView.tapAgreeButton();
233233
}
234+
if (optInToMetrics) {
235+
await OnboardingInterestQuestionnaireView.tapContinueButton();
236+
}
234237
//'Should dismiss Enable device Notifications checks alert'
235238
await Assertions.expectElementToBeVisible(OnboardingSuccessView.container, {
236239
description: 'Onboarding Success View should be visible',
@@ -342,6 +345,10 @@ export const CreateNewWallet = async ({
342345
await MetaMetricsOptInView.tapAgreeButton();
343346
await device.disableSynchronization(); // Detox is hanging after wallet creation
344347

348+
if (optInToMetrics) {
349+
await OnboardingInterestQuestionnaireView.tapContinueButton();
350+
}
351+
345352
await Assertions.expectElementToBeVisible(OnboardingSuccessView.container, {
346353
description: 'Onboarding Success View should be visible',
347354
});
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
{
2-
"asyncState": {}
2+
"asyncState": {
3+
"@MetaMask:AnalyticsId": "00000000-0000-4000-8000-000000000000"
4+
}
35
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { OnboardingInterestQuestionnaireTestIds } from '../../../app/components/Views/OnboardingInterestQuestionnaire/OnboardingInterestQuestionnaire.testIds';
2+
import Matchers from '../../framework/Matchers';
3+
import {
4+
encapsulated,
5+
EncapsulatedElementType,
6+
} from '../../framework/EncapsulatedElement';
7+
import PlaywrightMatchers from '../../framework/PlaywrightMatchers';
8+
import UnifiedGestures from '../../framework/UnifiedGestures';
9+
10+
type InterestOptionId =
11+
| 'buy_and_sell_crypto'
12+
| 'consolidate_wallets'
13+
| 'advanced_trades'
14+
| 'predict_sports_events'
15+
| 'crypto_as_money'
16+
| 'connect_apps_sites';
17+
18+
class OnboardingInterestQuestionnaireView {
19+
get container(): EncapsulatedElementType {
20+
return encapsulated({
21+
detox: () =>
22+
Matchers.getElementByID(OnboardingInterestQuestionnaireTestIds.SCREEN),
23+
appium: () =>
24+
PlaywrightMatchers.getElementById(
25+
OnboardingInterestQuestionnaireTestIds.SCREEN,
26+
{ exact: true },
27+
),
28+
});
29+
}
30+
31+
get continueButton(): EncapsulatedElementType {
32+
return encapsulated({
33+
detox: () =>
34+
Matchers.getElementByID(
35+
OnboardingInterestQuestionnaireTestIds.CONTINUE_BUTTON,
36+
),
37+
appium: () =>
38+
PlaywrightMatchers.getElementById(
39+
OnboardingInterestQuestionnaireTestIds.CONTINUE_BUTTON,
40+
{ exact: true },
41+
),
42+
});
43+
}
44+
45+
getOptionById(id: InterestOptionId): EncapsulatedElementType {
46+
const testID = `${OnboardingInterestQuestionnaireTestIds.OPTION_PREFIX}${id}`;
47+
return encapsulated({
48+
detox: () => Matchers.getElementByID(testID),
49+
appium: () => PlaywrightMatchers.getElementById(testID, { exact: true }),
50+
});
51+
}
52+
53+
async tapContinueButton(): Promise<void> {
54+
await UnifiedGestures.waitAndTap(this.continueButton, {
55+
description: 'Onboarding Interest Questionnaire Continue Button',
56+
});
57+
}
58+
59+
async tapOption(id: InterestOptionId): Promise<void> {
60+
await UnifiedGestures.waitAndTap(this.getOptionById(id), {
61+
description: `Onboarding Interest Questionnaire Option: ${id}`,
62+
});
63+
}
64+
}
65+
66+
export default new OnboardingInterestQuestionnaireView();

0 commit comments

Comments
 (0)