diff --git a/test/e2e/flask/multichain-api/evm/wallet_invokeMethod.spec.ts b/test/e2e/flask/multichain-api/evm/wallet_invokeMethod.spec.ts index 63b8c36e5043..f3af1014396b 100644 --- a/test/e2e/flask/multichain-api/evm/wallet_invokeMethod.spec.ts +++ b/test/e2e/flask/multichain-api/evm/wallet_invokeMethod.spec.ts @@ -29,6 +29,11 @@ describe('Multichain API', function () { const DEFAULT_INITIAL_BALANCE_HEX = convertETHToHexGwei( DEFAULT_LOCAL_NODE_ETH_BALANCE_DEC, ); + const SCOPE_TO_NETWORK_NAME: Record = { + 'eip155:1337': 'Localhost 8545', + 'eip155:1338': 'Localhost 8546', + 'eip155:1000': 'Localhost 7777', + }; describe('Calling `wallet_invokeMethod` with permissions granted from EIP-1193 provider', function () { it('should allow the request to be made', async function () { @@ -175,48 +180,66 @@ describe('Multichain API', function () { } await testDapp.clickInvokeAllMethodsButton(); - // first confirmation page should display Account 1 as sender account - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - const confirmation = new TransactionConfirmation(driver); - await confirmation.checkPageIsLoaded(); - assert.equal( - await confirmation.checkIsSenderAccountDisplayed('Account 1'), - true, - ); - await confirmation.clickFooterConfirmButton(); + // Build expected confirmations + const expectedConfirmations: { + account: string; + network: string; + }[] = []; + for (const [i, scope] of GANACHE_SCOPES.entries()) { + expectedConfirmations.push({ + account: + i === INDEX_FOR_ALTERNATE_ACCOUNT ? 'Account 2' : 'Account 1', + network: SCOPE_TO_NETWORK_NAME[scope], + }); + } - // check which account confirmation page is displayed on second screen + const resultConfirmations: { account: string; network: string }[] = + []; await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await confirmation.checkPageIsLoaded(); - const screenForAccount2 = - await confirmation.checkIsSenderAccountDisplayed('Account 2'); - if (screenForAccount2) { - await confirmation.checkNetworkIsDisplayed('Localhost 8546'); - await confirmation.clickFooterConfirmButton(); - - // third confirmation page should display Account 1 as sender account - await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await confirmation.checkPageIsLoaded(); - assert.equal( - await confirmation.checkIsSenderAccountDisplayed('Account 1'), - true, - ); - await confirmation.checkNetworkIsDisplayed('Localhost 7777'); - await confirmation.clickFooterConfirmButtonAndAndWaitForWindowToClose(); - } else { - await confirmation.checkNetworkIsDisplayed('Localhost 7777'); - await confirmation.clickFooterConfirmButton(); + const firstConfirmation = new TransactionConfirmation(driver); + await firstConfirmation.checkPageIsLoaded(); + let currentAccount = await firstConfirmation.getSenderAccountName(); + let currentNetwork = await firstConfirmation.getNetworkName(); + await firstConfirmation.clickFooterConfirmButton(); + resultConfirmations.push({ + account: currentAccount, + network: currentNetwork, + }); - // third confirmation page should display Account 2 as sender account + // Collect actual confirmations from each confirmation screen + for (let i = 0; i < GANACHE_SCOPES.length - 1; i++) { await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + const confirmation = new TransactionConfirmation(driver); await confirmation.checkPageIsLoaded(); - assert.equal( - await confirmation.checkIsSenderAccountDisplayed('Account 2'), - true, - ); - await confirmation.checkNetworkIsDisplayed('Localhost 8546'); - await confirmation.clickFooterConfirmButtonAndAndWaitForWindowToClose(); + await confirmation.checkNetworkIsNotDisplayed(currentNetwork); + currentAccount = await confirmation.getSenderAccountName(); + currentNetwork = await confirmation.getNetworkName(); + resultConfirmations.push({ + account: currentAccount, + network: currentNetwork, + }); + + // Confirm the transaction except for the last one + if (i < GANACHE_SCOPES.length - 2) { + await confirmation.clickFooterConfirmButton(); + } else { + await confirmation.clickFooterConfirmButtonAndAndWaitForWindowToClose(); + } } + + // Verify all expected confirmations were found + const hasAllExpectedConfirmations = expectedConfirmations.every( + (expectedConf) => + resultConfirmations.find( + (resultConf) => + resultConf.account === expectedConf.account && + resultConf.network === expectedConf.network, + ), + ); + assert.ok( + hasAllExpectedConfirmations, + 'Not all expected confirmation screens were found', + ); }, ); }); @@ -260,24 +283,64 @@ describe('Multichain API', function () { await testDapp.clickInvokeAllMethodsButton(); const totalNumberOfScopes = GANACHE_SCOPES.length; - for (let i = 0; i < totalNumberOfScopes; i++) { + const expectedNetworks = [ + 'Localhost 8545', + 'Localhost 8546', + 'Localhost 7777', + ]; + const currentNetworks = new Set(); + + // Get the network name from the first confirmation screen + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + const firstConfirmation = new TransactionConfirmation(driver); + await firstConfirmation.checkPageIsLoaded(); + let currentNetworkName = await firstConfirmation.getNetworkName(); + await firstConfirmation.checkPageNumbers(1, totalNumberOfScopes); + await firstConfirmation.clickFooterConfirmButton(); + currentNetworks.add(currentNetworkName); + + for (let i = 0; i < totalNumberOfScopes - 1; i++) { await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); const confirmation = new TransactionConfirmation(driver); await confirmation.checkPageIsLoaded(); - if (i < totalNumberOfScopes - 1) { - // if pending tx's, verify navigation and confirm - await confirmation.checkPageNumbers(1, totalNumberOfScopes - i); - await confirmation.checkNetworkIsDisplayed( - `Localhost ${8545 + i}`, + + // Check that the network is different from the previous confirmation screen to ensure that we’ve switched to a new confirmation screen + await confirmation.checkNetworkIsNotDisplayed(currentNetworkName); + + // Get the network name from the current confirmation screen + currentNetworkName = await confirmation.getNetworkName(); + + // Verify this network hasn't been seen before and is expected + assert( + !currentNetworks.has(currentNetworkName), + `Network ${currentNetworkName} appeared more than once`, + ); + assert( + expectedNetworks.includes(currentNetworkName), + `Unexpected network: ${currentNetworkName}`, + ); + currentNetworks.add(currentNetworkName); + + if (i < totalNumberOfScopes - 2) { + // First 2 confirmations: verify navigation and confirm + await confirmation.checkPageNumbers( + 1, + totalNumberOfScopes - i - 1, ); await confirmation.clickFooterConfirmButton(); } else { - await confirmation.checkNetworkIsDisplayed('Localhost 7777'); - // if no pending tx's, confirm and wait for window to close + // Last confirmation: confirm and wait for window to close await confirmation.clickFooterConfirmButtonAndAndWaitForWindowToClose(); } } + // Verify all expected networks were seen + assert.equal( + currentNetworks.size, + expectedNetworks.length, + 'Not all networks were confirmed', + ); + await driver.switchToWindowWithTitle( WINDOW_TITLES.ExtensionInFullScreenView, ); diff --git a/test/e2e/page-objects/pages/confirmations/redesign/transaction-confirmation.ts b/test/e2e/page-objects/pages/confirmations/redesign/transaction-confirmation.ts index e91106b318c8..b11e456a773d 100644 --- a/test/e2e/page-objects/pages/confirmations/redesign/transaction-confirmation.ts +++ b/test/e2e/page-objects/pages/confirmations/redesign/transaction-confirmation.ts @@ -70,13 +70,16 @@ class TransactionConfirmation extends Confirmation { private readonly gasLimitInput: RawLocator = '[data-testid="gas-limit-input"]'; + private readonly headerAccountName: RawLocator = + '[data-testid="header-account-name"]'; + + private readonly networkName: RawLocator = + '[data-testid="confirmation__details-network-name"]'; + private readonly saveButton: RawLocator = { tag: 'button', text: 'Save' }; private readonly senderAccount: RawLocator = '[data-testid="sender-address"]'; - private readonly transactionDetails: RawLocator = - '[data-testid="confirmation__token-details-section"]'; - private readonly walletInitiatedHeadingTitle: RawLocator = { css: 'h4', text: tEn('review') as string, @@ -215,6 +218,16 @@ class TransactionConfirmation extends Confirmation { }); } + async checkHeaderAccountNameIsDisplayed(account: string): Promise { + console.log( + `Checking header account name ${account} on transaction confirmation page.`, + ); + await this.driver.waitForSelector({ + css: this.headerAccountName, + text: account, + }); + } + async checkPaidByMetaMask() { await this.driver.findElement({ css: this.paidByMetaMaskNotice, @@ -223,26 +236,18 @@ class TransactionConfirmation extends Confirmation { } /** - * Checks if the sender account is displayed in the transaction confirmation page. + * Checks that the sender account is displayed on the transaction confirmation page. * * @param account - The sender account to check. */ - async checkIsSenderAccountDisplayed(account: string): Promise { + async checkSenderAccountIsDisplayed(account: string): Promise { console.log( `Checking sender account ${account} on transaction confirmation page.`, ); - try { - await this.driver.waitForSelector({ - css: this.senderAccount, - text: account, - }); - return true; - } catch (err) { - console.log( - `Sender account ${account} is not displayed on transaction confirmation page.`, - ); - return false; - } + await this.driver.waitForSelector({ + css: this.senderAccount, + text: account, + }); } /** @@ -259,11 +264,23 @@ class TransactionConfirmation extends Confirmation { `Checking network ${network} is displayed on transaction confirmation page.`, ); await this.driver.waitForSelector({ - css: this.transactionDetails, + css: this.networkName, text: network, }); } + async checkNetworkIsNotDisplayed(network: string): Promise { + console.log( + `Checking network ${network} is not displayed on transaction confirmation page.`, + ); + await this.driver.assertElementNotPresent( + { css: this.networkName, text: network }, + { + waitAtLeastGuard: 1000, + }, + ); + } + async checkNoAlertMessageIsDisplayed() { console.log( `Checking no alert message is displayed on transaction confirmation page.`, @@ -355,6 +372,45 @@ class TransactionConfirmation extends Confirmation { await this.driver.fill(this.customNonceInput, nonce); } + /** + * Gets the network name displayed on the transaction confirmation page. + * + * IMPORTANT: Make sure the transaction confirmation screen is fully loaded + * before calling this method to avoid race conditions, as the network name element + * might not be present or updated correctly immediately after navigation. + * + * @returns The network name. + */ + async getNetworkName(): Promise { + const networkNameElement = await this.driver.findElement(this.networkName); + const networkName = await networkNameElement.getText(); + console.log( + 'Current network name displayed on transaction confirmation page: ', + networkName, + ); + return networkName; + } + + /** + * Gets the sender account name displayed on the transaction confirmation page. + * + * IMPORTANT: Make sure the transaction confirmation screen is fully loaded + * before calling this method to avoid race conditions. + * + * @returns The sender account name. + */ + async getSenderAccountName(): Promise { + const senderAccountElement = await this.driver.findElement( + this.senderAccount, + ); + const senderAccountName = await senderAccountElement.getText(); + console.log( + 'Current sender account name displayed on transaction confirmation page: ', + senderAccountName, + ); + return senderAccountName; + } + async setCustomNonce(nonce: string) { await this.clickCustomNonceButton(); await this.fillCustomNonce(nonce); diff --git a/test/e2e/tests/confirmations/transactions/metrics.spec.ts b/test/e2e/tests/confirmations/transactions/metrics.spec.ts index 866be171eaf3..6e43f634f3bf 100644 --- a/test/e2e/tests/confirmations/transactions/metrics.spec.ts +++ b/test/e2e/tests/confirmations/transactions/metrics.spec.ts @@ -69,7 +69,7 @@ describe('Metrics', function () { const transactionConfirmation = new TransactionConfirmation(driver); // verify UI before clicking advanced details to give time for the Transaction Added event to be emitted without Advanced Details being displayed await transactionConfirmation.checkPageIsLoaded(); - await transactionConfirmation.checkIsSenderAccountDisplayed( + await transactionConfirmation.checkHeaderAccountNameIsDisplayed( 'Account 1', ); await transactionConfirmation.checkGasFeeSymbol('ETH'); diff --git a/ui/pages/confirmations/components/confirm/info/__snapshots__/info.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/__snapshots__/info.test.tsx.snap index d900b9aed0be..72212953e637 100644 --- a/ui/pages/confirmations/components/confirm/info/__snapshots__/info.test.tsx.snap +++ b/ui/pages/confirmations/components/confirm/info/__snapshots__/info.test.tsx.snap @@ -1883,6 +1883,7 @@ exports[`Info renders info section for typed sign request with permission 1`] =

Goerli

diff --git a/ui/pages/confirmations/components/confirm/info/native-transfer/__snapshots__/native-transfer.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/native-transfer/__snapshots__/native-transfer.test.tsx.snap index 1efbd7cfae75..ebcfa82d0275 100644 --- a/ui/pages/confirmations/components/confirm/info/native-transfer/__snapshots__/native-transfer.test.tsx.snap +++ b/ui/pages/confirmations/components/confirm/info/native-transfer/__snapshots__/native-transfer.test.tsx.snap @@ -204,6 +204,7 @@ exports[`NativeTransferInfo renders correctly 1`] = `

Goerli

diff --git a/ui/pages/confirmations/components/confirm/info/nft-token-transfer/__snapshots__/nft-token-transfer.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/nft-token-transfer/__snapshots__/nft-token-transfer.test.tsx.snap index bb0f8bc2815e..ab50d6357507 100644 --- a/ui/pages/confirmations/components/confirm/info/nft-token-transfer/__snapshots__/nft-token-transfer.test.tsx.snap +++ b/ui/pages/confirmations/components/confirm/info/nft-token-transfer/__snapshots__/nft-token-transfer.test.tsx.snap @@ -234,6 +234,7 @@ exports[`NFTTokenTransferInfo renders correctly 1`] = `

Goerli

diff --git a/ui/pages/confirmations/components/confirm/info/shared/network-row/network-row.tsx b/ui/pages/confirmations/components/confirm/info/shared/network-row/network-row.tsx index 4bc87f13a71a..a2d6aeb641ba 100644 --- a/ui/pages/confirmations/components/confirm/info/shared/network-row/network-row.tsx +++ b/ui/pages/confirmations/components/confirm/info/shared/network-row/network-row.tsx @@ -64,7 +64,11 @@ export const NetworkRow = ({ name={networkName} style={{ borderWidth: 0 }} /> - + {networkName} diff --git a/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-details-section.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-details-section.test.tsx.snap index ac44d47b4aca..0661223cdd71 100644 --- a/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-details-section.test.tsx.snap +++ b/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-details-section.test.tsx.snap @@ -34,6 +34,7 @@ exports[`TokenDetailsSection renders correctly 1`] = `

Goerli

diff --git a/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-transfer.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-transfer.test.tsx.snap index 8714d5ce5aba..1904bc9a9d1b 100644 --- a/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-transfer.test.tsx.snap +++ b/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-transfer.test.tsx.snap @@ -215,6 +215,7 @@ exports[`TokenTransferInfo renders correctly 1`] = `

Goerli