Skip to content

Commit 8b2a848

Browse files
test: use performance fixture in mm-connect tests (#26604)
## **Description** The mm-connect tests (EVM, Wagmi, Multichain) were importing `test` directly from `appwright`, bypassing the shared performance fixture used by all other tests under `tests/performance/`. This meant they had no performance tracking, metric attachment, quality gate validation, or session data capture. This PR: 1. Switches the import in all three mm-connect test files from `appwright` to `../../framework/fixtures/performance`, aligning them with the rest of the performance test suite 2. Adds `TimerHelper` performance measurements to capture timing data for key user-facing flows — connection, signing, chain switching, browser refresh reconnection, and post-disconnect reconnection ### Timers Added **connection-multichain.spec.js** (1 timer): | Timer | Threshold (iOS / Android) | |---|---| | Connect → Multichain connected state | 20s / 30s | **connection-evm.spec.js** (5 timers): | Timer | Threshold (iOS / Android) | |---|---| | Connect (Legacy) → EVM connected state | 20s / 30s | | Personal Sign → signature response displayed | 12s / 18s | | Switch to Polygon → chain ID 0x89 confirmed | 12s / 18s | | Browser refresh → still connected | 8s / 12s | | Reconnect after disconnect → connected confirmed | 20s / 30s | **connection-wagmi.spec.js** (5 timers): | Timer | Threshold (iOS / Android) | |---|---| | Connect (Wagmi) → Wagmi connected state | 20s / 30s | | Wagmi Sign Message → signature result displayed | 12s / 18s | | Switch to OP Mainnet → chain ID 10 confirmed | 12s / 18s | | Browser refresh → Wagmi still connected | 8s / 12s | | Reconnect after disconnect → connected confirmed | 20s / 30s | Thresholds are intentionally generous (no baseline data yet). The 10% margin is added automatically by `TimerHelper`. ## **Related issues** [MMQA-1517](https://consensyssoftware.atlassian.net/browse/MMQA-1517) ## **Manual testing steps** ```gherkin Feature: mm-connect performance fixture integration Scenario: user runs mm-connect EVM test Given the mm-connect EVM test suite is configured When user runs the connection-evm.spec.js test Then the test executes successfully with the performance fixture And performance metrics are attached to the test report And 5 timers are recorded: connect, sign, switch chain, refresh reconnect, reconnect Scenario: user runs mm-connect Wagmi test Given the mm-connect Wagmi test suite is configured When user runs the connection-wagmi.spec.js test Then the test executes successfully with the performance fixture And performance metrics are attached to the test report And 5 timers are recorded: connect, sign, switch chain, refresh reconnect, reconnect Scenario: user runs mm-connect Multichain test Given the mm-connect Multichain test suite is configured When user runs the connection-multichain.spec.js test Then the test executes successfully with the performance fixture And performance metrics are attached to the test report And 1 timer is recorded: connect ``` ## **Screenshots/Recordings** browserstack test [run](https://app-automate.browserstack.com/dashboard/v2/public-build/TDVTSjZHQk56UE9qZnN0WnZMaWM1b1NnVmpXOHpxRmFoZXI1NGpaWUF6S3c1UnVpYWh3SFp4dVZzWTFqdWxDL216K0xLWXlUUEIzWjJqUzZ6bXdsRkE9PS0tbkNreVRNaGswN0dxaE5ueU1KWlpoZz09--7ed9ade707feff3fee54734f86f3d746ff20f0e7) ## **Changelog** CHANGELOG entry: null ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed) - [x] I confirm that this PR addresses all acceptance criteria described in the linked issue and target all platforms that should be supported [MMQA-1517]: https://consensyssoftware.atlassian.net/browse/MMQA-1517?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches only performance test code, but introduces thresholded `TimerHelper` measurements and quality-gated tracking that could make mm-connect perf runs fail/flaky if timings regress or the timers are mis-scoped. > > **Overview** > Switches the three `mm-connect` performance specs (EVM legacy, Wagmi, Multichain) to use the shared `../../framework/fixtures/performance` test fixture so runs now capture/attach performance metrics and session artifacts. > > Adds `TimerHelper` instrumentation around key user flows and registers these timers via `performanceTracker.addTimers(...)` (connect, sign, chain switch, refresh reconnection, and post-disconnect reconnection; Multichain adds connect-only), with platform-specific thresholds for iOS/Android. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7c9d4ee. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 269782c commit 8b2a848

3 files changed

Lines changed: 107 additions & 3 deletions

File tree

tests/performance/mm-connect/connection-evm.spec.js

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { test } from 'appwright';
1+
import { test } from '../../framework/fixtures/performance';
2+
import TimerHelper from '../../framework/TimerHelper';
23

34
import { login } from '../../framework/utils/Flows.js';
45
import {
@@ -58,6 +59,7 @@ test.afterAll(async () => {
5859

5960
test('@metamask/connect-evm - Connect via EVM Legacy Connection to Local Browser Playground', async ({
6061
device,
62+
performanceTracker,
6163
}) => {
6264
const platform = device.getPlatform?.() || 'android';
6365
const useBrowserStackLocal =
@@ -80,6 +82,32 @@ test('@metamask/connect-evm - Connect via EVM Legacy Connection to Local Browser
8082
shouldWaitForQuiescence: false,
8183
});
8284

85+
const connectTimer = new TimerHelper(
86+
'Time from tapping Connect (Legacy) to dapp confirming EVM connected state',
87+
{ ios: 20000, android: 30000 },
88+
device,
89+
);
90+
const signTimer = new TimerHelper(
91+
'Time from tapping Personal Sign to dapp displaying signature response',
92+
{ ios: 12000, android: 18000 },
93+
device,
94+
);
95+
const switchChainTimer = new TimerHelper(
96+
'Time from tapping Switch to Polygon to dapp confirming chain ID 0x89',
97+
{ ios: 12000, android: 18000 },
98+
device,
99+
);
100+
const refreshReconnectTimer = new TimerHelper(
101+
'Time from refreshing browser to dapp confirming EVM still connected',
102+
{ ios: 8000, android: 12000 },
103+
device,
104+
);
105+
const reconnectTimer = new TimerHelper(
106+
'Time from tapping Connect (Legacy) after disconnect to dapp confirming reconnected',
107+
{ ios: 20000, android: 30000 },
108+
device,
109+
);
110+
83111
await AppwrightHelpers.withNativeAction(device, async () => {
84112
await login(device);
85113
await launchMobileBrowser(device);
@@ -90,6 +118,7 @@ test('@metamask/connect-evm - Connect via EVM Legacy Connection to Local Browser
90118
await AppwrightHelpers.withWebAction(
91119
device,
92120
async () => {
121+
connectTimer.start();
93122
await BrowserPlaygroundDapp.tapConnectLegacy();
94123
},
95124
DAPP_URL,
@@ -112,8 +141,10 @@ test('@metamask/connect-evm - Connect via EVM Legacy Connection to Local Browser
112141
device,
113142
async () => {
114143
await BrowserPlaygroundDapp.assertConnected(true);
144+
connectTimer.stop();
115145
await BrowserPlaygroundDapp.assertChainIdValue('0x1');
116146
await BrowserPlaygroundDapp.assertActiveAccount(ACCOUNT_1_ADDRESS);
147+
signTimer.start();
117148
await BrowserPlaygroundDapp.tapPersonalSign();
118149
},
119150
DAPP_URL,
@@ -135,6 +166,7 @@ test('@metamask/connect-evm - Connect via EVM Legacy Connection to Local Browser
135166
// Account 1 signed the message
136167
'0x361c13288b4ab02d50974efddf9e4e7ca651b81c298b614be908c4754abb1dd8328224645a1a8d0fab561c4b855c7bdcebea15db5ae8d1778a1ea791dbd05c2a1b',
137168
);
169+
signTimer.stop();
138170
await BrowserPlaygroundDapp.tapSendTransaction();
139171
},
140172
DAPP_URL,
@@ -155,6 +187,7 @@ test('@metamask/connect-evm - Connect via EVM Legacy Connection to Local Browser
155187
async () => {
156188
// Note: Error message may differ slightly in browser playground
157189
await BrowserPlaygroundDapp.assertResponseValue('denied');
190+
switchChainTimer.start();
158191
await BrowserPlaygroundDapp.tapSwitchToPolygon();
159192
},
160193
DAPP_URL,
@@ -174,6 +207,7 @@ test('@metamask/connect-evm - Connect via EVM Legacy Connection to Local Browser
174207
device,
175208
async () => {
176209
await BrowserPlaygroundDapp.assertChainIdValue('0x89');
210+
switchChainTimer.stop();
177211
await BrowserPlaygroundDapp.tapSendTransaction();
178212
},
179213
DAPP_URL,
@@ -227,6 +261,7 @@ test('@metamask/connect-evm - Connect via EVM Legacy Connection to Local Browser
227261
);
228262

229263
await AppwrightHelpers.withNativeAction(device, async () => {
264+
refreshReconnectTimer.start();
230265
await refreshMobileBrowser(device);
231266
});
232267
await new Promise((resolve) => setTimeout(resolve, 2000));
@@ -235,6 +270,7 @@ test('@metamask/connect-evm - Connect via EVM Legacy Connection to Local Browser
235270
device,
236271
async () => {
237272
await BrowserPlaygroundDapp.assertConnected(true);
273+
refreshReconnectTimer.stop();
238274
await BrowserPlaygroundDapp.assertChainIdValue('0x1');
239275
await BrowserPlaygroundDapp.assertActiveAccount(ACCOUNT_3_ADDRESS);
240276
await BrowserPlaygroundDapp.tapPersonalSign();
@@ -264,6 +300,7 @@ test('@metamask/connect-evm - Connect via EVM Legacy Connection to Local Browser
264300
async () => {
265301
await BrowserPlaygroundDapp.tapDisconnect();
266302
await BrowserPlaygroundDapp.assertConnected(false);
303+
reconnectTimer.start();
267304
await BrowserPlaygroundDapp.tapConnectLegacy();
268305
},
269306
DAPP_URL,
@@ -282,6 +319,7 @@ test('@metamask/connect-evm - Connect via EVM Legacy Connection to Local Browser
282319
device,
283320
async () => {
284321
await BrowserPlaygroundDapp.assertConnected(true);
322+
reconnectTimer.stop();
285323
await BrowserPlaygroundDapp.assertChainIdValue('0x1');
286324
await BrowserPlaygroundDapp.assertActiveAccount(ACCOUNT_3_ADDRESS);
287325
await BrowserPlaygroundDapp.tapPersonalSign();
@@ -366,6 +404,14 @@ test('@metamask/connect-evm - Connect via EVM Legacy Connection to Local Browser
366404
DAPP_URL,
367405
);
368406

407+
performanceTracker.addTimers(
408+
connectTimer,
409+
signTimer,
410+
switchChainTimer,
411+
refreshReconnectTimer,
412+
reconnectTimer,
413+
);
414+
369415
//
370416
// Read-only method should hit rpc endpoint instead of wallet
371417
//

tests/performance/mm-connect/connection-multichain.spec.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { test } from 'appwright';
1+
import { test } from '../../framework/fixtures/performance';
2+
import TimerHelper from '../../framework/TimerHelper';
23

34
import { login } from '../../framework/utils/Flows.js';
45
import {
@@ -49,6 +50,7 @@ test.afterAll(async () => {
4950

5051
test('@metamask/connect-multichain - Connect via Multichain API to Local Browser Playground', async ({
5152
device,
53+
performanceTracker,
5254
}) => {
5355
// Get platform-specific URL (use bs-local.com when running on BrowserStack Local tunnel)
5456
const platform = device.getPlatform?.() || 'android';
@@ -85,10 +87,17 @@ test('@metamask/connect-multichain - Connect via Multichain API to Local Browser
8587
// Connect via Multichain API (wait for dapp ready then tap Connect to minimize idle time / auto-lock)
8688
//
8789

90+
const connectTimer = new TimerHelper(
91+
'Time from tapping Connect to dapp confirming Multichain connected state',
92+
{ ios: 20000, android: 30000 },
93+
device,
94+
);
95+
8896
await AppwrightHelpers.withWebAction(
8997
device,
9098
async () => {
9199
await BrowserPlaygroundDapp.waitForConnectButtonVisible(15000);
100+
connectTimer.start();
92101
await BrowserPlaygroundDapp.tapConnect();
93102
},
94103
DAPP_URL,
@@ -114,13 +123,16 @@ test('@metamask/connect-multichain - Connect via Multichain API to Local Browser
114123
async () => {
115124
// Verify connected by checking for scope cards section
116125
await BrowserPlaygroundDapp.assertMultichainConnected(true);
126+
connectTimer.stop();
117127

118128
// Verify at least one scope card is visible (eip155:1 is default)
119129
await BrowserPlaygroundDapp.assertScopeCardVisible('eip155:1');
120130
},
121131
DAPP_URL,
122132
);
123133

134+
performanceTracker.addTimers(connectTimer);
135+
124136
//
125137
// Cleanup - disconnect
126138
//

tests/performance/mm-connect/connection-wagmi.spec.js

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { test } from 'appwright';
1+
import { test } from '../../framework/fixtures/performance';
2+
import TimerHelper from '../../framework/TimerHelper';
23

34
import { login } from '../../framework/utils/Flows.js';
45
import {
@@ -58,6 +59,7 @@ test.afterAll(async () => {
5859

5960
test('@metamask/connect-wagmi - Connect via Wagmi to Local Browser Playground', async ({
6061
device,
62+
performanceTracker,
6163
}) => {
6264
const platform = device.getPlatform?.() || 'android';
6365
const useBrowserStackLocal =
@@ -82,6 +84,32 @@ test('@metamask/connect-wagmi - Connect via Wagmi to Local Browser Playground',
8284
shouldWaitForQuiescence: false,
8385
});
8486

87+
const connectTimer = new TimerHelper(
88+
'Time from tapping Connect (Wagmi) to dapp confirming Wagmi connected state',
89+
{ ios: 20000, android: 30000 },
90+
device,
91+
);
92+
const signTimer = new TimerHelper(
93+
'Time from tapping Wagmi Sign Message to dapp displaying signature result',
94+
{ ios: 12000, android: 18000 },
95+
device,
96+
);
97+
const switchChainTimer = new TimerHelper(
98+
'Time from tapping Switch Chain to OP Mainnet to dapp confirming chain ID 10',
99+
{ ios: 12000, android: 18000 },
100+
device,
101+
);
102+
const refreshReconnectTimer = new TimerHelper(
103+
'Time from refreshing browser to dapp confirming Wagmi still connected',
104+
{ ios: 8000, android: 12000 },
105+
device,
106+
);
107+
const reconnectTimer = new TimerHelper(
108+
'Time from tapping Connect (Wagmi) after disconnect to dapp confirming reconnected',
109+
{ ios: 20000, android: 30000 },
110+
device,
111+
);
112+
85113
//
86114
// Login and navigate to dapp
87115
//
@@ -101,6 +129,7 @@ test('@metamask/connect-wagmi - Connect via Wagmi to Local Browser Playground',
101129
await AppwrightHelpers.withWebAction(
102130
device,
103131
async () => {
132+
connectTimer.start();
104133
await BrowserPlaygroundDapp.tapConnectWagmi();
105134
},
106135
DAPP_URL,
@@ -134,10 +163,12 @@ test('@metamask/connect-wagmi - Connect via Wagmi to Local Browser Playground',
134163
device,
135164
async () => {
136165
await BrowserPlaygroundDapp.assertWagmiConnected(true);
166+
connectTimer.stop();
137167
await BrowserPlaygroundDapp.assertWagmiChainIdValue('1');
138168
await BrowserPlaygroundDapp.assertWagmiActiveAccount(ACCOUNT_1_ADDRESS);
139169
// Type a message and sign
140170
await BrowserPlaygroundDapp.typeWagmiSignMessage('Hello MetaMask');
171+
signTimer.start();
141172
await BrowserPlaygroundDapp.tapWagmiSignMessage();
142173
},
143174
DAPP_URL,
@@ -160,6 +191,7 @@ test('@metamask/connect-wagmi - Connect via Wagmi to Local Browser Playground',
160191
async () => {
161192
// Verify we got a signature
162193
await BrowserPlaygroundDapp.assertWagmiSignatureResult('0x');
194+
signTimer.stop();
163195
// Switch to Sepolia
164196
await BrowserPlaygroundDapp.tapWagmiSwitchChain(11155111);
165197
await BrowserPlaygroundDapp.assertWagmiChainIdValue('11155111');
@@ -188,6 +220,7 @@ test('@metamask/connect-wagmi - Connect via Wagmi to Local Browser Playground',
188220
await AppwrightHelpers.withWebAction(
189221
device,
190222
async () => {
223+
switchChainTimer.start();
191224
await BrowserPlaygroundDapp.tapWagmiSwitchChain(10); // OP Mainnet
192225
},
193226
DAPP_URL,
@@ -207,6 +240,7 @@ test('@metamask/connect-wagmi - Connect via Wagmi to Local Browser Playground',
207240
device,
208241
async () => {
209242
await BrowserPlaygroundDapp.assertWagmiChainIdValue('10');
243+
switchChainTimer.stop();
210244
await BrowserPlaygroundDapp.typeWagmiSignMessage('Hello OP');
211245
await BrowserPlaygroundDapp.tapWagmiSignMessage();
212246
},
@@ -281,6 +315,7 @@ test('@metamask/connect-wagmi - Connect via Wagmi to Local Browser Playground',
281315
//
282316

283317
await AppwrightHelpers.withNativeAction(device, async () => {
318+
refreshReconnectTimer.start();
284319
await refreshMobileBrowser(device);
285320
});
286321
await new Promise((resolve) => setTimeout(resolve, 2000));
@@ -289,6 +324,7 @@ test('@metamask/connect-wagmi - Connect via Wagmi to Local Browser Playground',
289324
device,
290325
async () => {
291326
await BrowserPlaygroundDapp.assertWagmiConnected(true);
327+
refreshReconnectTimer.stop();
292328
// Note: Chain may reset to 1 after refresh
293329
await BrowserPlaygroundDapp.assertWagmiChainIdValue('1');
294330
await BrowserPlaygroundDapp.assertWagmiActiveAccount(ACCOUNT_3_ADDRESS);
@@ -316,6 +352,7 @@ test('@metamask/connect-wagmi - Connect via Wagmi to Local Browser Playground',
316352
async () => {
317353
await BrowserPlaygroundDapp.tapDisconnect();
318354
await BrowserPlaygroundDapp.assertWagmiConnected(false);
355+
reconnectTimer.start();
319356
await BrowserPlaygroundDapp.tapConnectWagmi();
320357
},
321358
DAPP_URL,
@@ -334,6 +371,7 @@ test('@metamask/connect-wagmi - Connect via Wagmi to Local Browser Playground',
334371
device,
335372
async () => {
336373
await BrowserPlaygroundDapp.assertWagmiConnected(true);
374+
reconnectTimer.stop();
337375
await BrowserPlaygroundDapp.assertWagmiChainIdValue('1');
338376
await BrowserPlaygroundDapp.assertWagmiActiveAccount(ACCOUNT_3_ADDRESS);
339377
},
@@ -398,6 +436,14 @@ test('@metamask/connect-wagmi - Connect via Wagmi to Local Browser Playground',
398436
DAPP_URL,
399437
);
400438

439+
performanceTracker.addTimers(
440+
connectTimer,
441+
signTimer,
442+
switchChainTimer,
443+
refreshReconnectTimer,
444+
reconnectTimer,
445+
);
446+
401447
//
402448
// Reset dapp state
403449
//

0 commit comments

Comments
 (0)