Skip to content

Commit f7de05a

Browse files
authored
test: remove toMatchSnapshot and removed snapshot files in mobile platform tests (#29207)
<!-- 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** > Removes `toMatchSnapshot()` usage from `MainNavigator`, `Main`, `Root`, and `RewardsController` tests, replacing snapshots with simpler smoke assertions (`toBeTruthy()`) or explicit `toEqual(...)` state expectations. > > Deletes the now-unused snapshot files under `app/components/Nav/Main/__snapshots__`, `app/components/Views/Root/__snapshots__`, and `app/core/Engine/controllers/rewards-controller/__snapshots__`. ## **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 because changes are limited to test assertions and removal of snapshot files; no production code paths are modified. > > **Overview** > Removes Jest snapshot-based coverage for `MainNavigator`, `Main`, `Root`, and `RewardsController` tests, replacing it with more focused assertions (e.g., tab bar returns `null` vs rendered, presence of key navigation screens/components, and explicit `deriveStateFromMetadata` `toEqual` expectations). > > Deletes the corresponding snapshot files under `app/components/Nav/Main/__snapshots__`, `app/components/Views/Root/__snapshots__`, and `app/core/Engine/controllers/rewards-controller/__snapshots__`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 245bd20. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent b6c87e7 commit f7de05a

8 files changed

Lines changed: 130 additions & 1515 deletions

File tree

app/components/Nav/Main/MainNavigator.test.tsx

Lines changed: 57 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -72,93 +72,79 @@ describe('MainNavigator', () => {
7272
process.env.METAMASK_ENVIRONMENT = originalEnv;
7373
});
7474

75-
it('matches rendered snapshot', () => {
76-
// Given the initial app state
77-
// When rendering the MainNavigator
78-
const { toJSON } = renderWithProvider(<MainNavigator />, {
79-
state: initialRootState,
80-
});
75+
describe('Tab Bar Visibility', () => {
76+
const getHomeTabsComponent = (): React.ComponentType<
77+
Record<string, unknown>
78+
> => {
79+
const { root: mainRoot } = renderWithProvider(<MainNavigator />, {
80+
state: initialRootState,
81+
});
82+
const homeScreen = mainRoot.findAll(
83+
(node: ReactTestInstance) =>
84+
node.type?.toString?.() === 'Screen' && node.props?.name === 'Home',
85+
)[0];
86+
return homeScreen?.props?.component;
87+
};
8188

82-
// Then it should match the expected navigation structure
83-
expect(toJSON()).toMatchSnapshot();
84-
});
89+
const getTabBarFn = (
90+
HomeTabsComponent: React.ComponentType<Record<string, unknown>>,
91+
) => {
92+
const { root: homeRoot } = renderWithProvider(
93+
<HomeTabsComponent route={{ params: {} }} />,
94+
{ state: initialRootState },
95+
);
96+
const tabNavigatorNode = homeRoot.findAll(
97+
(node: ReactTestInstance) => node.type?.toString?.() === 'TabNavigator',
98+
)[0];
99+
return tabNavigatorNode?.props?.tabBar as (args: {
100+
state: {
101+
routes: { name: string; state?: unknown }[];
102+
index: number;
103+
};
104+
descriptors: Record<string, unknown>;
105+
navigation: Record<string, unknown>;
106+
}) => React.ReactNode;
107+
};
85108

86-
describe('Tab Bar Visibility', () => {
87109
it('hides tab bar when browser is active', () => {
88-
// Given a state where browser is the active route
89-
const stateWithBrowserActive = {
90-
...initialRootState,
91-
browser: {
92-
...initialRootState.browser,
93-
activeTab: 0,
94-
tabs: [{ url: 'https://example.com', id: 0 }],
110+
// Given HomeTabs is rendered and the active route is the browser
111+
const HomeTabs = getHomeTabsComponent();
112+
const renderTabBar = getTabBarFn(HomeTabs);
113+
114+
// When renderTabBar is called with a browser route as the active tab
115+
const result = renderTabBar({
116+
state: {
117+
routes: [{ name: Routes.BROWSER.HOME }],
118+
index: 0,
95119
},
96-
};
97-
98-
// When rendering the MainNavigator
99-
const { toJSON } = renderWithProvider(<MainNavigator />, {
100-
state: stateWithBrowserActive,
120+
descriptors: {},
121+
navigation: {},
101122
});
102123

103-
// Then the tab bar should be hidden (returns null in renderTabBar)
104-
expect(toJSON()).toMatchSnapshot();
124+
// Then the tab bar should be hidden
125+
expect(result).toBeNull();
105126
});
106127

107128
it('shows tab bar when not in browser', () => {
108-
// Given a state where wallet is the active route
109-
const stateWithWalletActive = {
110-
...initialRootState,
111-
browser: {
112-
...initialRootState.browser,
113-
activeTab: null,
114-
tabs: [],
129+
// Given HomeTabs is rendered and the active route is the wallet
130+
const HomeTabs = getHomeTabsComponent();
131+
const renderTabBar = getTabBarFn(HomeTabs);
132+
133+
// When renderTabBar is called with a non-browser route as the active tab
134+
const result = renderTabBar({
135+
state: {
136+
routes: [{ name: Routes.WALLET.HOME }],
137+
index: 0,
115138
},
116-
};
117-
118-
// When rendering the MainNavigator
119-
const { toJSON } = renderWithProvider(<MainNavigator />, {
120-
state: stateWithWalletActive,
139+
descriptors: {},
140+
navigation: {},
121141
});
122142

123143
// Then the tab bar should be visible
124-
expect(toJSON()).toMatchSnapshot();
144+
expect(result).not.toBeNull();
125145
});
126146

127147
describe('Rewards sub-page tab bar visibility', () => {
128-
const getHomeTabsComponent = (): React.ComponentType<
129-
Record<string, unknown>
130-
> => {
131-
const { root: mainRoot } = renderWithProvider(<MainNavigator />, {
132-
state: initialRootState,
133-
});
134-
const homeScreen = mainRoot.findAll(
135-
(node: ReactTestInstance) =>
136-
node.type?.toString?.() === 'Screen' && node.props?.name === 'Home',
137-
)[0];
138-
return homeScreen?.props?.component;
139-
};
140-
141-
const getTabBarFn = (
142-
HomeTabsComponent: React.ComponentType<Record<string, unknown>>,
143-
) => {
144-
const { root: homeRoot } = renderWithProvider(
145-
<HomeTabsComponent route={{ params: {} }} />,
146-
{ state: initialRootState },
147-
);
148-
const tabNavigatorNode = homeRoot.findAll(
149-
(node: ReactTestInstance) =>
150-
node.type?.toString?.() === 'TabNavigator',
151-
)[0];
152-
return tabNavigatorNode?.props?.tabBar as (args: {
153-
state: {
154-
routes: { name: string; state?: unknown }[];
155-
index: number;
156-
};
157-
descriptors: Record<string, unknown>;
158-
navigation: Record<string, unknown>;
159-
}) => React.ReactNode;
160-
};
161-
162148
// rewardsViewRoute is found via .find(r => r.name === Routes.REWARDS_VIEW),
163149
// so the inner route that wraps the nested nav state must carry that name.
164150
const buildRewardsState = (activeRouteName: string | undefined) => ({

0 commit comments

Comments
 (0)