Skip to content

feat: Add E2E test for storage operations failure recovery#39317

Merged
itsyoboieltr merged 12 commits intomainfrom
feat_storage_operations_recovery_e2e_test
Jan 22, 2026
Merged

feat: Add E2E test for storage operations failure recovery#39317
itsyoboieltr merged 12 commits intomainfrom
feat_storage_operations_recovery_e2e_test

Conversation

@gauthierpetetin
Copy link
Copy Markdown
Contributor

@gauthierpetetin gauthierpetetin commented Jan 16, 2026

Description

This PR is a follow-up PR for #39010
It adds E2E tests

Open in GitHub Codespaces

Changelog

CHANGELOG entry: null

Related issues

Fixes: #10091

Manual testing steps

  1. yarn build:test
  2. IS_SIDEPANEL=true yarn test:e2e:single test/e2e/tests/vault-corruption/storage-operations-failure.spec.ts --browser=chrome

Screenshots/Recordings

NA

Pre-merge author checklist

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.

Note

Adds targeted E2E tests to validate recovery behavior when browser.storage.local operations fail, plus supporting test hooks and small UI/test utilities.

  • New tests: storage-operations-failure.spec.ts verifies vault recovery on simulated get() failure and storage error toast on simulated set() failure; refactors vault-corruption.spec.ts to reuse shared flows
  • Test flags: Adds testing.simulateStorageGetFailure and testing.simulateStorageSetFailure in manifestFlags.ts
  • PersistenceManager test hooks: Wraps reads/writes via #getFromLocalStore, #setInLocalStore, #setKeyValuesInLocalStore with optional failure simulation; integrates into get, set, and persist
  • Page objects/flows: Adds VaultRecoveryPage, shared vault-corruption.flow.ts, and helpers; updates CriticalErrorPage visibility for reuse
  • UI: Adds data-testid="storage-error-toast" to the storage error toast and page object methods to assert and act on it

Written by Cursor Bugbot for commit 69d22bb. This will update automatically on new commits. Configure here.

@github-actions
Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.


return accountAddress;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are all moved to helpers.ts file

