From 1cc54f699f1f445cbe773da466f48f45a900aa5d Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Tue, 25 Jun 2024 10:12:57 -0500 Subject: [PATCH] test: add e2e for scenario where `wallet_switchEthereumChain` call is canceled with other confirmations queued behind it (#25341) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** Add an e2e to catch regressions similar to the bug identified in[ this patch/cherry-pick fix](https://github.com/MetaMask/metamask-extension/pull/25339) to the v12.0.0 RC branch We had an e2e for a similar flow but where the `wallet_switchEthereumChain` confirmation was confirmed rather than cancelled. The bug occurred when the confirmation was cancelled and so this test handles that case. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/25341?quickstart=1) ## **Related issues** See: https://consensys.slack.com/archives/CTQAGKY5V/p1718385169900809?thread_ts=1718140104.578969&cid=CTQAGKY5V ## **Manual testing steps** N/A ## **Screenshots/Recordings** N/A ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- .../dapp1-switch-dapp2-send.spec.js | 156 +++++++++++++++++- 1 file changed, 155 insertions(+), 1 deletion(-) diff --git a/test/e2e/tests/request-queuing/dapp1-switch-dapp2-send.spec.js b/test/e2e/tests/request-queuing/dapp1-switch-dapp2-send.spec.js index 02f496f68235..6cab2f88d96b 100644 --- a/test/e2e/tests/request-queuing/dapp1-switch-dapp2-send.spec.js +++ b/test/e2e/tests/request-queuing/dapp1-switch-dapp2-send.spec.js @@ -12,7 +12,7 @@ const { } = require('../../helpers'); describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () { - it('should queue send tx after switch network confirmation.', async function () { + it('should queue send tx after switch network confirmation and transaction should target the correct network after switch is confirmed', async function () { const port = 8546; const chainId = 1338; await withFixtures( @@ -165,4 +165,158 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () { }, ); }); + + it('should queue send tx after switch network confirmation and transaction should target the correct network after switch is cancelled.', async function () { + const port = 8546; + const chainId = 1338; + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkControllerTripleGanache() + .withPreferencesControllerUseRequestQueueEnabled() + .withSelectedNetworkControllerPerDomain() + .build(), + dappOptions: { numberOfDapps: 2 }, + ganacheOptions: { + ...defaultGanacheOptions, + concurrent: [ + { + port, + chainId, + ganacheOptions2: defaultGanacheOptions, + }, + { + port: 7777, + chainId: 1000, + ganacheOptions2: defaultGanacheOptions, + }, + ], + }, + title: this.test.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + + // Open Dapp One + await openDapp(driver, undefined, DAPP_URL); + + // Connect to dapp + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); + + await driver.delay(regularDelayMs); + + await switchToNotificationWindow(driver); + + await driver.clickElement({ + text: 'Next', + tag: 'button', + css: '[data-testid="page-container-footer-next"]', + }); + + await driver.clickElement({ + text: 'Confirm', + tag: 'button', + css: '[data-testid="page-container-footer-next"]', + }); + + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + + // Network Selector + await driver.clickElement('[data-testid="network-display"]'); + + // Switch to second network + await driver.clickElement({ + text: 'Localhost 8546', + css: 'p', + }); + + // Wait for the first dapp's connect confirmation to disappear + await driver.waitUntilXWindowHandles(2); + + // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them. + // Open Dapp Two + await openDapp(driver, undefined, DAPP_ONE_URL); + + // Connect to dapp 2 + await driver.findClickableElement({ text: 'Connect', tag: 'button' }); + await driver.clickElement('#connectButton'); + + await driver.delay(regularDelayMs); + + await switchToNotificationWindow(driver, 4); + + await driver.clickElement({ + text: 'Next', + tag: 'button', + css: '[data-testid="page-container-footer-next"]', + }); + + await driver.clickElement({ + text: 'Confirm', + tag: 'button', + css: '[data-testid="page-container-footer-next"]', + }); + + await driver.switchToWindowWithUrl(DAPP_URL); + + // switchEthereumChain request + const switchEthereumChainRequest = JSON.stringify({ + jsonrpc: '2.0', + method: 'wallet_switchEthereumChain', + params: [{ chainId: '0x3e8' }], + }); + + // Initiate switchEthereumChain on Dapp Two + await driver.executeScript( + `window.ethereum.request(${switchEthereumChainRequest})`, + ); + + await driver.switchToWindowWithUrl(DAPP_ONE_URL); + + await driver.clickElement('#sendButton'); + + await switchToNotificationWindow(driver, 4); + await driver.findClickableElements({ + text: 'Cancel', + tag: 'button', + }); + + await driver.clickElement({ text: 'Cancel', tag: 'button' }); + + // Wait for switch confirmation to close then tx confirmation to show. + await driver.waitUntilXWindowHandles(3); + + await switchToNotificationWindow(driver, 4); + + // Check correct network on the send confirmation. + await driver.findElement({ + css: '[data-testid="network-display"]', + text: 'Localhost 8546', + }); + + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + // Switch back to the extension + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + + await driver.clickElement( + '[data-testid="account-overview__activity-tab"]', + ); + + // Check for transaction + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .activity-list-item', + ); + return confirmedTxes.length === 1; + }, 10000); + }, + ); + }); });