From a5c0442b099139418a86f7e87ad0ecfcc61be4b1 Mon Sep 17 00:00:00 2001 From: EdgeClaws <268039199+EdgeClaws@users.noreply.github.com> Date: Fri, 14 Aug 2026 16:10:07 -0700 Subject: [PATCH 01/15] fix(maestro): persist JavaScript state via output --- .../C000032-archive-and-restore-wallets.yaml | 36 +++++++++---------- .../C000036-autodetect-all-networks.yaml | 16 ++++----- maestro/07-wallets/C000037-split-wallets.yaml | 6 ++-- .../07-wallets/C000043-private-view-key.yaml | 20 +++++------ .../C000044-create-all-wallet-types.yaml | 14 ++++---- maestro/07-wallets/C000046-rename-wallet.yaml | 6 ++-- maestro/07-wallets/C000048-split-all-evm.yaml | 13 ++++--- maestro/common/add-wallets.yaml | 14 ++++---- maestro/common/create-account.yaml | 27 +++++++------- maestro/common/import-wallets.yaml | 26 +++++++------- 10 files changed, 88 insertions(+), 90 deletions(-) diff --git a/maestro/07-wallets/C000032-archive-and-restore-wallets.yaml b/maestro/07-wallets/C000032-archive-and-restore-wallets.yaml index 1fd43f8d6d1..a781c4268d5 100644 --- a/maestro/07-wallets/C000032-archive-and-restore-wallets.yaml +++ b/maestro/07-wallets/C000032-archive-and-restore-wallets.yaml @@ -22,38 +22,38 @@ tags: # Archive wallets -- evalScript: ${var walletNames = ["My Bitcoin", "My Bitcoin Cash", "My Dash", "My Ether", "My Litecoin"]} -- evalScript: ${var index = 0} +- evalScript: ${output.walletNames = ["My Bitcoin", "My Bitcoin Cash", "My Dash", "My Ether", "My Litecoin"]} +- evalScript: ${output.index = 0} - tapOn: Assets - repeat: - times: ${walletNames.length - 1} + times: ${output.walletNames.length - 1} commands: - - tapOn: ${walletNames[index]} + - tapOn: ${output.walletNames[output.index]} - tapOn: id: gearIcon - tapOn: ".*Archive Wallet" # Modal - assertVisible: "Archive Wallet" - - assertVisible: ${"Are you sure you want to archive " + walletNames[index] + "?"} + - assertVisible: ${"Are you sure you want to archive " + output.walletNames[output.index] + "?"} - assertVisible: Cancel # Check if "My Ether" wallet - runFlow: when: - true: ${walletNames[index] == "My Ether"} + true: ${output.walletNames[output.index] == "My Ether"} commands: - assertVisible: "Archiving this wallet will also archive any enabled tokens for this wallet." label: "Extra message for Ether wallets" # Archive - tapOn: Archive - - assertNotVisible: ${walletNames[index]} + - assertNotVisible: ${output.walletNames[output.index]} - - evalScript: ${index++} + - evalScript: ${output.index++} label: "Archive all wallets except last" # Unable to archive last wallet - runFlow: commands: - - longPressOn: ${walletNames[index]} + - longPressOn: ${output.walletNames[output.index]} - tapOn: ".*Archive Wallet" - assertVisible: "Cannot Archive Wallet" - assertVisible: "At least one wallet required in this account." @@ -80,13 +80,13 @@ tags: - assertVisible: "Restore Wallets" # Toggle on wallets to restore -- evalScript: ${var walletCurrencyCodes = ["BTC", "BCH", "DASH", "ETH", "LTC"]} -- evalScript: ${var index = 0} +- evalScript: ${output.walletCurrencyCodes = ["BTC", "BCH", "DASH", "ETH", "LTC"]} +- evalScript: ${output.index = 0} - repeat: - times: ${walletCurrencyCodes.length - 1} + times: ${output.walletCurrencyCodes.length - 1} commands: - - tapOn: ${walletCurrencyCodes[index]} - - evalScript: ${index++} + - tapOn: ${output.walletCurrencyCodes[output.index]} + - evalScript: ${output.index++} - tapOn: Restore # Modal @@ -97,14 +97,14 @@ tags: # Confirm restored and returned to assets screen - assertVisible: "Total Balance.*" -- evalScript: ${var index = 0} +- evalScript: ${output.index = 0} - repeat: - times: ${walletNames.length} + times: ${output.walletNames.length} commands: - scrollUntilVisible: - element: ${walletNames[index]} + element: ${output.walletNames[output.index]} direction: DOWN - - evalScript: ${index++} + - evalScript: ${output.index++} # Ensure restore is not tappable when none left to restore - tapOn: diff --git a/maestro/07-wallets/C000036-autodetect-all-networks.yaml b/maestro/07-wallets/C000036-autodetect-all-networks.yaml index 4d9bdbc4e31..fe228d3d64b 100644 --- a/maestro/07-wallets/C000036-autodetect-all-networks.yaml +++ b/maestro/07-wallets/C000036-autodetect-all-networks.yaml @@ -23,7 +23,7 @@ tags: # All networks that support tokens (and import seed) # EVMs: Only Sonic and Pulsechain (others tested via regular asset sync) - evalScript: ${ - var wallets = '[ + output.wallets = '[ "Coreum", "Osmosis", "Avalanche", @@ -40,7 +40,7 @@ tags: - runFlow: file: ../common/import-wallets.yaml env: - ASSET_NAMES: ${wallets} + ASSET_NAMES: ${output.wallets} # label: "Import wallets" - runFlow: @@ -54,7 +54,7 @@ tags: # Tokens matching the imported networks - evalScript: ${ - var tokens = [ + output.tokens = [ "ATOM", "JOE", "PYTH", @@ -94,17 +94,17 @@ tags: # visible: ${".*New tokens were detected and enabled on " + WALLET_NAME + ".*"} # timeout: 60000 -- evalScript: ${var index = 0} +- evalScript: ${output.index = 0} - repeat: - times: ${tokens.length} + times: ${output.tokens.length} commands: - scrollUntilVisible: - element: ${tokens[index]} + element: ${output.tokens[output.index]} direction: UP timeout: 20000 optional: true - scrollUntilVisible: - element: ${tokens[index]} + element: ${output.tokens[output.index]} direction: DOWN timeout: 90000 - scrollUntilVisible: @@ -114,7 +114,7 @@ tags: timeout: 10000 optional: true label: "Scroll to bottom." - - evalScript: ${index++} + - evalScript: ${output.index++} diff --git a/maestro/07-wallets/C000037-split-wallets.yaml b/maestro/07-wallets/C000037-split-wallets.yaml index afe956fe4b2..74e6d602b88 100644 --- a/maestro/07-wallets/C000037-split-wallets.yaml +++ b/maestro/07-wallets/C000037-split-wallets.yaml @@ -56,8 +56,8 @@ tags: - assertVisible: Split Wallet - assertVisible: This action creates wallets from pre-existing wallets. - assertVisible: Tap on wallet to edit name -- evalScript: ${var newETHName = ".*My Ether \\(Split from My Base\\).*"} -- assertVisible: ${newETHName} +- evalScript: ${output.newETHName = ".*My Ether \\(Split from My Base\\).*"} +- assertVisible: ${output.newETHName} # Rename modal - tapOn: @@ -109,7 +109,7 @@ tags: ## Verify new wallets and balances # ETH recovered - scrollUntilVisible: - element: ${newETHName} + element: ${output.newETHName} direction: DOWN centerElement: true timeout: 10000 diff --git a/maestro/07-wallets/C000043-private-view-key.yaml b/maestro/07-wallets/C000043-private-view-key.yaml index d2b94ab2d12..5ba00c20693 100644 --- a/maestro/07-wallets/C000043-private-view-key.yaml +++ b/maestro/07-wallets/C000043-private-view-key.yaml @@ -21,20 +21,20 @@ tags: # Monero/Zano (CryptoNote): 64-char hex # Zcash/Pirate (zk-SNARKs): longer alphanumeric strings - evalScript: ${ - var walletFormats = { + output.walletFormats = { "Monero":"[a-fA-F0-9]{64}", "Pirate Chain":"[a-zA-Z0-9]{64,}", "Zcash":"[a-zA-Z0-9]{64,}", "Zano":"[a-fA-F0-9]{64}" } } -- evalScript: ${var walletNames = Object.keys(walletFormats)} +- evalScript: ${output.walletNames = Object.keys(output.walletFormats)} # Create account with wallets that support private view key - runFlow: file: ../common/create-account.yaml env: - NEW_WALLETS: ${JSON.stringify(walletNames)} + NEW_WALLETS: ${JSON.stringify(output.walletNames)} label: "Add wallets with private view key support" - runFlow: @@ -43,17 +43,17 @@ tags: - tapOn: Assets # Loop over each wallet and test Private View Key -- evalScript: ${var index = 0} +- evalScript: ${output.index = 0} - repeat: - times: ${walletNames.length} + times: ${output.walletNames.length} commands: # Wallet nickname often excludes extra words (e.g. "Pirate Chain" -> "Pirate") - - evalScript: ${var nickName = "My " + walletNames[index].split(" ")[0]} + - evalScript: ${output.nickName = "My " + output.walletNames[output.index].split(" ")[0]} - scrollUntilVisible: - element: ${nickName} + element: ${output.nickName} direction: DOWN centerElement: true - - longPressOn: ${nickName} + - longPressOn: ${output.nickName} - assertVisible: ".*Private View Key" - tapOn: ".*Private View Key" # Private View Key Modal @@ -63,9 +63,9 @@ tags: - assertVisible: "Copy" # Validate view key format for this network - assertVisible: - text: ${walletFormats[walletNames[index]]} + text: ${output.walletFormats[output.walletNames[output.index]]} - tapOn: id: "modal-close-button" - - evalScript: ${index++} + - evalScript: ${output.index++} # - stopApp diff --git a/maestro/07-wallets/C000044-create-all-wallet-types.yaml b/maestro/07-wallets/C000044-create-all-wallet-types.yaml index 95cb1e13473..4597f295e9e 100644 --- a/maestro/07-wallets/C000044-create-all-wallet-types.yaml +++ b/maestro/07-wallets/C000044-create-all-wallet-types.yaml @@ -29,10 +29,10 @@ tags: file: ../common/no-errors.yaml # Validate that all wallets were created -- evalScript: ${var index = 0} -- evalScript: ${var walletNames = JSON.parse(output.assetNames)} +- evalScript: ${output.index = 0} +- evalScript: ${output.walletNames = JSON.parse(output.assetNames)} - repeat: - times: ${walletNames.length} + times: ${output.walletNames.length} commands: # option 1 # Preferred quicker method, but iOS wallet search is not currently reliable when maestro types too fast @@ -45,9 +45,9 @@ tags: # Option 2 # Wallet nickname often excludes extra words (e.g. "Pirate Chain" -> "My Pirate") - - evalScript: ${var nickName = "My " + walletNames[index].split(" ")[0] + ".*"} + - evalScript: ${output.nickName = "My " + output.walletNames[output.index].split(" ")[0] + ".*"} # Hack to address inconsistent wallet name for XRP - - evalScript: ${if (walletNames[index] === "XRPL") { nickName = "My XRP"}} + - evalScript: ${if (output.walletNames[output.index] === "XRPL") { output.nickName = "My XRP"}} - retry: maxRetries: 2 commands: @@ -57,9 +57,9 @@ tags: speed: 150 timeout: 30000 - scrollUntilVisible: - element: ${nickName} + element: ${output.nickName} centerElement: true timeout: 60000 speed: 5 - - evalScript: ${index++} \ No newline at end of file + - evalScript: ${output.index++} \ No newline at end of file diff --git a/maestro/07-wallets/C000046-rename-wallet.yaml b/maestro/07-wallets/C000046-rename-wallet.yaml index 29b4b06ca5a..490b0f37d54 100644 --- a/maestro/07-wallets/C000046-rename-wallet.yaml +++ b/maestro/07-wallets/C000046-rename-wallet.yaml @@ -31,10 +31,10 @@ tags: # Copy new name and save - copyTextFrom: id: "undefined.textInput" -- evalScript: ${var newWalletName = maestro.copiedText} +- evalScript: ${output.newWalletName = maestro.copiedText} - tapOn: Submit -- assertVisible: ${newWalletName} +- assertVisible: ${output.newWalletName} # Arbitrary wait to ensure wallet state is saved to sync server (~30 seconds) - extendedWaitUntil: visible: ${WALLET_NAME} @@ -54,4 +54,4 @@ tags: file: ../common/dismiss-modals.yaml - tapOn: Assets -- assertVisible: ${newWalletName} \ No newline at end of file +- assertVisible: ${output.newWalletName} \ No newline at end of file diff --git a/maestro/07-wallets/C000048-split-all-evm.yaml b/maestro/07-wallets/C000048-split-all-evm.yaml index f31dcbf205b..d4274c6e698 100644 --- a/maestro/07-wallets/C000048-split-all-evm.yaml +++ b/maestro/07-wallets/C000048-split-all-evm.yaml @@ -39,7 +39,7 @@ tags: # Define expected EVM networks (ordered by appearance) - evalScript: | - ${var evmNetworks = [ + ${output.evmNetworks = [ "zkSync", "Optimism", "Ethereum Classic", @@ -62,9 +62,9 @@ tags: ]} # Loop over each network and scroll until visible -- evalScript: ${var index = 0} +- evalScript: ${output.index = 0} - repeat: - times: ${evmNetworks.length} + times: ${output.evmNetworks.length} commands: # # Once search can accomodate multiple words # # Search is slower but more reliable @@ -82,15 +82,15 @@ tags: maxRetries: 2 commands: - scrollUntilVisible: - element: ${".*" + evmNetworks[index]} + element: ${".*" + output.evmNetworks[output.index]} direction: DOWN centerElement: true speed: 1 timeout: 1000 optional: true - - tapOn: ${".*" + evmNetworks[index]} + - tapOn: ${".*" + output.evmNetworks[output.index]} - - evalScript: ${index++} + - evalScript: ${output.index++} - tapOn: Next @@ -108,4 +108,3 @@ tags: - stopApp - diff --git a/maestro/common/add-wallets.yaml b/maestro/common/add-wallets.yaml index 34e8dce96dd..08445969538 100644 --- a/maestro/common/add-wallets.yaml +++ b/maestro/common/add-wallets.yaml @@ -8,8 +8,8 @@ appId: ${MAESTRO_APP_ID} env: ASSET_NAMES: ${ASSET_NAMES || ""} --- -# Parse if an array/list- all passed env become strings with maestro's Rhino JS runtime -- evalScript: ${if (ASSET_NAMES.startsWith('[')) ASSET_NAMES = JSON.parse(ASSET_NAMES); else ASSET_NAMES = [ASSET_NAMES]} +# Parse if an array/list; all passed env values become strings +- evalScript: ${if (ASSET_NAMES.startsWith('[')) output.ASSET_NAMES = JSON.parse(ASSET_NAMES); else output.ASSET_NAMES = [ASSET_NAMES]} - tapOn: Assets - tapOn: @@ -17,17 +17,17 @@ env: - tapOn: Search Wallets # Loop over wallet names and add them -- evalScript: ${var index = 0} +- evalScript: ${output.index = 0} - repeat: - times: ${ASSET_NAMES.length} + times: ${output.ASSET_NAMES.length} commands: - tapOn: id: "undefined.clearIcon" - - inputText: ${ASSET_NAMES[index]} + - inputText: ${output.ASSET_NAMES[output.index]} - tapOn: - text: ${".*" + ASSET_NAMES[index]} + text: ${".*" + output.ASSET_NAMES[output.index]} index: 1 # First index is thesearch bar - - evalScript: ${index++} + - evalScript: ${output.index++} - tapOn: Next diff --git a/maestro/common/create-account.yaml b/maestro/common/create-account.yaml index d3fbb6b4032..eccccda024e 100644 --- a/maestro/common/create-account.yaml +++ b/maestro/common/create-account.yaml @@ -131,30 +131,29 @@ env: true: ${NEW_WALLETS} commands: # Remove default wallets - - evalScript: ${var wallets = JSON.parse(NEW_WALLETS)} - - evalScript: ${var defaults = JSON.parse(DEFAULT_WALLETS)} - - evalScript: ${var filteredDefaults = defaults.filter(d => !wallets.includes(d))} - - evalScript: ${var filteredWallets = wallets.filter(w => !defaults.includes(w))} - - evalScript: ${var defIndex = 0} + - evalScript: ${output.wallets = JSON.parse(NEW_WALLETS)} + - evalScript: ${output.defaults = JSON.parse(DEFAULT_WALLETS)} + - evalScript: ${output.filteredDefaults = output.defaults.filter(d => !output.wallets.includes(d))} + - evalScript: ${output.filteredWallets = output.wallets.filter(w => !output.defaults.includes(w))} + - evalScript: ${output.defIndex = 0} - repeat: - times: ${filteredDefaults.length} + times: ${output.filteredDefaults.length} commands: - - tapOn: ${".*" + filteredDefaults[defIndex]} - - evalScript: ${defIndex++} + - tapOn: ${".*" + output.filteredDefaults[output.defIndex]} + - evalScript: ${output.defIndex++} # Add new wallets - - evalScript: ${var newIndex = 0} + - evalScript: ${output.newIndex = 0} - repeat: - times: ${filteredWallets.length} + times: ${output.filteredWallets.length} commands: - tapOn: Search Wallets - tapOn: id: "undefined.clearIcon" - - inputText: ${filteredWallets[newIndex]} + - inputText: ${output.filteredWallets[output.newIndex]} - tapOn: - text: ${".*" + filteredWallets[newIndex]} + text: ${".*" + output.filteredWallets[output.newIndex]} index: 1 - - evalScript: ${newIndex++} + - evalScript: ${output.newIndex++} - tapOn: id: "nextButton" - diff --git a/maestro/common/import-wallets.yaml b/maestro/common/import-wallets.yaml index 0d6025a3f9a..01d2d66d014 100644 --- a/maestro/common/import-wallets.yaml +++ b/maestro/common/import-wallets.yaml @@ -8,7 +8,7 @@ env: ZCASH_BDAY: ${ZCASH_BDAY || ""} --- # Parse env so we can accept a string or array input -- evalScript: ${if (ASSET_NAMES.startsWith('[')) ASSET_NAMES = JSON.parse(ASSET_NAMES); else ASSET_NAMES = [ASSET_NAMES]} +- evalScript: ${if (ASSET_NAMES.startsWith('[')) output.ASSET_NAMES = JSON.parse(ASSET_NAMES); else output.ASSET_NAMES = [ASSET_NAMES]} # Open add wallet screen - tapOn: Assets @@ -17,21 +17,21 @@ env: - tapOn: Search Wallets # Loop over wallet names and import them -- evalScript: ${var index = 0} +- evalScript: ${output.index = 0} - repeat: - times: ${ASSET_NAMES.length} + times: ${output.ASSET_NAMES.length} commands: - - evalScript: ${var assetName = ASSET_NAMES[index]} + - evalScript: ${output.assetName = output.ASSET_NAMES[output.index]} - tapOn: id: "undefined.clearIcon" - - inputText: ${assetName} + - inputText: ${output.assetName} # Escape parentheses for regex matching - "Bitcoin (no Segwit)" breaks flow otherwise - - evalScript: ${assetName = assetName.replace(/\(/g, '\\(').replace(/\)/g, '\\)')} + - evalScript: ${output.assetName = output.assetName.replace(/\(/g, '\\(').replace(/\)/g, '\\)')} - tapOn: - text: ${".*" + assetName} + text: ${".*" + output.assetName} index: 1 # First index is thesearch bar - - evalScript: ${index++} + - evalScript: ${output.index++} - tapOn: Next - tapOn: Import Wallets @@ -64,7 +64,7 @@ env: # Add birthday height for Zcash and Pirate Chain # Index for targetting the correct "edit" icon -- evalScript: ${var index = 0} +- evalScript: ${output.index = 0} # Pirate Chain on top if both are displayed - runFlow: when: @@ -72,10 +72,10 @@ env: commands: - tapOn: text: "" - index: ${index} + index: ${output.index} - inputText: ${PIRATE_BDAY} - tapOn: Submit - - evalScript: ${index++} + - evalScript: ${output.index++} # Zcash birthday - runFlow: when: @@ -83,10 +83,10 @@ env: commands: - tapOn: text: "" - index: ${index} + index: ${output.index} - inputText: ${ZCASH_BDAY} - tapOn: Submit - - evalScript: ${index++} + - evalScript: ${output.index++} # tap on next until it becomes tapable and works to see "assets" button From d950db54b34c16be3860fb9ec10f83e84998fa85 Mon Sep 17 00:00:00 2001 From: EdgeClaws <268039199+EdgeClaws@users.noreply.github.com> Date: Wed, 19 Aug 2026 19:49:22 -0700 Subject: [PATCH 02/15] fix(maestro): correct C000029a tag to stop silent skip The tag was C000029 but the flow is C000029a; a C000029a tag-filtered run silently skipped it. Match the tag to the test ID. Co-Authored-By: Claude Opus 4.8 --- maestro/07-wallets/C000029a-migrate-wallets.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maestro/07-wallets/C000029a-migrate-wallets.yaml b/maestro/07-wallets/C000029a-migrate-wallets.yaml index e166e442070..f858e1e29b8 100644 --- a/maestro/07-wallets/C000029a-migrate-wallets.yaml +++ b/maestro/07-wallets/C000029a-migrate-wallets.yaml @@ -17,7 +17,7 @@ env: IMPORT_SEED: ${MAESTRO_EDGE_MAX_IMPORT_SEED} tags: - android -- C000029 +- C000029a --- - runFlow: file: ../common/launch-cleared.yaml From 722b611b091e51d3e57bf9fcd69a79cceb6f33e0 Mon Sep 17 00:00:00 2001 From: EdgeClaws <268039199+EdgeClaws@users.noreply.github.com> Date: Tue, 18 Aug 2026 19:23:41 -0700 Subject: [PATCH 03/15] fix(maestro): disable C000035 raw keys flow --- .../07-wallets/C000035-get-raw-keys.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {maestro => maestro-disabled}/07-wallets/C000035-get-raw-keys.yaml (100%) diff --git a/maestro/07-wallets/C000035-get-raw-keys.yaml b/maestro-disabled/07-wallets/C000035-get-raw-keys.yaml similarity index 100% rename from maestro/07-wallets/C000035-get-raw-keys.yaml rename to maestro-disabled/07-wallets/C000035-get-raw-keys.yaml From 6fc7c5da81d2c44e5e369ff60295e54bce32c5ad Mon Sep 17 00:00:00 2001 From: EdgeClaws <268039199+EdgeClaws@users.noreply.github.com> Date: Wed, 19 Aug 2026 00:06:21 -0700 Subject: [PATCH 04/15] fix(maestro): skip unavailable GRS and UFO coverage --- maestro/10-assets/C184035-utxo-01.yaml | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/maestro/10-assets/C184035-utxo-01.yaml b/maestro/10-assets/C184035-utxo-01.yaml index 1c995f8afe3..b3fecfa8ede 100644 --- a/maestro/10-assets/C184035-utxo-01.yaml +++ b/maestro/10-assets/C184035-utxo-01.yaml @@ -141,28 +141,6 @@ tags: timeout: 15000 - tapOn: Assets -- scrollUntilVisible: - element: GRS - direction: DOWN - centerElement: true - timeout: 50000 -- tapOn: GRS -- extendedWaitUntil: - visible: 1.43161025 GRS - timeout: 15000 -- tapOn: Assets - -- scrollUntilVisible: - element: UFO - direction: DOWN - centerElement: true - timeout: 50000 -- tapOn: UFO -- extendedWaitUntil: - visible: "1,337 UFO" - timeout: 15000 -- tapOn: Assets - - scrollUntilVisible: element: PIVX direction: DOWN From bfa8bbc81c4e4f4f14c9587c3fcfdc466a3e3ab3 Mon Sep 17 00:00:00 2001 From: EdgeClaws <268039199+EdgeClaws@users.noreply.github.com> Date: Tue, 18 Aug 2026 11:20:02 -0700 Subject: [PATCH 05/15] fix(maestro): stabilize C000045 token flow --- .../07-wallets/C000045-add-edit-tokens.yaml | 13 ++++---- maestro/common/import-wallets.yaml | 30 +++++++++++++------ src/components/scenes/ManageTokensScene.tsx | 3 +- src/components/themed/ManageTokensRow.tsx | 6 +++- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/maestro/07-wallets/C000045-add-edit-tokens.yaml b/maestro/07-wallets/C000045-add-edit-tokens.yaml index 4024e06edde..57c78be9025 100644 --- a/maestro/07-wallets/C000045-add-edit-tokens.yaml +++ b/maestro/07-wallets/C000045-add-edit-tokens.yaml @@ -50,9 +50,8 @@ tags: - pressKey: Enter # First time token warning modal -- tapOn: - text: "1INCH.*" - index: 2 +- tapOn: + id: manageTokensRow.1INCH - assertVisible: "ETH Needed to Send Tokens" - tapOn: "ETH is required to pay the mining fees when sending tokens. The associated ETH wallet must contain a sufficient.*" - tapOn: "Please confirm your understanding below:" @@ -117,11 +116,9 @@ tags: timeout: 15000 # Save token - tapOn: Save - - assertVisible: ".*MOG.*" - - + # Confirm -- tapOn: Done +- tapOn: Save # Ensure tokens are visible - scrollUntilVisible: @@ -177,4 +174,4 @@ tags: # - tapOn: ".*Add / Edit Tokens" # # Tap on 'edit' icon # - tapOn: "" -# - tapOn: Delete \ No newline at end of file +# - tapOn: Delete diff --git a/maestro/common/import-wallets.yaml b/maestro/common/import-wallets.yaml index 01d2d66d014..0e4239f8a02 100644 --- a/maestro/common/import-wallets.yaml +++ b/maestro/common/import-wallets.yaml @@ -47,11 +47,15 @@ env: - hideKeyboard - tapOn: "Enter your.*" # Drop keyboard - iOS +# Do not press Enter/Return: seed field is multiline, returnKeyType=none, +# blurOnSubmit=false. Tapping the field label also fails to dismiss. Tap the +# non-interactive instruction paragraph (Maestro iOS keyboard workaround). - runFlow: when: platform: iOS commands: - - tapOn: "Private Key or Private Seed" + - tapOn: + text: "^Enter your private seed, private key, or active key to verify and restore the associated wallet$" - tapOn: Next @@ -89,13 +93,21 @@ env: - evalScript: ${output.index++} -# tap on next until it becomes tapable and works to see "assets" button -# skip if NO_COMPLETE is true (for autodetect tokens flow test) -- repeat: - while: - visible: Next +# Complete the import unless the caller intentionally stops early +# to test the auto-detected-token notification. +- runFlow: + when: true: ${!NO_COMPLETE} commands: - - tapOn: - text: Next - optional: true \ No newline at end of file + # Bound retries so a stuck Next button cannot hang the suite. + - repeat: + times: 10 + while: + visible: Next + commands: + - tapOn: + text: Next + optional: true + + # A bounded repeat can exhaust successfully, so verify completion. + - assertNotVisible: Next diff --git a/src/components/scenes/ManageTokensScene.tsx b/src/components/scenes/ManageTokensScene.tsx index 02512622e7e..4ce4ebd6ebf 100644 --- a/src/components/scenes/ManageTokensScene.tsx +++ b/src/components/scenes/ManageTokensScene.tsx @@ -381,7 +381,8 @@ const ManageTokensSceneComponent: React.FC = props => { primary={{ label: lstrings.string_save, onPress: handleSave, - disabled: !hasUnsavedChanges + disabled: !hasUnsavedChanges, + testID: 'manageTokensSaveButton' }} secondary={ wallet.currencyInfo.customTokenTemplate == null diff --git a/src/components/themed/ManageTokensRow.tsx b/src/components/themed/ManageTokensRow.tsx index 36cf7555bf1..2720cdbd45a 100644 --- a/src/components/themed/ManageTokensRow.tsx +++ b/src/components/themed/ManageTokensRow.tsx @@ -83,7 +83,11 @@ export const ManageTokensRowComponent: React.FC = props => { }) return ( - + Date: Wed, 19 Aug 2026 15:23:31 -0700 Subject: [PATCH 06/15] fix(maestro): update disabled token selectors --- maestro/07-wallets/C000034-detect-disable-tokens.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/maestro/07-wallets/C000034-detect-disable-tokens.yaml b/maestro/07-wallets/C000034-detect-disable-tokens.yaml index 7b63b1741eb..4e530483840 100644 --- a/maestro/07-wallets/C000034-detect-disable-tokens.yaml +++ b/maestro/07-wallets/C000034-detect-disable-tokens.yaml @@ -42,6 +42,9 @@ tags: # Complete import - tapOn: Next # Ensure receive token detected notification and tap on it + # After trying several wait/tap patterns, this polling loop has been the + # most dependable: the notification disappears after about 5 seconds, so + # poll while Total Balance remains visible; tapping it exits the loop. - repeat: while: visible: "Total Balance.*" @@ -55,9 +58,8 @@ tags: - assertVisible: "Auto Detected Tokens" - assertVisible: "All Tokens" - tapOn: - text: ${TOKEN_NAME + ".*"} - index: 1 - - tapOn: Done + id: ${"manageTokensRow." + TOKEN_NAME} + - tapOn: Save - assertNotVisible: ${TOKEN_NAME} # # Skip testing resync behavior until changed - expected NOT to rediscover tokens from a resync From 979dbe475a92f21793c3bc697a797a566fd09985 Mon Sep 17 00:00:00 2001 From: EdgeClaws <268039199+EdgeClaws@users.noreply.github.com> Date: Tue, 18 Aug 2026 23:45:05 -0700 Subject: [PATCH 07/15] fix(maestro): follow wallet settings rename flow --- maestro/07-wallets/C000046-rename-wallet.yaml | 16 +++++++++------- src/components/modals/WalletSettingsModal.tsx | 2 ++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/maestro/07-wallets/C000046-rename-wallet.yaml b/maestro/07-wallets/C000046-rename-wallet.yaml index 490b0f37d54..943edfcd50f 100644 --- a/maestro/07-wallets/C000046-rename-wallet.yaml +++ b/maestro/07-wallets/C000046-rename-wallet.yaml @@ -20,19 +20,21 @@ tags: - tapOn: Assets - longPressOn: ${WALLET_NAME} -- tapOn: ".*Rename" -# Modal -- assertVisible: Rename Wallet +- tapOn: + id: "walletListMenu_walletSettings" +# Wallet Settings modal +- assertVisible: Wallet Settings - assertVisible: id: "modal-close-button" - tapOn: - id: "undefined.clearIcon" + id: "walletSettingsNameInput.clearIcon" - inputRandomText # Copy new name and save - copyTextFrom: - id: "undefined.textInput" + id: "walletSettingsNameInput.textInput" - evalScript: ${output.newWalletName = maestro.copiedText} -- tapOn: Submit +- tapOn: + id: "walletSettingsDoneButton" - assertVisible: ${output.newWalletName} # Arbitrary wait to ensure wallet state is saved to sync server (~30 seconds) @@ -54,4 +56,4 @@ tags: file: ../common/dismiss-modals.yaml - tapOn: Assets -- assertVisible: ${output.newWalletName} \ No newline at end of file +- assertVisible: ${output.newWalletName} diff --git a/src/components/modals/WalletSettingsModal.tsx b/src/components/modals/WalletSettingsModal.tsx index e7af313301e..ce0f3b71b6a 100644 --- a/src/components/modals/WalletSettingsModal.tsx +++ b/src/components/modals/WalletSettingsModal.tsx @@ -157,6 +157,7 @@ export const WalletSettingsModal: React.FC = props => { scroll > = props => { Date: Fri, 21 Aug 2026 15:01:52 -0700 Subject: [PATCH 08/15] fix(maestro): repair C000037 split wallet flow --- maestro/07-wallets/C000037-split-wallets.yaml | 28 ++++++++++--------- .../scenes/CreateWalletEditNameScene.tsx | 3 +- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/maestro/07-wallets/C000037-split-wallets.yaml b/maestro/07-wallets/C000037-split-wallets.yaml index 74e6d602b88..378fc57d017 100644 --- a/maestro/07-wallets/C000037-split-wallets.yaml +++ b/maestro/07-wallets/C000037-split-wallets.yaml @@ -44,18 +44,21 @@ tags: - longPressOn: "My Base" # Verify split option is available and tap it -- tapOn: ".*Split Wallet" +- tapOn: + id: walletListMenu_split # Select Ethereum as target -- assertVisible: Create Wallet From Seed +- assertVisible: Split Wallet - assertVisible: Search Wallets -- tapOn: ".*Ethereum" -- tapOn: Next +- tapOn: + id: "createWalletRow.create-wallet:ethereum-ethereum" +- tapOn: + id: nextButton # Next scene - assertVisible: Split Wallet -- assertVisible: This action creates wallets from pre-existing wallets. -- assertVisible: Tap on wallet to edit name +- assertVisible: EVM-compatible networks share the.*existing address. +- assertVisible: Tap on wallet to edit settings - evalScript: ${output.newETHName = ".*My Ether \\(Split from My Base\\).*"} - assertVisible: ${output.newETHName} @@ -64,21 +67,20 @@ tags: text: ${"ETH.*"} index: 0 - tapOn: - id: "undefined.clearIcon" + id: "walletSettingsNameInput.clearIcon" - inputRandomText ## Unable to target text input field to test changing name # - copyTextFrom: # id: "undefined.textInput" # - evalScript: ${var newETHName = maestro.copiedText} -# - tapOn: Submit -- assertVisible: Submit +# - tapOn: Done +- assertVisible: Done - tapOn: id: "modal-close-button" # Button shares name with scene title -- tapOn: - text: Split Wallet - index: 1 +- tapOn: + id: splitWalletConfirmButton @@ -98,7 +100,7 @@ tags: # - assertVisible: Split Wallet # - assertVisible: This action creates wallets from pre-existing wallets. -# - assertVisible: Tap on wallet to edit name +# - assertVisible: Tap on wallet to edit settings # - evalScript: ${var newBTCName = ".*My Bitcoin \\(Split from My Litecoin\\).*"} # - assertVisible: ${newBTCName} # - tapOn: diff --git a/src/components/scenes/CreateWalletEditNameScene.tsx b/src/components/scenes/CreateWalletEditNameScene.tsx index 456227d9b68..1e891fded53 100644 --- a/src/components/scenes/CreateWalletEditNameScene.tsx +++ b/src/components/scenes/CreateWalletEditNameScene.tsx @@ -441,7 +441,8 @@ const CreateWalletEditNameComponent: React.FC = props => { ) : ( From fb5c9a0da8e2f119ffb9287b6c94d6e7dd4be004 Mon Sep 17 00:00:00 2001 From: EdgeClaws <268039199+EdgeClaws@users.noreply.github.com> Date: Fri, 21 Aug 2026 15:06:46 -0700 Subject: [PATCH 09/15] fix(maestro): select Coreum by stable row id --- maestro/07-wallets/C000036-autodetect-all-networks.yaml | 2 +- maestro/common/import-wallets.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/maestro/07-wallets/C000036-autodetect-all-networks.yaml b/maestro/07-wallets/C000036-autodetect-all-networks.yaml index fe228d3d64b..07b6e4949e0 100644 --- a/maestro/07-wallets/C000036-autodetect-all-networks.yaml +++ b/maestro/07-wallets/C000036-autodetect-all-networks.yaml @@ -24,7 +24,7 @@ tags: # EVMs: Only Sonic and Pulsechain (others tested via regular asset sync) - evalScript: ${ output.wallets = '[ - "Coreum", + "TX", "Osmosis", "Avalanche", "Solana", diff --git a/maestro/common/import-wallets.yaml b/maestro/common/import-wallets.yaml index 0e4239f8a02..5a54504e811 100644 --- a/maestro/common/import-wallets.yaml +++ b/maestro/common/import-wallets.yaml @@ -30,7 +30,7 @@ env: - evalScript: ${output.assetName = output.assetName.replace(/\(/g, '\\(').replace(/\)/g, '\\)')} - tapOn: text: ${".*" + output.assetName} - index: 1 # First index is thesearch bar + index: 1 # First index is the search bar - evalScript: ${output.index++} - tapOn: Next From be61591bbb6bcafe27fca32484fc0b65b6968f87 Mon Sep 17 00:00:00 2001 From: EdgeClaws <268039199+EdgeClaws@users.noreply.github.com> Date: Fri, 21 Aug 2026 15:07:10 -0700 Subject: [PATCH 10/15] fix(maestro): update C000048 split wallet expectations --- maestro/07-wallets/C000048-split-all-evm.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/maestro/07-wallets/C000048-split-all-evm.yaml b/maestro/07-wallets/C000048-split-all-evm.yaml index d4274c6e698..b2be68d87df 100644 --- a/maestro/07-wallets/C000048-split-all-evm.yaml +++ b/maestro/07-wallets/C000048-split-all-evm.yaml @@ -34,7 +34,7 @@ tags: - tapOn: ".*Split Wallet" # Verify split wallet scene -- assertVisible: Create Wallet From Seed +- assertVisible: Split Wallet - assertVisible: Search Wallets # Define expected EVM networks (ordered by appearance) @@ -52,7 +52,6 @@ tags: "Abstract", "Arbitrum One", "Base", - "Botanix Bitcoin", "Celo", "EthereumPoW", "Filecoin FEVM", From 08cf83fca4e370a71ba5dffbda12d1a421b9aa32 Mon Sep 17 00:00:00 2001 From: EdgeClaws <268039199+EdgeClaws@users.noreply.github.com> Date: Fri, 21 Aug 2026 15:07:34 -0700 Subject: [PATCH 11/15] fix(maestro): update C190284 2FA prompt --- maestro/03-login/C190284-2fa-01.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maestro/03-login/C190284-2fa-01.yaml b/maestro/03-login/C190284-2fa-01.yaml index b299bb51ed8..44159ec374c 100644 --- a/maestro/03-login/C190284-2fa-01.yaml +++ b/maestro/03-login/C190284-2fa-01.yaml @@ -23,8 +23,8 @@ tags: visible: "Username and password are correct. This device cannot log in because\ \ it does not have the right 2-factor code." timeout: 15000 -- assertVisible: "Enter Backup Code" -- tapOn: "Enter Backup Code" +- assertVisible: "Enter 2FA code" +- tapOn: "Enter 2FA code" - inputText: ${MAESTRO_EDGE_2FA_BACKUP_CODE} - assertVisible: "Submit" From 2f44f32de209bc96a970d26ee07278cafb6bfac9 Mon Sep 17 00:00:00 2001 From: EdgeClaws <268039199+EdgeClaws@users.noreply.github.com> Date: Fri, 21 Aug 2026 15:07:57 -0700 Subject: [PATCH 12/15] fix(maestro): update C999003 help flow --- maestro/13-settings/C999003-help-logged-in.yaml | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/maestro/13-settings/C999003-help-logged-in.yaml b/maestro/13-settings/C999003-help-logged-in.yaml index 722d742511e..9638d944f57 100644 --- a/maestro/13-settings/C999003-help-logged-in.yaml +++ b/maestro/13-settings/C999003-help-logged-in.yaml @@ -32,12 +32,11 @@ tags: - assertVisible: "Thanks for using Edge!" - assertVisible: "Knowledge Base" - assertVisible: "Live Chat" -- assertVisible: "Submit a Support Ticket" - assertVisible: "Call for Assistance" - assertVisible: "Visit Official Site" - tapOn: "Knowledge Base" - extendedWaitUntil: - visible: "Edge Help Center home page" + visible: ".*Troubleshooting for Edge related issues.*" timeout: 15000 - assertVisible: id: "chevronBack" @@ -48,18 +47,13 @@ tags: - tapOn: "Live Chat" # Ensure it opens to correct page AND chat is open - assertVisible: ".*support\\.edge\\.app.*" -- assertVisible: "Options menu" +- assertVisible: ".*Need Help\\? Reach Out via Our Chat Bubble!.*" +# Call button opens in phone app - launchApp: stopApp: false - extendedWaitUntil: - visible: "Submit a Support Ticket" + visible: "Call for Assistance" timeout: 15000 -- tapOn: "Submit a Support Ticket" -- assertVisible: "Submit a Request" -- tapOn: - id: "chevronBack" -# Call button opens in phone app -- tapOn: "Help" - tapOn: "Call for Assistance" # Optional for iOS simulator (unable to open phone app) - extendedWaitUntil: @@ -78,4 +72,3 @@ tags: id: "chevronBack" - stopApp - From a3804d193481fb73dcc92c41bb6df65274d48947 Mon Sep 17 00:00:00 2001 From: EdgeClaws <268039199+EdgeClaws@users.noreply.github.com> Date: Sat, 22 Aug 2026 21:32:51 -0700 Subject: [PATCH 13/15] fix(maestro): clear password field before relogin --- maestro/01-accounts/C000000-change-password.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/maestro/01-accounts/C000000-change-password.yaml b/maestro/01-accounts/C000000-change-password.yaml index df9573e6d8a..8f006bf40ed 100644 --- a/maestro/01-accounts/C000000-change-password.yaml +++ b/maestro/01-accounts/C000000-change-password.yaml @@ -62,8 +62,9 @@ tags: - pressKey: Enter - assertVisible: Invalid username or password # Ensure new password works +- tapOn: + id: "passwordFormField.clearIcon" - tapOn: Password -- eraseText - inputText: ${SECOND_PASSWORD} - pressKey: Enter From 179cc389d89733cb190df2aef6cbf3d297b38cfd Mon Sep 17 00:00:00 2001 From: EdgeClaws <268039199+EdgeClaws@users.noreply.github.com> Date: Mon, 24 Aug 2026 15:26:11 -0700 Subject: [PATCH 14/15] fix(maestro): use scoped account username --- .../C000001-switch-and-forget-account.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/maestro/01-accounts/C000001-switch-and-forget-account.yaml b/maestro/01-accounts/C000001-switch-and-forget-account.yaml index a903d87ed0d..0b177e974f0 100644 --- a/maestro/01-accounts/C000001-switch-and-forget-account.yaml +++ b/maestro/01-accounts/C000001-switch-and-forget-account.yaml @@ -40,7 +40,7 @@ tags: id: "sideMenuButton" - tapOn: "Logout" - tapOn: "Exit PIN" -- assertVisible: ${USERNAME} +- assertVisible: ${USERNAME1} - tapOn: "Username" - eraseText - inputText: ${USERNAME2} @@ -79,7 +79,7 @@ tags: id: "sideMenuButton" - tapOn: id: "downArrow" -- assertVisible: ${USERNAME} +- assertVisible: ${USERNAME1} - assertVisible: ${USERNAME2} - assertVisible: ${USERNAME3} @@ -89,22 +89,22 @@ tags: index: 0 - assertVisible: ${".*Forget Account.*"} - tapOn: "Cancel" -- assertVisible: ${USERNAME} +- assertVisible: ${USERNAME1} - assertVisible: ${USERNAME2} - assertVisible: ${USERNAME3} # Delete first account - tapOn: id: "sideMenuClose" index: 1 -- assertVisible: ${".*" + USERNAME + ".*"} # Username in confirmation modal +- assertVisible: ${".*" + USERNAME1 + ".*"} # Username in confirmation modal - tapOn: "Forget" -- assertNotVisible: ${USERNAME} +- assertNotVisible: ${USERNAME1} - tapOn: ${USERNAME2} # View, forget, switch accounts from PIN login screen - assertVisible: ${USERNAME2} - tapOn: ${USERNAME2} -- assertNotVisible: ${USERNAME} +- assertNotVisible: ${USERNAME1} - assertVisible: ${USERNAME2} - assertVisible: ${USERNAME3} - tapOn: @@ -153,4 +153,4 @@ tags: - assertNotVisible: id: "userDropdownIcon" -- stopApp \ No newline at end of file +- stopApp From f1201a2a6c75c4a00a813f3f73ff4e2c93eb0c5e Mon Sep 17 00:00:00 2001 From: EdgeClaws <268039199+EdgeClaws@users.noreply.github.com> Date: Tue, 25 Aug 2026 16:34:10 -0700 Subject: [PATCH 15/15] fix(maestro): wait for PIN screen animation --- maestro/03-login/C999002-pin-login.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/maestro/03-login/C999002-pin-login.yaml b/maestro/03-login/C999002-pin-login.yaml index 5f6ce9b00f2..ed0bc4ef5f0 100644 --- a/maestro/03-login/C999002-pin-login.yaml +++ b/maestro/03-login/C999002-pin-login.yaml @@ -33,6 +33,7 @@ tags: - extendedWaitUntil: visible: ${MAESTRO_EDGE_UTXO_USERNAME} timeout: 15000 +- waitForAnimationToEnd - tapOn: ${MAESTRO_EDGE_UTXO_PIN_1} - tapOn: ${MAESTRO_EDGE_UTXO_PIN_2}