getConfig(this.test?.title),
async ({ driver }: { driver: Driver }) => {
const initialFirstAddress = await onboardThenCorruptVault(
const initialFirstAddress = await onboardThenTriggerCorruption(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onboardThenCorruptVault has just been renamed into onboardThenTriggerCorruption to have a more generic name that's more compatible with new E2E test scenarios we're adding in this PR (we're not specifically corrupting the vault, we're corrupting/breaking the database).

@metamaskbotv2
Copy link
Copy Markdown
Contributor

metamaskbotv2 bot commented Jan 16, 2026

Builds ready [d098277]
UI Startup Metrics (1286 ± 113 ms)
PlatformBuildTypePageMetricTest Title (ms)Persona (ms)Mean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--12861033167311313491509
load--1078876140410311421294
domContentLoaded--1071866138410211371288
domInteractive--261589192381
firstPaint--166651137121196317
backgroundConnect--21419224912218242
firstReactRender--16103051828
getState--371995144569
initialActions--105113
loadScripts--86666811581039281082
setupStore--1373451524
numNetworkReqs--171170161167
19--------
BrowserifyPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--18541408244520619962307
load--1004895164612610271300
domContentLoaded--992886163412610051290
domInteractive--33161872731105
firstPaint--195701458185220285
backgroundConnect--269201670124233612
firstReactRender--21164342329
getState--17613268959190224
initialActions--102112
loadScripts--78468013661217901085
setupStore--18106291841
numNetworkReqs--61362213258139
19--------
WebpackStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--8597051175949111034
load--68959898788741881
domContentLoaded--68359497787735871
domInteractive--2716138212384
firstPaint--1216236067155235
backgroundConnect--2561372932105
firstReactRender--19128792030
getState--3715144204968
initialActions--104112
loadScripts--68059197286729862
setupStore--1474771626
numNetworkReqs--181180181171
19--------
WebpackPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--1349954257630515511924
load--6535681132101652867
domContentLoaded--6445631125101644860
domInteractive--34161442636105
firstPaint--1365743475165330
backgroundConnect--977100719818560
firstReactRender--22173642430
getState--15814023216163192
initialActions--105111
loadScripts--6415611116100642850
setupStore--1594881543
numNetworkReqs--943825651133228
19--------
FirefoxBrowserifyStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--13841103247118714691721
load--109792813789911531286
domContentLoaded--109692813789911531286
domInteractive--803522142111149
firstPaint--------
backgroundConnect--61222624872171
firstReactRender--1393441322
getState--145148221130
initialActions--103122
loadScripts--106191013608311181231
setupStore--144166211140
numNetworkReqs--20991211478
19--------
BrowserifyPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--23581721494949523963709
load--1209966245529011601838
domContentLoaded--1209966245429011591837
domInteractive--1164046291110392
firstPaint--------
backgroundConnect--11225959153105276
firstReactRender--22157572330
getState--23828830211327709
initialActions--2142423
loadScripts--1160947232424511261544
setupStore--14613694184171620
numNetworkReqs--60301664083162
19--------
WebpackStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--17151342319432218772463
load--14151121287624314881875
domContentLoaded--14151120287624314881875
domInteractive--912881587121180
firstPaint--------
backgroundConnect--792330561125228
firstReactRender--16117071826
getState--2482243518135
initialActions--104122
loadScripts--13651104272122014351777
setupStore--184187261660
numNetworkReqs--20986201477
19--------
WebpackPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--29492072788694133274670
load--16621087490263017502986
domContentLoaded--16621084490263017492986
domInteractive--141301169197112557
firstPaint--------
backgroundConnect--1782015592611721090
firstReactRender--22163952632
getState--321661214273544858
initialActions--217123
loadScripts--15551070488156216052802
setupStore--106774015692518
numNetworkReqs--60311673978159
19--------
📊 Page Load Benchmark Results

Current Commit: d098277 | Date: 1/16/2026

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.04s (±41ms) 🟡 | historical mean value: 1.04s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 725ms (±38ms) 🟢 | historical mean value: 727ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 77ms (±12ms) 🟢 | historical mean value: 77ms ⬆️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.04s 41ms 1.01s 1.35s 1.08s 1.35s
domContentLoaded 725ms 38ms 702ms 1.01s 749ms 1.01s
firstPaint 77ms 12ms 60ms 180ms 88ms 180ms
firstContentfulPaint 77ms 12ms 60ms 180ms 88ms 180ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 58 Bytes (0%)
  • ui: 33 Bytes (0%)
  • common: 231 Bytes (0%)

@metamaskbotv2
Copy link
Copy Markdown
Contributor

metamaskbotv2 bot commented Jan 16, 2026

Builds ready [801f437]
UI Startup Metrics (1255 ± 99 ms)
PlatformBuildTypePageMetricTest Title (ms)Persona (ms)Mean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--1255101516499913071425
load--104386013879210971182
domContentLoaded--103785813829210931168
domInteractive--2515101202190
firstPaint--151651091171165312
backgroundConnect--21219525412217234
firstReactRender--1593541624
getState--3917148204283
initialActions--103112
loadScripts--832657116391886966
setupStore--1272741420
numNetworkReqs--171179171167
19--------
BrowserifyPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--18491394243618719732274
load--1014886159612610201322
domContentLoaded--1002874158712610071312
domInteractive--34161432731116
firstPaint--206681333200229438
backgroundConnect--270203645123231615
firstReactRender--22165472341
getState--16913026528188219
initialActions--102011
loadScripts--79366613731257921108
setupStore--1774661831
numNetworkReqs--59372152960132
19--------
WebpackStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--796654112985830987
load--65057292975702801
domContentLoaded--64456892374697797
domInteractive--241590172176
firstPaint--1155971380141227
backgroundConnect--3151413247124
firstReactRender--16115671733
getState--321471144360
initialActions--102111
loadScripts--64156692173695789
setupStore--1163861221
numNetworkReqs--171173171171
19--------
WebpackPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--1378948199025815511901
load--680589112494686911
domContentLoaded--670582111895674904
domInteractive--35161532833112
firstPaint--1426143079191290
backgroundConnect--93668918120578
firstReactRender--22173432428
getState--14812721516155174
initialActions--102111
loadScripts--667579110993671896
setupStore--1664871737
numNetworkReqs--1053831151137228
19--------
FirefoxBrowserifyStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--13431098195417414151752
load--1071937164711611261246
domContentLoaded--1070936164711611251246
domInteractive--70332013990145
firstPaint--------
backgroundConnect--46162223749153
firstReactRender--1394051325
getState--156161211269
initialActions--103122
loadScripts--1046921162310910931211
setupStore--166145201546
numNetworkReqs--20990201577
19--------
BrowserifyPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--26051990592175524884573
load--13001013292944012302645
domContentLoaded--13001013292944012302644
domInteractive--12235695102111386
firstPaint--------
backgroundConnect--142271585234119477
firstReactRender--22155952430
getState--28359830230436787
initialActions--217123
loadScripts--1217984274030812021968
setupStore--15312801189135618
numNetworkReqs--59291362880113
19--------
WebpackStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--15931297251620417431948
load--13221086194614614041579
domContentLoaded--13221086194514614041578
domInteractive--832923640115146
firstPaint--------
backgroundConnect--65222664977154
firstReactRender--15117771624
getState--2682534117133
initialActions--103122
loadScripts--12791070182212513331461
setupStore--173225261546
numNetworkReqs--20981191475
19--------
WebpackPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--29262184492072834054525
load--16441093313854017512906
domContentLoaded--16431092313854017502905
domInteractive--12931997163108519
firstPaint--------
backgroundConnect--1782612592501591109
firstReactRender--2416121112532
getState--30683915255485833
initialActions--203123
loadScripts--15431078296742916912688
setupStore--106876114594467
numNetworkReqs--61291714082158
19--------
📊 Page Load Benchmark Results

Current Commit: 801f437 | Date: 1/16/2026

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.02s (±36ms) 🟡 | historical mean value: 1.04s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 711ms (±34ms) 🟢 | historical mean value: 727ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 74ms (±11ms) 🟢 | historical mean value: 77ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.02s 36ms 1.00s 1.30s 1.03s 1.30s
domContentLoaded 711ms 34ms 692ms 979ms 721ms 979ms
firstPaint 74ms 11ms 60ms 168ms 84ms 168ms
firstContentfulPaint 74ms 11ms 60ms 168ms 84ms 168ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 58 Bytes (0%)
  • ui: 33 Bytes (0%)
  • common: 231 Bytes (0%)

@gauthierpetetin gauthierpetetin marked this pull request as ready for review January 16, 2026 13:16
@github-project-automation github-project-automation bot moved this to Needs dev review in PR review queue Jan 16, 2026
@metamaskbotv2
Copy link
Copy Markdown
Contributor

metamaskbotv2 bot commented Jan 19, 2026

Builds ready [d256427]
UI Startup Metrics (1272 ± 104 ms)
PlatformBuildTypePageMetricTest Title (ms)Persona (ms)Mean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--12721030153510413361464
load--106787413249811191245
domContentLoaded--106186813089711141240
domInteractive--261591182179
firstPaint--167641084140187326
backgroundConnect--2172012589221237
firstReactRender--1693551825
getState--351765103855
initialActions--104112
loadScripts--8506601102979061030
setupStore--1374461424
numNetworkReqs--171176161165
19--------
BrowserifyPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--19171464249420019902349
load--1041910163711810701288
domContentLoaded--1028895161311810571275
domInteractive--37192293133113
firstPaint--169721091121208357
backgroundConnect--26020665396243534
firstReactRender--22166962434
getState--17313033329191217
initialActions--104112
loadScripts--81168913611158251067
setupStore--1895281838
numNetworkReqs--59331332262117
19--------
WebpackStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--794659120082832911
load--64157791267663782
domContentLoaded--63657390766658772
domInteractive--2515148212083
firstPaint--1016041856122207
backgroundConnect--265140273785
firstReactRender--15113241723
getState--3315136174361
initialActions--107112
loadScripts--63357089565655763
setupStore--127111111323
numNetworkReqs--171174171170
19--------
WebpackPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--1339974199726815161875
load--670588112887684877
domContentLoaded--661582112288672873
domInteractive--32171372629105
firstPaint--1276340278145311
backgroundConnect--92763717519544
firstReactRender--22174042431
getState--14412819514149174
initialActions--102111
loadScripts--658580111386669863
setupStore--1764681740
numNetworkReqs--1024023949138217
19--------
FirefoxBrowserifyStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--13591108197218314481728
load--1091940159110911691267
domContentLoaded--1090940159110911691267
domInteractive--68301393893136
firstPaint--------
backgroundConnect--56193045653191
firstReactRender--12102321218
getState--146145181239
initialActions--103122
loadScripts--105891815659811191218
setupStore--134104141143
numNetworkReqs--20981201377
19--------
BrowserifyPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--26951983570673926224593
load--13441038297743113862711
domContentLoaded--13441035297643113852711
domInteractive--156351112202118497
firstPaint--------
backgroundConnect--157261453233131890
firstReactRender--261599122658
getState--310691033241474843
initialActions--217123
loadScripts--12891008294839712132590
setupStore--1718798211206681
numNetworkReqs--5231111227693
19--------
WebpackStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--16051324202716516931915
load--13531110168212014051616
domContentLoaded--13531110168212014051616
domInteractive--892926851130178
firstPaint--------
backgroundConnect--62231583970145
firstReactRender--15112221519
getState--208255301588
initialActions--102122
loadScripts--13151095164810913751533
setupStore--13578121334
numNetworkReqs--19978171370
19--------
WebpackPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--29062166810786629414646
load--15911155339150016932824
domContentLoaded--15911154339150016932823
domInteractive--122321000151106444
firstPaint--------
backgroundConnect--155241298231129732
firstReactRender--24173752832
getState--325801769286466887
initialActions--213123
loadScripts--15121139314140116332356
setupStore--111782117383669
numNetworkReqs--513099206891
19--------
📊 Page Load Benchmark Results

Current Commit: d256427 | Date: 1/19/2026

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.03s (±52ms) 🟡 | historical mean value: 1.03s ⬆️ (historical data)
  • domContentLoaded-> current mean value: 721ms (±49ms) 🟢 | historical mean value: 717ms ⬆️ (historical data)
  • firstContentfulPaint-> current mean value: 76ms (±14ms) 🟢 | historical mean value: 78ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.03s 52ms 1.01s 1.33s 1.09s 1.33s
domContentLoaded 721ms 49ms 699ms 992ms 758ms 992ms
firstPaint 76ms 14ms 64ms 208ms 84ms 208ms
firstContentfulPaint 76ms 14ms 64ms 208ms 84ms 208ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 58 Bytes (0%)
  • ui: 33 Bytes (0%)
  • common: 231 Bytes (0%)

itsyoboieltr
itsyoboieltr previously approved these changes Jan 20, 2026
await homePage.checkPageIsLoaded();

// The toast should appear because writes are failing
await driver.waitForSelector('[data-testid="storage-error-toast"]');
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should avoid using selectors directly in a spec file. Rather, we should create a method in the corresponding page object class, and then call it from here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the feedback, it's now updated in this commit: 76903ac

// Click the toast action button to navigate to reveal SRP page
// The button text is inside a nested span, so we target the span's text
await driver.clickElement({
text: 'Back up Secret Recovery Phrase',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated in this commit: 76903ac

});

// Verify we navigated to the reveal SRP page (password prompt)
await driver.waitForSelector('[data-testid="input-password"]');
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated in this commit: 76903ac

Move vault recovery-specific selectors and methods from helpers.ts to a
new VaultRecoveryPage class that extends CriticalErrorPage, following
the page object pattern with separation of concerns by feature.

Changes:
- Create VaultRecoveryPage with recovery button methods
- Revert CriticalErrorPage to base error page functionality
- Change CriticalErrorPage fields from private to protected for inheritance
- Update helpers.ts to use VaultRecoveryPage
@metamaskbotv2
Copy link
Copy Markdown
Contributor

metamaskbotv2 bot commented Jan 20, 2026

✨ Files requiring CODEOWNER review ✨

🧪 @MetaMask/qa (4 files, +249 -10)
  • 📁 test/
    • 📁 e2e/
      • 📁 page-objects/
        • 📁 flows/
          • 📄 vault-corruption.flow.ts +105 -0
        • 📁 pages/
          • 📁 home/
            • 📄 homepage.ts +30 -0
            • 📄 critical-error-page.ts +10 -10
            • 📄 vault-recovery-page.ts +104 -0

@metamaskbotv2
Copy link
Copy Markdown
Contributor

metamaskbotv2 bot commented Jan 20, 2026

Builds ready [0205518]
UI Startup Metrics (1287 ± 101 ms)
PlatformBuildTypePageMetricTest Title (ms)Persona (ms)Mean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--12871035160510113491444
load--107386013429711311234
domContentLoaded--106785513309711261227
domInteractive--2515112192283
firstPaint--170641335190193326
backgroundConnect--21920326111223240
firstReactRender--14103541623
getState--341681103746
initialActions--103111
loadScripts--8566531117969171017
setupStore--1162031317
numNetworkReqs--171177161167
19--------
BrowserifyPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--19631700251920820712438
load--1061907140612011051358
domContentLoaded--1048894139612010901341
domInteractive--3519166243494
firstPaint--175721414146211368
backgroundConnect--282211723121254624
firstReactRender--22174442333
getState--18013770559193234
initialActions--106112
loadScripts--82468811741188651122
setupStore--17104151933
numNetworkReqs--60362163161133
19--------
WebpackStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--823665114692876997
load--664584100385711836
domContentLoaded--65957999785707826
domInteractive--2616135232290
firstPaint--1055937758126218
backgroundConnect--285114254081
firstReactRender--15103541622
getState--331599164262
initialActions--107112
loadScripts--65757798984705823
setupStore--1264871326
numNetworkReqs--181184181168
19--------
WebpackPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--1394941196728015991920
load--70361096583720904
domContentLoaded--69360595983706897
domInteractive--37181593035138
firstPaint--1396442070160271
backgroundConnect--77762816420532
firstReactRender--23183642429
getState--15112920715160182
initialActions--102011
loadScripts--69060395081704889
setupStore--1694761824
numNetworkReqs--1023922946133210
19--------
FirefoxBrowserifyStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--14211111208718015661705
load--1137932149412812231396
domContentLoaded--1136932149412812201396
domInteractive--763323254116200
firstPaint--------
backgroundConnect--63212715493178
firstReactRender--14104151323
getState--146134171242
initialActions--102122
loadScripts--1095917137410011751277
setupStore--134127161131
numNetworkReqs--18979161370
19--------
BrowserifyPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--27472053581754228633949
load--13731073315724814111740
domContentLoaded--13731073315624814111740
domInteractive--14138558100140440
firstPaint--------
backgroundConnect--11826928123130244
firstReactRender--251783102734
getState--291691140240347766
initialActions--203123
loadScripts--13301042302922613731685
setupStore--19112878239218839
numNetworkReqs--52301382649117
19--------
WebpackStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--15531285204615516441878
load--13191099169811013821507
domContentLoaded--13181098169711013821507
domInteractive--842721443118148
firstPaint--------
backgroundConnect--50181743055123
firstReactRender--15116761519
getState--178275301529
initialActions--102122
loadScripts--12891082157610013571477
setupStore--145141191241
numNetworkReqs--18978161371
19--------
WebpackPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--29912141664789833934659
load--16971226527269516593161
domContentLoaded--16961226527169516593158
domInteractive--150303238344108400
firstPaint--------
backgroundConnect--1702412672551341074
firstReactRender--23169292532
getState--28175913237402818
initialActions--213123
loadScripts--16061205525061916272983
setupStore--1346695174117623
numNetworkReqs--482495196688
19--------
📊 Page Load Benchmark Results

Current Commit: 0205518 | Date: 1/20/2026

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.02s (±45ms) 🟡 | historical mean value: 1.05s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 716ms (±65ms) 🟢 | historical mean value: 734ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 89ms (±130ms) 🟢 | historical mean value: 81ms ⬆️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.02s 45ms 999ms 1.39s 1.06s 1.39s
domContentLoaded 716ms 65ms 689ms 1.31s 739ms 1.31s
firstPaint 89ms 130ms 60ms 1.38s 88ms 1.38s
firstContentfulPaint 89ms 130ms 60ms 1.38s 88ms 1.38s
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 122.96 KiB (2.45%)
  • ui: 2.25 KiB (0.03%)
  • common: 234.78 KiB (2.6%)

itsyoboieltr
itsyoboieltr previously approved these changes Jan 21, 2026
Copy link
Copy Markdown
Member

@seaona seaona left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi there 👋 thanks for the changes! Looking good! I added a couple of more comments in regards to stick withthe page object standard practices using flows🙏
Let me know if this makes sense or have any questions!

password: WALLET_PASSWORD,
skipSRPBackup: true,
});
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of having a helper function which just calls a flow, can we call the flow directly in the spec file?
In our spec files we should try to use page objects methods or flows (under flow folder). Adding extra layers on top can make it harded to debug, when we are investigating flakiness etc.
The general POM guidelines for performing test actions are eitherto work with:

  • page objects
  • flows
    So we could remove this wrapper. Wdyt?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes total sense, it's updated in this commit: 4a60f05

});

