Skip to content

Commit e8d5375

Browse files
authored
fix: test multiple ios execution (#27635)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** - **Platform helpers** in `tests/component-view/platform.ts`: `describeForPlatforms`, `itForPlatforms`, `itOnlyForPlatforms`, `itEach`, `describeEach`, `getTargetPlatforms`. Tests run per OS (iOS/Android); optional `filter` and `TEST_OS` supported. - **Array-style tests**: `itEach(table)(name, fn)` and `describeEach(table)(name, define)` run each row for each OS (like Jest `it.each` / `describe.each` with platform dimension). - **View tests** now import from `tests/component-view/platform` instead of `app/util/test/platform` (BridgeView, Wallet, WalletActions, AssetDetails, Trending, Send, Earn, etc.). - **Docs**: `writing-tests.md` updated with a "describe / it and platform" section (helpers, filter, example). SKILL.md and AGENTS.md updated <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **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** - [ ] 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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Medium risk because it changes the component-view test harness behavior (platform scoping and test generation), which can alter how many tests run and expose new CI failures/flakiness across iOS/Android. > > **Overview** > **Improves component-view test execution across iOS/Android.** The PR updates `tests/component-view/platform.ts` to better scope `describeForPlatforms` (avoiding duplicate nested platform runs) and adds table-driven helpers `itEach`/`describeEach` for running each case across platforms. > > It also migrates existing `*.view.test.tsx` files to import platform helpers from `tests/component-view/platform` instead of the older `app/util/test/platform`, and updates the testing docs/agent references to document the new helpers, filters, and `TEST_OS` environment targeting. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 090d516. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 7176f71 commit e8d5375

14 files changed

Lines changed: 128 additions & 10 deletions

File tree

.agents/skills/component-view-test/SKILL.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ tests/component-view/
5656
├── mocks.ts ← Engine + native mocks (import this first, always)
5757
├── render.tsx ← renderComponentViewScreen, renderScreenWithRoutes
5858
├── stateFixture.ts ← StateFixtureBuilder (createStateFixture)
59+
├── platform.ts ← describeForPlatforms, itForPlatforms (run per iOS/Android)
5960
├── api-mocking/ ← HTTP API mocks (nock) — extensible, one file per feature
6061
├── presets/ ← initialState<Feature>() builders — one file per feature area
6162
└── renderers/ ← render<Feature>View() functions — one file per feature area

.agents/skills/component-view-test/references/writing-tests.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,38 @@ const defaultBridgeWithTokens = (overrides?: Record<string, unknown>) => {
195195

196196
Then each test only specifies its delta from this baseline.
197197

198+
### describe / it and platform (iOS + Android)
199+
200+
Import from `tests/component-view/platform`. All helpers accept an optional **filter** (3rd arg): `'ios'` | `'android'` | `['ios','android']` | `{ only: 'ios' }` | `{ skip: ['android'] }`. Env: `TEST_OS=ios` or `TEST_OS=android` to run only one OS.
201+
202+
| Helper | Use |
203+
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
204+
| `describeForPlatforms(name, define, filter?)` | One describe per OS. Inside, `define({ os })`; use `it()` or `itForPlatforms()` — each runs once per that OS. |
205+
| `itForPlatforms(name, (ctx) => {}, filter?)` | One `it` per OS. Callback receives `{ os }`. |
206+
| `itOnlyForPlatforms(name, fn, filter?)` | Same as `itForPlatforms` but registers `it.only`. |
207+
| `itEach(table)(name, (row) => {}, filter?)` | One `it` per table row × per OS. Use `$key` in name to interpolate row fields. |
208+
| `describeEach(table)(name, (row) => { it('...', () => {}); }, filter?)` | One describe per row × per OS. Use `$key` in name. |
209+
| `getTargetPlatforms(filter?)` | Returns `['ios','android']` (or filtered list) for custom loops. |
210+
211+
Example — `itEach` (each case runs on iOS and Android):
212+
213+
```typescript
214+
import { itEach } from '../../../../../../tests/component-view/platform';
215+
216+
const cases = [
217+
{ name: 'renders empty', amount: '0' },
218+
{ name: 'displays fiat', amount: '1' },
219+
];
220+
itEach(cases)('$name', ({ amount }) => {
221+
const { findByDisplayValue } = renderDefault({
222+
bridge: { sourceAmount: amount },
223+
});
224+
expect(findByDisplayValue(amount)).toBeOnTheScreen();
225+
});
226+
```
227+
228+
Jest modifiers (`it.only`, `it.skip`, `describe.only`, `describe.skip`) work as usual inside these blocks.
229+
198230
### Minimal template
199231

200232
```typescript

app/components/UI/Bridge/Views/BridgeView/BridgeView.view.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { renderScreenWithRoutes } from '../../../../../../tests/component-view/r
99
import Routes from '../../../../../constants/navigation/Routes';
1010
import { initialStateBridge } from '../../../../../../tests/component-view/presets/bridge';
1111
import BridgeView from './index';
12-
import { describeForPlatforms } from '../../../../../util/test/platform';
12+
import { describeForPlatforms } from '../../../../../../tests/component-view/platform';
1313
import { BridgeViewSelectorsIDs } from './BridgeView.testIds';
1414
import { BuildQuoteSelectors } from '../../../Ramp/Aggregator/Views/BuildQuote/BuildQuote.testIds';
1515
import { CommonSelectorsIDs } from '../../../../../util/Common.testIds';

app/components/UI/Earn/Views/EarnMusdConversionEducationView/EarnMusdConversionEducationView.view.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import '../../../../../../tests/component-view/mocks';
22
import { renderScreenWithRoutes } from '../../../../../../tests/component-view/render';
33
import { initialStateWallet } from '../../../../../../tests/component-view/presets/wallet';
4-
import { describeForPlatforms } from '../../../../../util/test/platform';
4+
import { describeForPlatforms } from '../../../../../../tests/component-view/platform';
55
import React from 'react';
66
import EarnMusdConversionEducationView from './index';
77
import { strings } from '../../../../../../locales/i18n';

app/components/UI/Earn/components/Musd/MusdConversionAssetListCta/MusdConversionAssetListCta.view.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import '../../../../../../../tests/component-view/mocks';
22
import { renderComponentViewScreen } from '../../../../../../../tests/component-view/render';
33
import { initialStateWallet } from '../../../../../../../tests/component-view/presets/wallet';
4-
import { describeForPlatforms } from '../../../../../../util/test/platform';
4+
import { describeForPlatforms } from '../../../../../../../tests/component-view/platform';
55
import React from 'react';
66
import { View } from 'react-native';
77
import MusdConversionAssetListCta from './index';

app/components/UI/Earn/components/Musd/MusdConversionAssetOverviewCta/MusdConversionAssetOverviewCta.view.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import '../../../../../../../tests/component-view/mocks';
22
import { renderComponentViewScreen } from '../../../../../../../tests/component-view/render';
33
import { initialStateWallet } from '../../../../../../../tests/component-view/presets/wallet';
4-
import { describeForPlatforms } from '../../../../../../util/test/platform';
4+
import { describeForPlatforms } from '../../../../../../../tests/component-view/platform';
55
import React from 'react';
66
import { View } from 'react-native';
77
import MusdConversionAssetOverviewCta from './index';

app/components/Views/AssetDetails/AssetDetails.view.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import '../../../../tests/component-view/mocks';
22
import { renderAssetDetailsView } from '../../../../tests/component-view/renderers/assetDetails';
3-
import { describeForPlatforms } from '../../../util/test/platform';
3+
import { describeForPlatforms } from '../../../../tests/component-view/platform';
44

55
// addresses Regression: #25100 – Token Details page shows wrong network
66

app/components/Views/TrendingView/TrendingView.view.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import '../../../../tests/component-view/mocks';
2-
import { describeForPlatforms } from '../../../util/test/platform';
2+
import { describeForPlatforms } from '../../../../tests/component-view/platform';
33
import { renderTrendingViewWithRoutes } from '../../../../tests/component-view/renderers/trending';
44
import { TrendingViewSelectorsIDs } from './TrendingView.testIds';
55
import {

app/components/Views/Wallet/Wallet.view.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
renderWalletViewWithRoutes,
55
} from '../../../../tests/component-view/renderers/wallet';
66
import { WalletViewSelectorsIDs } from './WalletView.testIds';
7-
import { describeForPlatforms } from '../../../util/test/platform';
7+
import { describeForPlatforms } from '../../../../tests/component-view/platform';
88
import { fireEvent } from '@testing-library/react-native';
99
import Routes from '../../../constants/navigation/Routes';
1010

app/components/Views/WalletActions/WalletActions.view.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import '../../../../tests/component-view/mocks';
22
import { renderWalletActionsView } from '../../../../tests/component-view/renderers/walletActions';
33
import { WalletActionsBottomSheetSelectorsIDs } from './WalletActionsBottomSheet.testIds';
4-
import { describeForPlatforms } from '../../../util/test/platform';
4+
import { describeForPlatforms } from '../../../../tests/component-view/platform';
55

66
// Regression: #24972 – Perps missing from Trade menu when non-EVM network selected
77
describeForPlatforms('WalletActions', () => {

0 commit comments

Comments
 (0)