From 40417b086aa97bff50a6cb01ba7ef8eb7130d424 Mon Sep 17 00:00:00 2001 From: Davide Brocchetto Date: Wed, 8 Jan 2025 09:53:28 +0100 Subject: [PATCH] test: Swap tests addition (#29442) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** Adding Linea Tests as well as test for getting a quote on Mainnet. To run the tests locally use `yarn playwright test --project=swap` [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/29442?quickstart=1) ## **Related issues** Fixes: ## **Manual testing steps** ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] 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 - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- .../pageObjects/network-controller-page.ts | 19 ++++--- .../shared/pageObjects/signup-page.ts | 4 ++ .../playwright/swap/pageObjects/swap-page.ts | 9 ++- test/e2e/playwright/swap/specs/swap.spec.ts | 55 ++++++++++++++++--- test/e2e/playwright/swap/tenderly-network.ts | 16 +++--- 5 files changed, 79 insertions(+), 24 deletions(-) diff --git a/test/e2e/playwright/shared/pageObjects/network-controller-page.ts b/test/e2e/playwright/shared/pageObjects/network-controller-page.ts index cc496f2c9a36..e2116bcac676 100644 --- a/test/e2e/playwright/shared/pageObjects/network-controller-page.ts +++ b/test/e2e/playwright/shared/pageObjects/network-controller-page.ts @@ -24,8 +24,6 @@ export class NetworkController { readonly dismissBtn: Locator; - readonly networkList: Locator; - readonly networkListEdit: Locator; readonly rpcName: Locator; @@ -39,9 +37,6 @@ export class NetworkController { constructor(page: Page) { this.page = page; this.networkDisplay = this.page.getByTestId('network-display'); - this.networkList = this.page.getByTestId( - 'network-list-item-options-button-0x1', - ); this.networkListEdit = this.page.getByTestId( 'network-list-item-options-edit', ); @@ -69,9 +64,14 @@ export class NetworkController { }) { let rpcName = options.name; await this.networkDisplay.click(); - if (options.name === Tenderly.Mainnet.name) { + if ( + options.name === Tenderly.Mainnet.name || + options.name === Tenderly.Linea.name + ) { rpcName = options.rpcName; - await this.networkList.click(); + await this.page + .getByTestId(`network-list-item-options-button-${options.chainID}`) + .click(); await this.networkListEdit.click(); } else { await this.addNetworkButton.click(); @@ -82,7 +82,10 @@ export class NetworkController { await this.networkRpc.fill(options.url); await this.rpcName.fill(rpcName); await this.addURLBtn.click(); - if (options.name !== Tenderly.Mainnet.name) { + if ( + options.name !== Tenderly.Mainnet.name && + options.name !== Tenderly.Linea.name + ) { await this.networkChainId.fill(options.chainID); } await this.networkTicker.fill(options.symbol); diff --git a/test/e2e/playwright/shared/pageObjects/signup-page.ts b/test/e2e/playwright/shared/pageObjects/signup-page.ts index 28909f23ba20..692ca2ea70a4 100644 --- a/test/e2e/playwright/shared/pageObjects/signup-page.ts +++ b/test/e2e/playwright/shared/pageObjects/signup-page.ts @@ -49,6 +49,8 @@ export class SignUpPage { readonly skipSrpBackupBtn: Locator; + readonly popOverBtn: Locator; + constructor(page: Page) { this.page = page; this.getStartedBtn = page.locator('button:has-text("Get started")'); @@ -77,6 +79,7 @@ export class SignUpPage { this.nextBtn = page.getByTestId('pin-extension-next'); this.agreeBtn = page.locator('button:has-text("I agree")'); this.enableBtn = page.locator('button:has-text("Enable")'); + this.popOverBtn = page.getByTestId('popover-close'); } async importWallet() { @@ -114,5 +117,6 @@ export class SignUpPage { await this.gotItBtn.click(); await this.nextBtn.click(); await this.doneBtn.click(); + await this.popOverBtn.click(); } } diff --git a/test/e2e/playwright/swap/pageObjects/swap-page.ts b/test/e2e/playwright/swap/pageObjects/swap-page.ts index c10536d37f05..2f92597a2620 100644 --- a/test/e2e/playwright/swap/pageObjects/swap-page.ts +++ b/test/e2e/playwright/swap/pageObjects/swap-page.ts @@ -63,7 +63,12 @@ export class SwapPage { ); } - async enterQuote(options: { from?: string; to: string; qty: string }) { + async enterQuote(options: { + from?: string; + to: string; + qty: string; + checkBalance: boolean; + }) { // Enter source token const native = await this.page.$(`text=/${options.from}/`); if (!native && options.from) { @@ -75,7 +80,7 @@ export class SwapPage { .locator('[class*="balance"]') .first() .textContent(); - if (balanceString) { + if (balanceString && options.checkBalance) { if (parseFloat(balanceString.split(' ')[1]) <= parseFloat(options.qty)) { await this.goBack(); // not enough balance so cancel out diff --git a/test/e2e/playwright/swap/specs/swap.spec.ts b/test/e2e/playwright/swap/specs/swap.spec.ts index ec9cd73858da..bbfbfa3d8c98 100644 --- a/test/e2e/playwright/swap/specs/swap.spec.ts +++ b/test/e2e/playwright/swap/specs/swap.spec.ts @@ -14,6 +14,7 @@ let swapPage: SwapPage; let networkController: NetworkController; let walletPage: WalletPage; let activityListPage: ActivityListPage; +let wallet: ethers.Wallet; const testSet = [ { @@ -23,6 +24,20 @@ const testSet = [ destination: 'DAI', network: Tenderly.Mainnet, }, + { + quantity: '.5', + source: 'ETH', + type: 'native', + destination: 'DAI', + network: Tenderly.Linea, + }, + { + quantity: '10', + source: 'DAI', + type: 'unapproved', + destination: 'USDC', + network: Tenderly.Linea, + }, { quantity: '50', source: 'DAI', @@ -61,9 +76,6 @@ test.beforeAll( const page = await extension.initExtension(); page.setDefaultTimeout(15000); - const wallet = ethers.Wallet.createRandom(); - await addFundsToAccount(Tenderly.Mainnet.url, wallet.address); - const signUp = new SignUpPage(page); await signUp.createWallet(); @@ -71,13 +83,41 @@ test.beforeAll( swapPage = new SwapPage(page); activityListPage = new ActivityListPage(page); walletPage = new WalletPage(page); - - await networkController.addCustomNetwork(Tenderly.Mainnet); - await walletPage.importAccount(wallet.privateKey); - expect(walletPage.accountMenu).toHaveText('Account 2', { timeout: 30000 }); }, ); +test(`Get quote on Mainnet Network`, async () => { + await walletPage.selectSwapAction(); + await walletPage.page.waitForTimeout(3000); + await swapPage.enterQuote({ + from: 'ETH', + to: 'USDC', + qty: '.01', + checkBalance: false, + }); + await walletPage.page.waitForTimeout(3000); + const quoteFound = await swapPage.waitForQuote(); + expect(quoteFound).toBeTruthy(); + await swapPage.goBack(); +}); + +test(`Add Custom Networks and import test account`, async () => { + let response; + wallet = ethers.Wallet.createRandom(); + + response = await addFundsToAccount(Tenderly.Mainnet.url, wallet.address); + expect(response.error).toBeUndefined(); + + response = await addFundsToAccount(Tenderly.Linea.url, wallet.address); + expect(response.error).toBeUndefined(); + + await networkController.addCustomNetwork(Tenderly.Linea); + await networkController.addCustomNetwork(Tenderly.Mainnet); + + await walletPage.importAccount(wallet.privateKey); + expect(walletPage.accountMenu).toHaveText('Account 2', { timeout: 30000 }); +}); + testSet.forEach((options) => { test(`should swap ${options.type} token ${options.source} to ${options.destination} on ${options.network.name}'`, async () => { await walletPage.selectTokenWallet(); @@ -94,6 +134,7 @@ testSet.forEach((options) => { from: options.source, to: options.destination, qty: options.quantity, + checkBalance: true, }); if (quoteEntered) { diff --git a/test/e2e/playwright/swap/tenderly-network.ts b/test/e2e/playwright/swap/tenderly-network.ts index 996dee47a81a..3b6ef8b8a62b 100644 --- a/test/e2e/playwright/swap/tenderly-network.ts +++ b/test/e2e/playwright/swap/tenderly-network.ts @@ -1,12 +1,11 @@ import axios from 'axios'; -import log from 'loglevel'; export const Tenderly = { Mainnet: { name: 'Ethereum Mainnet', rpcName: 'Tenderly - Mainnet', url: 'https://virtual.mainnet.rpc.tenderly.co/03bb8912-7505-4856-839f-52819a26d0cd', - chainID: '1', + chainID: '0x1', symbol: 'ETH', }, Optimism: { @@ -23,6 +22,13 @@ export const Tenderly = { chainID: '137', symbol: 'ETH', }, + Linea: { + name: 'Linea', + rpcName: '', + url: 'https://virtual.linea.rpc.tenderly.co/2c429ceb-43db-45bc-9d84-21a40d21e0d2', + chainID: '0xe708', + symbol: 'ETH', + }, }; export async function addFundsToAccount( @@ -42,9 +48,5 @@ export async function addFundsToAccount( }, }); - if (response.data.error) { - log.error( - `\tERROR: RROR: Failed to add funds to Tenderly VirtualTestNet\n${response.data.error}`, - ); - } + return response.data; }