// now that we are re-onboarded, get the first account's address
return await getFirstAddress(driver);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, could we omit this extra layer onboardAfterRecovery and call the inside flows in the spec file?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, updated in this commit: 4a60f05

*/
async function waitForVaultRestorePage(driver: Driver): Promise<void> {
const vaultRecoveryPage = new VaultRecoveryPage(driver);
await vaultRecoveryPage.waitForPageAfterExtensionReload();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, updated in this commit: 4a60f05

* background page for MV2 or offscreen page for MV3.
* @returns The initial first account's address.
*/
export async function onboardThenTriggerCorruption(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we place this under the page-objects/flow folder? to follow our POM guidelines -> if there are actions which need multiple pages, and it's re-used in multiple places, we can create a flow for that

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, it's now moved to the flow folder in this commit: e560fb0

* @param options.driver - The WebDriver instance.
* @param options.confirm - Whether to confirm the action or not.
*/
export async function clickRecover({
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this abstraction can also be removed and instead, call the actions from the spec file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, updated in this commit: 4a60f05

* @param driver - The WebDriver instance.
* @param headerNavbar
*/
export async function getFirstAddress(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems like we need a flow here as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, moved to the flow folder in this commit: e560fb0

Remove wrapper functions that just call flows/page objects directly,
following POM guidelines to reduce indirection and improve debuggability.

Removed wrappers:
- onboard() - now call completeCreateNewWalletOnboardingFlow directly
- clickRecover() - now call vaultRecoveryPage.clickRecoveryButton directly
- onboardAfterRecovery() - now call flow + getFirstAddress directly
- waitForVaultRestorePage() - inlined in onboardThenTriggerCorruption

Spec files now import and use flows/page objects directly.
Move multi-page orchestration functions to page-objects/flows following
POM guidelines for reusable flows that span multiple pages.

Changes:
- Create vault-corruption.flow.ts with getFirstAddress and
  onboardThenTriggerCorruptionFlow
- Reduce helpers.ts to only contain getConfig test configuration
- Update spec files to import from the new flow file
@metamaskbotv2
Copy link
Copy Markdown
Contributor

metamaskbotv2 bot commented Jan 21, 2026

Builds ready [69d22bb]
UI Startup Metrics (1304 ± 117 ms)
PlatformBuildTypePageMetricTest Title (ms)Persona (ms)Mean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--13041061167211713691465
load--1105909142410411671289
domContentLoaded--1098896141210311621280
domInteractive--2715100192383
firstPaint--178641435198191324
backgroundConnect--22821028114232257
firstReactRender--1793861931
getState--3517120134155
initialActions--103112
loadScripts--87868011701029411067
setupStore--1262641421
numNetworkReqs--171173161165
19--------
BrowserifyPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--285515378106147431926221
load--1122940146813612321377
domContentLoaded--1105918144813312131355
domInteractive--35191632535105
firstPaint--198811475196236332
backgroundConnect--71121032088406002861
firstReactRender--21164152335
getState--2811313750392261593
initialActions--104111
loadScripts--87771312331239811103
setupStore--20672112339
numNetworkReqs--85462283492153
19--------
WebpackStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--8546901146818941012
load--69261390169747830
domContentLoaded--68760789369742825
domInteractive--2818126222488
firstPaint--1026530447119198
backgroundConnect--2561613229103
firstReactRender--18113962135
getState--3515152224266
initialActions--104112
loadScripts--68460589168740818
setupStore--1464381630
numNetworkReqs--171172171168
19--------
WebpackPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--13191026265426814261791
load--70461796880703893
domContentLoaded--69261095780692884
domInteractive--37191372536111
firstPaint--1466633564192265
backgroundConnect--46959711321283
firstReactRender--22173332429
getState--15513349040159185
initialActions--102011
loadScripts--68960894979690874
setupStore--2094792143
numNetworkReqs--93402534099193
19--------
FirefoxBrowserifyStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--14671163203717115841778
load--1176970181213012391420
domContentLoaded--1175970181213112391420
domInteractive--793435850107162
firstPaint--------
backgroundConnect--64222714883159
firstReactRender--15115861424
getState--156146181431
initialActions--2028422
loadScripts--1135955178211711791393
setupStore--154192211242
numNetworkReqs--19987191372
19--------
BrowserifyPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--27701931744081329263859
load--13571008347837114282253
domContentLoaded--13561008347837114282253
domInteractive--188491314211199518
firstPaint--------
backgroundConnect--3933950165805961038
firstReactRender--23166072532
getState--240671073189296650
initialActions--2021223
loadScripts--1286984343733313461992
setupStore--14224711137169471
numNetworkReqs--74381312389121
19--------
WebpackStandard Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--16521402231118317262043
load--13731186165010914541559
domContentLoaded--13721185164910914531559
domInteractive--893222845125168
firstPaint--------
backgroundConnect--662319947106161
firstReactRender--16125051624
getState--178106171645
initialActions--103122
loadScripts--1332116215459314031509
setupStore--2242654113101
numNetworkReqs--19983191477
19--------
WebpackPower User Home0--------
1--------
2--------
3--------
4--------
5--------
6--------
7--------
8--------
9--------
10--------
11--------
12--------
13--------
14--------
15--------
16--------
17--------
18--------
uiStartup--27272089467842928463516
load--14661211250021215241918
domContentLoaded--14661211249421215241917
domInteractive--15331733113198346
firstPaint--------
backgroundConnect--3093124103494741008
firstReactRender--22155052429
getState--23470885198230685
initialActions--207123
loadScripts--14181188247819114831776
setupStore--13414757156145592
numNetworkReqs--73331793180161
19--------
📊 Page Load Benchmark Results

Current Commit: 69d22bb | Date: 1/21/2026

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.06s (±59ms) 🟡 | historical mean value: 1.04s ⬆️ (historical data)
  • domContentLoaded-> current mean value: 741ms (±56ms) 🟢 | historical mean value: 728ms ⬆️ (historical data)
  • firstContentfulPaint-> current mean value: 79ms (±11ms) 🟢 | historical mean value: 78ms ⬆️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.06s 59ms 1.02s 1.38s 1.11s 1.38s
domContentLoaded 741ms 56ms 710ms 1.04s 768ms 1.04s
firstPaint 79ms 11ms 60ms 176ms 88ms 176ms
firstContentfulPaint 79ms 11ms 60ms 176ms 88ms 176ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs
  • background: 58 Bytes (0%)
  • ui: 33 Bytes (0%)
  • common: 231 Bytes (0%)

*
* @throws Error if simulating storage failure for testing
*/
#maybeSimulateSetFailure(): void {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the set failure in its own function but not the get failure? This is not a request for change in either direction, just curious.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The get failure is only called in one method (get).
The set failure is called from two different methods (set and persist), so extracting logic to a separate function (maybeSimulateSetFailure) avoids code duplication.

Copy link
Copy Markdown
Member

@seaona seaona left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QA changes LGTM !

@github-project-automation github-project-automation bot moved this from Needs dev review to Review finalised - Ready to be merged in PR review queue Jan 22, 2026
@itsyoboieltr itsyoboieltr added this pull request to the merge queue Jan 22, 2026
Merged via the queue into main with commit 75a98f9 Jan 22, 2026
517 of 526 checks passed
@itsyoboieltr itsyoboieltr deleted the feat_storage_operations_recovery_e2e_test branch January 22, 2026 11:08
@github-project-automation github-project-automation bot moved this from Review finalised - Ready to be merged to Merged, Closed or Archived in PR review queue Jan 22, 2026
@github-actions github-actions bot locked and limited conversation to collaborators Jan 22, 2026
@metamaskbot metamaskbot added the release-13.16.0 Issue or pull request that will be included in release 13.16.0 label Jan 22, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-13.16.0 Issue or pull request that will be included in release 13.16.0 size-L team-extension-platform Extension Platform team

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Mysterious Firefox error "An unexpected error occurred"

5 participants