From c5367d0cff4faf94fb3fd2fdac200a400fe659a9 Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Tue, 17 Dec 2024 17:54:24 +0000 Subject: [PATCH 01/16] migrate test to ts and POM --- .../page-objects/pages/dialog/add-tokens.ts | 36 ++++++ test/e2e/page-objects/pages/dialog/dialog.ts | 20 +++ .../e2e/page-objects/pages/home/asset-list.ts | 18 +++ test/e2e/page-objects/pages/test-dapp.ts | 43 +++++++ .../tests/tokens/add-multiple-tokens.spec.js | 114 ------------------ .../tests/tokens/add-multiple-tokens.spec.ts | 68 +++++++++++ 6 files changed, 185 insertions(+), 114 deletions(-) create mode 100644 test/e2e/page-objects/pages/dialog/add-tokens.ts create mode 100644 test/e2e/page-objects/pages/dialog/dialog.ts delete mode 100644 test/e2e/tests/tokens/add-multiple-tokens.spec.js create mode 100644 test/e2e/tests/tokens/add-multiple-tokens.spec.ts diff --git a/test/e2e/page-objects/pages/dialog/add-tokens.ts b/test/e2e/page-objects/pages/dialog/add-tokens.ts new file mode 100644 index 000000000000..1c728e5bae5e --- /dev/null +++ b/test/e2e/page-objects/pages/dialog/add-tokens.ts @@ -0,0 +1,36 @@ +import { Driver } from '../../../webdriver/driver'; +import { strict as assert } from 'assert'; + + +class AddTokensModal { + protected driver: Driver; + + private addTokenButton = { text: 'Add token', tag: 'button' }; + + private tokenListItem = '.confirm-add-suggested-token__token-list-item'; + + constructor(driver: Driver) { + this.driver = driver; + } + + /** + * Checks the count of suggested tokens. + * + * @param expectedTokenCount - The expected count of suggested tokens. + */ + async check_SuggestedTokensCount(expectedTokenCount: number) { + const multipleSuggestedTokens = await this.driver.findElements( + this.tokenListItem, + ); + + // Confirm the expected number of tokens are present as suggested token list + assert.equal(multipleSuggestedTokens.length, expectedTokenCount); + } + + async confirmAddTokens() { + await this.driver.findClickableElement(this.addTokenButton); + await this.driver.clickElement(this.addTokenButton); + } +} + +export default AddTokensModal; diff --git a/test/e2e/page-objects/pages/dialog/dialog.ts b/test/e2e/page-objects/pages/dialog/dialog.ts new file mode 100644 index 000000000000..9762e2a892cd --- /dev/null +++ b/test/e2e/page-objects/pages/dialog/dialog.ts @@ -0,0 +1,20 @@ +import { Driver } from '../../../webdriver/driver'; +import { strict as assert } from 'assert'; + +class GenericConfirmCancelDialog { + protected driver: Driver; + + constructor(driver: Driver) { + this.driver = driver; + } + + async clickConfirm() { + await this.driver.clickElement({ text: 'Confirm', tag: 'button' }) + } + + async clickCancel() { + await this.driver.clickElement({ text: 'Confirm', tag: 'button' }) + } +} + +export default GenericConfirmCancelDialog; diff --git a/test/e2e/page-objects/pages/home/asset-list.ts b/test/e2e/page-objects/pages/home/asset-list.ts index db9367991bf7..2cb33a69f81e 100644 --- a/test/e2e/page-objects/pages/home/asset-list.ts +++ b/test/e2e/page-objects/pages/home/asset-list.ts @@ -204,6 +204,24 @@ class AssetListPage { }); } + /** + * This function checks if the specified token is displayed in the token list by its name. + * + * @param tokenName - The name of the token to check for. + * @returns A promise that resolves if the specified token is displayed. + */ + async check_tokenIsDisplayed(tokenName: string): Promise { + console.log(`Waiting for token ${tokenName} to be displayed`); + await this.driver.wait(async () => { + const tokenIsDisplayed = await this.driver.findElement({ + text: tokenName, + tag: 'p', + }); + return tokenIsDisplayed !== null; + }, 10000); + console.log(`Token ${tokenName} is displayed.`); + } + /** * This function checks if the specified number of token items is displayed in the token list. * diff --git a/test/e2e/page-objects/pages/test-dapp.ts b/test/e2e/page-objects/pages/test-dapp.ts index ef5aca0c6bf7..0578734302e9 100644 --- a/test/e2e/page-objects/pages/test-dapp.ts +++ b/test/e2e/page-objects/pages/test-dapp.ts @@ -8,6 +8,11 @@ const DAPP_URL = `http://${DAPP_HOST_ADDRESS}`; class TestDapp { private driver: Driver; + private readonly addTokensToWalletButton = { + text: 'Add Token(s) to Wallet', + tag: 'button', + }; + private readonly confirmDepositButton = '[data-testid="confirm-footer-button"]'; @@ -38,6 +43,8 @@ class TestDapp { private readonly simpleSendButton = '#sendButton'; + private readonly erc20TokenAddresses = '#erc20TokenAddresses'; + private readonly erc721MintButton = '#mintButton'; private readonly erc721TransferFromButton = '#transferFromButton'; @@ -177,6 +184,11 @@ class TestDapp { private erc20TokenTransferButton = '#transferTokens'; + private createTokenButton = { + text: 'Create Token', + tag: 'button', + }; + constructor(driver: Driver) { this.driver = driver; } @@ -221,6 +233,10 @@ class TestDapp { }); } + public async clickAddTokenToWallet() { + await this.driver.clickElement(this.addTokensToWalletButton); + } + async clickSimpleSendButton() { await this.driver.clickElement(this.simpleSendButton); } @@ -321,6 +337,15 @@ class TestDapp { }); } + /** + * Scrolls to the create token button and clicks it. + */ + public async findAndClickCreateToken() { + const createTokenElement = await this.driver.findElement(this.createTokenButton); + await this.driver.scrollToElement(createTokenElement); + await this.driver.clickElement(this.createTokenButton); + } + /** * Verifies the accounts connected to the test dapp. * @@ -577,6 +602,24 @@ class TestDapp { }); } + /** + * Checks the count of token addresses. + * + * @param expectedCount - The expected count of token addresses. + */ + async check_TokenAddressesCount(expectedCount: number) { + console.log(`checking token addresses count: ${expectedCount}`); + await this.driver.wait(async () => { + const tokenAddressesElement = await this.driver.findElement( + this.erc20TokenAddresses, + ); + const tokenAddresses = await tokenAddressesElement.getText(); + const addresses = tokenAddresses.split(',').filter(Boolean); + + return addresses.length === expectedCount; + }, 10000); + } + async verify_successSignTypedDataV4Result(result: string) { await this.driver.waitForSelector({ css: this.signTypedDataV4Result, diff --git a/test/e2e/tests/tokens/add-multiple-tokens.spec.js b/test/e2e/tests/tokens/add-multiple-tokens.spec.js deleted file mode 100644 index bc6ea5e6f2c0..000000000000 --- a/test/e2e/tests/tokens/add-multiple-tokens.spec.js +++ /dev/null @@ -1,114 +0,0 @@ -const { strict: assert } = require('assert'); -const { - withFixtures, - defaultGanacheOptions, - openDapp, - switchToNotificationWindow, - WINDOW_TITLES, - DAPP_URL, - unlockWallet, -} = require('../../helpers'); -const FixtureBuilder = require('../../fixture-builder'); - -describe('Multiple ERC20 Watch Asset', function () { - // TODO: This assertion will change once the method is fixed. - it('should show multiple erc20 watchAsset token list, only confirms one bug', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() - .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - }, - async ({ driver }) => { - await unlockWallet(driver); - - await openDapp(driver, undefined, DAPP_URL); - - // Create Token 1 - const createToken = await driver.findElement({ - text: 'Create Token', - tag: 'button', - }); - await driver.scrollToElement(createToken); - await driver.clickElement({ text: 'Create Token', tag: 'button' }); - await switchToNotificationWindow(driver); - await driver.findClickableElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // Wait for token 1 address to populate in dapp - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.wait(async () => { - const tokenAddressesElement = await driver.findElement( - '#erc20TokenAddresses', - ); - const tokenAddresses = await tokenAddressesElement.getText(); - return tokenAddresses !== ''; - }, 10000); - - // Create Token 2 - await driver.clickElement({ text: 'Create Token', tag: 'button' }); - await switchToNotificationWindow(driver); - await driver.findClickableElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // Wait for token 2 address to populate in dapp - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.wait(async () => { - const tokenAddressesElement = await driver.findElement( - '#erc20TokenAddresses', - ); - const tokenAddresses = await tokenAddressesElement.getText(); - return tokenAddresses.split(',').length === 2; - }, 10000); - - // Create Token 3 - await driver.clickElement({ text: 'Create Token', tag: 'button' }); - await switchToNotificationWindow(driver); - await driver.findClickableElement({ text: 'Confirm', tag: 'button' }); - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - - // Wait for token 3 address to populate in dapp - await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await driver.wait(async () => { - const tokenAddressesElement = await driver.findElement( - '#erc20TokenAddresses', - ); - const tokenAddresses = await tokenAddressesElement.getText(); - return tokenAddresses.split(',').length === 3; - }, 10000); - - // Watch all 3 tokens - await driver.clickElement({ - text: 'Add Token(s) to Wallet', - tag: 'button', - }); - - // Switch to watchAsset notification - await switchToNotificationWindow(driver); - const multipleSuggestedtokens = await driver.findElements( - '.confirm-add-suggested-token__token-list-item', - ); - - // Confirm all 3 tokens are present as suggested token list - assert.equal(multipleSuggestedtokens.length, 3); - await driver.findClickableElement({ text: 'Add token', tag: 'button' }); - await driver.clickElement({ text: 'Add token', tag: 'button' }); - - // Switch to fullscreen extension - await driver.switchToWindowWithTitle( - WINDOW_TITLES.ExtensionInFullScreenView, - ); - - // Check all three tokens have been added to the token list. - const addedTokens = await driver.findElements({ - tag: 'p', - text: 'TST', - }); - assert.equal(addedTokens.length, 3); - }, - ); - }); -}); diff --git a/test/e2e/tests/tokens/add-multiple-tokens.spec.ts b/test/e2e/tests/tokens/add-multiple-tokens.spec.ts new file mode 100644 index 000000000000..7f02334b90d3 --- /dev/null +++ b/test/e2e/tests/tokens/add-multiple-tokens.spec.ts @@ -0,0 +1,68 @@ +import AddTokensModal from '../../page-objects/pages/dialog/add-tokens'; +import GenericConfirmCancelDialog from '../../page-objects/pages/dialog/dialog'; +import AssetListPage from '../../page-objects/pages/home/asset-list'; +import TestDapp from '../../page-objects/pages/test-dapp'; +import { + withFixtures, + defaultGanacheOptions, + openDapp, + WINDOW_TITLES, + DAPP_URL, + unlockWallet, +} from '../../helpers'; +import FixtureBuilder from '../../fixture-builder'; + +describe('Multiple ERC20 Watch Asset', function () { + it('should show multiple erc20 watchAsset token list, only confirms one bug', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withPermissionControllerConnectedToTestDapp() + .build(), + ganacheOptions: defaultGanacheOptions, + title: this.test?.fullTitle(), + }, + async ({ driver }) => { + await unlockWallet(driver); + await openDapp(driver, undefined, DAPP_URL); + const testDapp = new TestDapp(driver); + + // Create multiple tokens + for (let i = 0; i < 3; i++) { + // Create token + await testDapp.findAndClickCreateToken(); + + // Confirm token creation + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + const confirmModal = new GenericConfirmCancelDialog(driver); + await confirmModal.clickConfirm(); + + // Wait for token address to populate in dapp + await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + await testDapp.check_pageIsLoaded(); + await testDapp.check_TokenAddressesCount(i + 1); + } + + // Watch all 3 tokens + // Switch to watchAsset notification + await testDapp.clickAddTokenToWallet(); + await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + const addTokensPopupModal = new AddTokensModal(driver); + await addTokensPopupModal.check_SuggestedTokensCount(3); + await addTokensPopupModal.confirmAddTokens(); + + // Switch to fullscreen extension + await driver.switchToWindowWithTitle( + WINDOW_TITLES.ExtensionInFullScreenView, + ); + + // Check all three tokens have been added to the token list. + const tokenList = new AssetListPage(driver); + await tokenList.check_tokenItemNumber(4); // 3 tokens plus ETH + await tokenList.check_tokenIsDisplayed('Ethererum'); + await tokenList.check_tokenIsDisplayed('TST'); + }, + ); + }); +}); From 20ba9c4e1e2638ff969380b3fcc5a9c226665cbe Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Wed, 18 Dec 2024 10:06:46 +0000 Subject: [PATCH 02/16] update typo, general tidy up --- .../page-objects/pages/dialog/add-tokens.ts | 2 -- .../pages/dialog/create-contract.ts | 23 +++++++++++++++++++ test/e2e/page-objects/pages/dialog/dialog.ts | 20 ---------------- .../e2e/page-objects/pages/home/asset-list.ts | 15 +++++------- .../tests/tokens/add-multiple-tokens.spec.ts | 9 ++++---- 5 files changed, 34 insertions(+), 35 deletions(-) create mode 100644 test/e2e/page-objects/pages/dialog/create-contract.ts delete mode 100644 test/e2e/page-objects/pages/dialog/dialog.ts diff --git a/test/e2e/page-objects/pages/dialog/add-tokens.ts b/test/e2e/page-objects/pages/dialog/add-tokens.ts index 1c728e5bae5e..b5bbe0c4a1ba 100644 --- a/test/e2e/page-objects/pages/dialog/add-tokens.ts +++ b/test/e2e/page-objects/pages/dialog/add-tokens.ts @@ -1,7 +1,6 @@ import { Driver } from '../../../webdriver/driver'; import { strict as assert } from 'assert'; - class AddTokensModal { protected driver: Driver; @@ -28,7 +27,6 @@ class AddTokensModal { } async confirmAddTokens() { - await this.driver.findClickableElement(this.addTokenButton); await this.driver.clickElement(this.addTokenButton); } } diff --git a/test/e2e/page-objects/pages/dialog/create-contract.ts b/test/e2e/page-objects/pages/dialog/create-contract.ts new file mode 100644 index 000000000000..f38b91f1fc28 --- /dev/null +++ b/test/e2e/page-objects/pages/dialog/create-contract.ts @@ -0,0 +1,23 @@ +import { Driver } from '../../../webdriver/driver'; + +class CreateContractDialog { + protected driver: Driver; + + private readonly confirmButtton = { text: 'Confirm', tag: 'button' }; + + private readonly cancelButton = { text: 'Cancel', tag: 'button' }; + + constructor(driver: Driver) { + this.driver = driver; + } + + async clickConfirm() { + await this.driver.clickElement(this.confirmButtton); + } + + async clickCancel() { + await this.driver.clickElement(this.cancelButton); + } +} + +export default CreateContractDialog; diff --git a/test/e2e/page-objects/pages/dialog/dialog.ts b/test/e2e/page-objects/pages/dialog/dialog.ts deleted file mode 100644 index 9762e2a892cd..000000000000 --- a/test/e2e/page-objects/pages/dialog/dialog.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Driver } from '../../../webdriver/driver'; -import { strict as assert } from 'assert'; - -class GenericConfirmCancelDialog { - protected driver: Driver; - - constructor(driver: Driver) { - this.driver = driver; - } - - async clickConfirm() { - await this.driver.clickElement({ text: 'Confirm', tag: 'button' }) - } - - async clickCancel() { - await this.driver.clickElement({ text: 'Confirm', tag: 'button' }) - } -} - -export default GenericConfirmCancelDialog; diff --git a/test/e2e/page-objects/pages/home/asset-list.ts b/test/e2e/page-objects/pages/home/asset-list.ts index 2cb33a69f81e..c6fac69bfbae 100644 --- a/test/e2e/page-objects/pages/home/asset-list.ts +++ b/test/e2e/page-objects/pages/home/asset-list.ts @@ -204,21 +204,18 @@ class AssetListPage { }); } - /** + /** * This function checks if the specified token is displayed in the token list by its name. * * @param tokenName - The name of the token to check for. * @returns A promise that resolves if the specified token is displayed. */ - async check_tokenIsDisplayed(tokenName: string): Promise { + async check_tokenIsDisplayed(tokenName: string): Promise { console.log(`Waiting for token ${tokenName} to be displayed`); - await this.driver.wait(async () => { - const tokenIsDisplayed = await this.driver.findElement({ - text: tokenName, - tag: 'p', - }); - return tokenIsDisplayed !== null; - }, 10000); + const tokenIsDisplayed = await this.driver.waitForSelector({ + text: tokenName, + tag: 'p', + }); console.log(`Token ${tokenName} is displayed.`); } diff --git a/test/e2e/tests/tokens/add-multiple-tokens.spec.ts b/test/e2e/tests/tokens/add-multiple-tokens.spec.ts index 7f02334b90d3..bbe09ea8f89d 100644 --- a/test/e2e/tests/tokens/add-multiple-tokens.spec.ts +++ b/test/e2e/tests/tokens/add-multiple-tokens.spec.ts @@ -1,5 +1,5 @@ import AddTokensModal from '../../page-objects/pages/dialog/add-tokens'; -import GenericConfirmCancelDialog from '../../page-objects/pages/dialog/dialog'; +import GenericConfirmCancelDialog from '../../page-objects/pages/dialog/create-contract'; import AssetListPage from '../../page-objects/pages/home/asset-list'; import TestDapp from '../../page-objects/pages/test-dapp'; import { @@ -11,6 +11,7 @@ import { unlockWallet, } from '../../helpers'; import FixtureBuilder from '../../fixture-builder'; +import CreateContractDialog from '../../page-objects/pages/dialog/create-contract'; describe('Multiple ERC20 Watch Asset', function () { it('should show multiple erc20 watchAsset token list, only confirms one bug', async function () { @@ -35,8 +36,8 @@ describe('Multiple ERC20 Watch Asset', function () { // Confirm token creation await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - const confirmModal = new GenericConfirmCancelDialog(driver); - await confirmModal.clickConfirm(); + const createContractDialog = new CreateContractDialog(driver); + await createContractDialog.clickConfirm(); // Wait for token address to populate in dapp await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); @@ -60,7 +61,7 @@ describe('Multiple ERC20 Watch Asset', function () { // Check all three tokens have been added to the token list. const tokenList = new AssetListPage(driver); await tokenList.check_tokenItemNumber(4); // 3 tokens plus ETH - await tokenList.check_tokenIsDisplayed('Ethererum'); + await tokenList.check_tokenIsDisplayed('Ethereum'); await tokenList.check_tokenIsDisplayed('TST'); }, ); From 886cf1ab5a7685a0fa70fce9a3e5bd28ef7305f7 Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Wed, 18 Dec 2024 10:14:35 +0000 Subject: [PATCH 03/16] add load check methods, make naming consistent --- .../page-objects/pages/dialog/add-tokens.ts | 16 ++++++++++++++ .../pages/dialog/create-contract.ts | 21 +++++++++++++++++-- .../tests/tokens/add-multiple-tokens.spec.ts | 8 ++++--- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/test/e2e/page-objects/pages/dialog/add-tokens.ts b/test/e2e/page-objects/pages/dialog/add-tokens.ts index b5bbe0c4a1ba..0950058bc59e 100644 --- a/test/e2e/page-objects/pages/dialog/add-tokens.ts +++ b/test/e2e/page-objects/pages/dialog/add-tokens.ts @@ -12,6 +12,22 @@ class AddTokensModal { this.driver = driver; } + async check_pageIsLoaded(): Promise { + try { + await this.driver.waitForMultipleSelectors([ + this.tokenListItem, + this.addTokenButton, + ]); + } catch (e) { + console.log( + 'Timeout while waiting for Add tokens dialog to be loaded', + e, + ); + throw e; + } + console.log('Add tokens dialog was loaded'); + } + /** * Checks the count of suggested tokens. * diff --git a/test/e2e/page-objects/pages/dialog/create-contract.ts b/test/e2e/page-objects/pages/dialog/create-contract.ts index f38b91f1fc28..999f9833c3da 100644 --- a/test/e2e/page-objects/pages/dialog/create-contract.ts +++ b/test/e2e/page-objects/pages/dialog/create-contract.ts @@ -1,6 +1,6 @@ import { Driver } from '../../../webdriver/driver'; -class CreateContractDialog { +class CreateContractModal { protected driver: Driver; private readonly confirmButtton = { text: 'Confirm', tag: 'button' }; @@ -11,6 +11,23 @@ class CreateContractDialog { this.driver = driver; } + async check_pageIsLoaded(): Promise { + try { + await this.driver.waitForMultipleSelectors([ + this.confirmButtton, + this.cancelButton, + ]); + } catch (e) { + console.log( + 'Timeout while waiting for create contract dialog to be loaded', + e, + ); + throw e; + } + console.log('Create contract dialog was loaded'); + } + + async clickConfirm() { await this.driver.clickElement(this.confirmButtton); } @@ -20,4 +37,4 @@ class CreateContractDialog { } } -export default CreateContractDialog; +export default CreateContractModal; diff --git a/test/e2e/tests/tokens/add-multiple-tokens.spec.ts b/test/e2e/tests/tokens/add-multiple-tokens.spec.ts index bbe09ea8f89d..7b99ff96353e 100644 --- a/test/e2e/tests/tokens/add-multiple-tokens.spec.ts +++ b/test/e2e/tests/tokens/add-multiple-tokens.spec.ts @@ -11,7 +11,7 @@ import { unlockWallet, } from '../../helpers'; import FixtureBuilder from '../../fixture-builder'; -import CreateContractDialog from '../../page-objects/pages/dialog/create-contract'; +import CreateContractModal from '../../page-objects/pages/dialog/create-contract'; describe('Multiple ERC20 Watch Asset', function () { it('should show multiple erc20 watchAsset token list, only confirms one bug', async function () { @@ -36,8 +36,9 @@ describe('Multiple ERC20 Watch Asset', function () { // Confirm token creation await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - const createContractDialog = new CreateContractDialog(driver); - await createContractDialog.clickConfirm(); + const createContractModal = new CreateContractModal(driver); + await createContractModal.check_pageIsLoaded() + await createContractModal.clickConfirm(); // Wait for token address to populate in dapp await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); @@ -50,6 +51,7 @@ describe('Multiple ERC20 Watch Asset', function () { await testDapp.clickAddTokenToWallet(); await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); const addTokensPopupModal = new AddTokensModal(driver); + addTokensPopupModal.check_pageIsLoaded() await addTokensPopupModal.check_SuggestedTokensCount(3); await addTokensPopupModal.confirmAddTokens(); From d00f8e392b7b4dae8c948f6a8060cb435aa8ed48 Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Wed, 18 Dec 2024 10:55:43 +0000 Subject: [PATCH 04/16] linting --- test/e2e/page-objects/pages/dialog/add-tokens.ts | 2 +- test/e2e/page-objects/pages/dialog/create-contract.ts | 1 - test/e2e/page-objects/pages/home/asset-list.ts | 2 +- test/e2e/page-objects/pages/test-dapp.ts | 6 ++++-- test/e2e/tests/tokens/add-multiple-tokens.spec.ts | 5 ++--- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/e2e/page-objects/pages/dialog/add-tokens.ts b/test/e2e/page-objects/pages/dialog/add-tokens.ts index 0950058bc59e..7ed95c8e20b5 100644 --- a/test/e2e/page-objects/pages/dialog/add-tokens.ts +++ b/test/e2e/page-objects/pages/dialog/add-tokens.ts @@ -1,5 +1,5 @@ -import { Driver } from '../../../webdriver/driver'; import { strict as assert } from 'assert'; +import { Driver } from '../../../webdriver/driver'; class AddTokensModal { protected driver: Driver; diff --git a/test/e2e/page-objects/pages/dialog/create-contract.ts b/test/e2e/page-objects/pages/dialog/create-contract.ts index 999f9833c3da..44d7eec28bfa 100644 --- a/test/e2e/page-objects/pages/dialog/create-contract.ts +++ b/test/e2e/page-objects/pages/dialog/create-contract.ts @@ -27,7 +27,6 @@ class CreateContractModal { console.log('Create contract dialog was loaded'); } - async clickConfirm() { await this.driver.clickElement(this.confirmButtton); } diff --git a/test/e2e/page-objects/pages/home/asset-list.ts b/test/e2e/page-objects/pages/home/asset-list.ts index c6fac69bfbae..9db896e3a035 100644 --- a/test/e2e/page-objects/pages/home/asset-list.ts +++ b/test/e2e/page-objects/pages/home/asset-list.ts @@ -212,7 +212,7 @@ class AssetListPage { */ async check_tokenIsDisplayed(tokenName: string): Promise { console.log(`Waiting for token ${tokenName} to be displayed`); - const tokenIsDisplayed = await this.driver.waitForSelector({ + await this.driver.waitForSelector({ text: tokenName, tag: 'p', }); diff --git a/test/e2e/page-objects/pages/test-dapp.ts b/test/e2e/page-objects/pages/test-dapp.ts index 560de2a337e6..f2e957969ec0 100644 --- a/test/e2e/page-objects/pages/test-dapp.ts +++ b/test/e2e/page-objects/pages/test-dapp.ts @@ -354,11 +354,13 @@ class TestDapp { }); } - /** + /** * Scrolls to the create token button and clicks it. */ public async findAndClickCreateToken() { - const createTokenElement = await this.driver.findElement(this.createTokenButton); + const createTokenElement = await this.driver.findElement( + this.createTokenButton, + ); await this.driver.scrollToElement(createTokenElement); await this.driver.clickElement(this.createTokenButton); } diff --git a/test/e2e/tests/tokens/add-multiple-tokens.spec.ts b/test/e2e/tests/tokens/add-multiple-tokens.spec.ts index 7b99ff96353e..b71e0fff1eb0 100644 --- a/test/e2e/tests/tokens/add-multiple-tokens.spec.ts +++ b/test/e2e/tests/tokens/add-multiple-tokens.spec.ts @@ -1,5 +1,4 @@ import AddTokensModal from '../../page-objects/pages/dialog/add-tokens'; -import GenericConfirmCancelDialog from '../../page-objects/pages/dialog/create-contract'; import AssetListPage from '../../page-objects/pages/home/asset-list'; import TestDapp from '../../page-objects/pages/test-dapp'; import { @@ -37,7 +36,7 @@ describe('Multiple ERC20 Watch Asset', function () { // Confirm token creation await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); const createContractModal = new CreateContractModal(driver); - await createContractModal.check_pageIsLoaded() + await createContractModal.check_pageIsLoaded(); await createContractModal.clickConfirm(); // Wait for token address to populate in dapp @@ -51,7 +50,7 @@ describe('Multiple ERC20 Watch Asset', function () { await testDapp.clickAddTokenToWallet(); await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); const addTokensPopupModal = new AddTokensModal(driver); - addTokensPopupModal.check_pageIsLoaded() + addTokensPopupModal.check_pageIsLoaded(); await addTokensPopupModal.check_SuggestedTokensCount(3); await addTokensPopupModal.confirmAddTokens(); From bab4345c1219e042c836e637575c19998dac4564 Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Wed, 18 Dec 2024 13:25:31 +0000 Subject: [PATCH 05/16] migrate erc-20 to contract test --- .../pages/send/send-token-page.ts | 22 ++++++++ .../page-objects/pages/token-overview-page.ts | 46 ++++++++++++++++ .../tokens/send-erc20-to-contract.spec.js | 53 ------------------- .../tokens/send-erc20-to-contract.spec.ts | 52 ++++++++++++++++++ 4 files changed, 120 insertions(+), 53 deletions(-) create mode 100644 test/e2e/page-objects/pages/token-overview-page.ts delete mode 100644 test/e2e/tests/tokens/send-erc20-to-contract.spec.js create mode 100644 test/e2e/tests/tokens/send-erc20-to-contract.spec.ts diff --git a/test/e2e/page-objects/pages/send/send-token-page.ts b/test/e2e/page-objects/pages/send/send-token-page.ts index 3c1d96618556..29c3f322ee65 100644 --- a/test/e2e/page-objects/pages/send/send-token-page.ts +++ b/test/e2e/page-objects/pages/send/send-token-page.ts @@ -40,6 +40,9 @@ class SendTokenPage { private readonly toastText = '.toast-text'; + private readonly warning = + '[data-testid="send-warning"] .mm-box--min-width-0 span'; + constructor(driver: Driver) { this.driver = driver; } @@ -196,6 +199,25 @@ class SendTokenPage { text: address, }); } + + /** + * Verifies that a specific warning message is displayed on the send token screen. + * + * @param warningText - The expected warning text to validate against. + * @returns A promise that resolves if the warning message matches the expected text. + * @throws Assertion error if the warning message does not match the expected text. + */ + async check_warningMessage(warningText: string): Promise { + console.log(`Checking if warning message "${warningText}" is displayed`); + const warning = await this.driver.findElement(this.warning); + const text = await warning.getText(); + assert.equal( + text, + warningText, + `Expected warning message to be "${warningText}", got "${text}"`, + ); + console.log('Warning message validation successful'); + } } export default SendTokenPage; diff --git a/test/e2e/page-objects/pages/token-overview-page.ts b/test/e2e/page-objects/pages/token-overview-page.ts new file mode 100644 index 000000000000..8c3f8921ddb5 --- /dev/null +++ b/test/e2e/page-objects/pages/token-overview-page.ts @@ -0,0 +1,46 @@ +import { Driver } from '../../webdriver/driver'; + +class TokenOverviewPage { + private driver: Driver; + + private readonly sendButton = '[data-testid="coin-overview-send"]'; + + private readonly receiveButton = '[data-testid="coin-overview-receive"]'; + + private readonly swapButton = '[data-testid="token-overview-button-swap"]'; + + constructor(driver: Driver) { + this.driver = driver; + } + + async check_pageIsLoaded(): Promise { + try { + await this.driver.waitForMultipleSelectors([ + this.sendButton, + this.receiveButton, + this.swapButton, + ]); + } catch (e) { + console.log( + 'Timeout while waiting for Token overview page to be loaded', + e, + ); + throw e; + } + console.log('Token overview page is loaded'); + } + + async clickSend(): Promise { + await this.driver.clickElement(this.sendButton); + } + + async clickReceive(): Promise { + await this.driver.clickElement(this.receiveButton); + } + + async clickSwap(): Promise { + await this.driver.clickElement(this.swapButton); + } +} + +export default TokenOverviewPage; diff --git a/test/e2e/tests/tokens/send-erc20-to-contract.spec.js b/test/e2e/tests/tokens/send-erc20-to-contract.spec.js deleted file mode 100644 index 6e94b6377e67..000000000000 --- a/test/e2e/tests/tokens/send-erc20-to-contract.spec.js +++ /dev/null @@ -1,53 +0,0 @@ -const { strict: assert } = require('assert'); -const { - defaultGanacheOptions, - withFixtures, - unlockWallet, -} = require('../../helpers'); -const { SMART_CONTRACTS } = require('../../seeder/smart-contracts'); -const FixtureBuilder = require('../../fixture-builder'); - -describe('Send ERC20 token to contract address', function () { - const smartContract = SMART_CONTRACTS.HST; - - it('should display the token contract warning to the user', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().withTokensControllerERC20().build(), - ganacheOptions: defaultGanacheOptions, - smartContract, - title: this.test.fullTitle(), - }, - async ({ driver, contractRegistry }) => { - const contractAddress = await contractRegistry.getContractAddress( - smartContract, - ); - await unlockWallet(driver); - - // Send TST - await driver.clickElement( - '[data-testid="account-overview__asset-tab"]', - ); - await driver.clickElement( - '[data-testid="multichain-token-list-button"]', - ); - await driver.clickElement('[data-testid="coin-overview-send"]'); - - // Type contract address - await driver.fill( - 'input[placeholder="Enter public address (0x) or domain name"]', - contractAddress, - ); - - // Verify warning - const warningText = - 'Warning: you are about to send to a token contract which could result in a loss of funds. Learn more'; - const warning = await driver.findElement( - '[data-testid="send-warning"] .mm-box--min-width-0 span', - ); - assert.equal(await warning.getText(), warningText); - }, - ); - }); -}); diff --git a/test/e2e/tests/tokens/send-erc20-to-contract.spec.ts b/test/e2e/tests/tokens/send-erc20-to-contract.spec.ts new file mode 100644 index 000000000000..34b673ff033c --- /dev/null +++ b/test/e2e/tests/tokens/send-erc20-to-contract.spec.ts @@ -0,0 +1,52 @@ +import { + defaultGanacheOptions, + withFixtures, + unlockWallet, +} from '../../helpers'; +import { SMART_CONTRACTS } from '../../seeder/smart-contracts'; +import FixtureBuilder from '../../fixture-builder'; + +import AssetListPage from '../../page-objects/pages/home/asset-list'; +import HomePage from '../../page-objects/pages/home/homepage'; +import SendTokenPage from '../../page-objects/pages/send/send-token-page'; +import TokenOverviewPage from '../../page-objects/pages/token-overview-page'; + +describe('Send ERC20 token to contract address', function () { + const smartContract = SMART_CONTRACTS.HST; + + it('should display the token contract warning to the user', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder().withTokensControllerERC20().build(), + ganacheOptions: defaultGanacheOptions, + smartContract, + title: this.test?.fullTitle(), + }, + async ({ driver, contractRegistry }) => { + const contractAddress: string = + await contractRegistry.getContractAddress(smartContract); + await unlockWallet(driver); + + const homePage = new HomePage(driver); + const assetListPage = new AssetListPage(driver); + await homePage.check_pageIsLoaded(); + await assetListPage.clickOnAsset('Ethereum'); + + // Send TST + const tokenOverviewPage = new TokenOverviewPage(driver); + await tokenOverviewPage.check_pageIsLoaded(); + await tokenOverviewPage.clickSend(); + + const sendTokenPage = new SendTokenPage(driver); + await sendTokenPage.check_pageIsLoaded(); + await sendTokenPage.fillRecipient(contractAddress); + + // Verify warning + const warningText = + 'Warning: you are about to send to a token contract which could result in a loss of funds. Learn more'; + await sendTokenPage.check_warningMessage(warningText); + }, + ); + }); +}); From b4d3fec9fc2b0095c99dbf6afc2138e65960ffa0 Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Thu, 19 Dec 2024 09:47:39 +0000 Subject: [PATCH 06/16] remove duplicate function --- test/e2e/page-objects/pages/test-dapp.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/test/e2e/page-objects/pages/test-dapp.ts b/test/e2e/page-objects/pages/test-dapp.ts index a559d400dbe8..5471afb3556a 100644 --- a/test/e2e/page-objects/pages/test-dapp.ts +++ b/test/e2e/page-objects/pages/test-dapp.ts @@ -365,17 +365,6 @@ class TestDapp { await this.driver.clickElement(this.createTokenButton); } - /** - * Scrolls to the create token button and clicks it. - */ - public async findAndClickCreateToken() { - const createTokenElement = await this.driver.findElement( - this.createTokenButton, - ); - await this.driver.scrollToElement(createTokenElement); - await this.driver.clickElement(this.createTokenButton); - } - /** * Verifies the accounts connected to the test dapp. * From e8fbb7a3c9e55cbf4a8240f88151343ed863b9f0 Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Thu, 19 Dec 2024 13:29:04 +0000 Subject: [PATCH 07/16] use seconadar name --- test/e2e/tests/tokens/send-erc20-to-contract.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/tests/tokens/send-erc20-to-contract.spec.ts b/test/e2e/tests/tokens/send-erc20-to-contract.spec.ts index 34b673ff033c..b2ef89372081 100644 --- a/test/e2e/tests/tokens/send-erc20-to-contract.spec.ts +++ b/test/e2e/tests/tokens/send-erc20-to-contract.spec.ts @@ -31,7 +31,7 @@ describe('Send ERC20 token to contract address', function () { const homePage = new HomePage(driver); const assetListPage = new AssetListPage(driver); await homePage.check_pageIsLoaded(); - await assetListPage.clickOnAsset('Ethereum'); + await assetListPage.clickOnAsset('ETH'); // Send TST const tokenOverviewPage = new TokenOverviewPage(driver); From f11c25d4b403bd6364ede367ef1b1015d465cc57 Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Fri, 20 Dec 2024 06:37:40 +0000 Subject: [PATCH 08/16] get buttons by text to avoid flake --- .../page-objects/pages/token-overview-page.ts | 16 ++++++++++++---- .../tests/tokens/send-erc20-to-contract.spec.ts | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/test/e2e/page-objects/pages/token-overview-page.ts b/test/e2e/page-objects/pages/token-overview-page.ts index 8c3f8921ddb5..2d8d5abf6bfc 100644 --- a/test/e2e/page-objects/pages/token-overview-page.ts +++ b/test/e2e/page-objects/pages/token-overview-page.ts @@ -3,11 +3,20 @@ import { Driver } from '../../webdriver/driver'; class TokenOverviewPage { private driver: Driver; - private readonly sendButton = '[data-testid="coin-overview-send"]'; + private readonly sendButton = { + text: 'Send', + css: '.icon-button', + } - private readonly receiveButton = '[data-testid="coin-overview-receive"]'; + private readonly receiveButton = { + text: 'Receive', + css: '.icon-button', + } - private readonly swapButton = '[data-testid="token-overview-button-swap"]'; + private readonly swapButton = { + text: 'Swap', + css: '.icon-button', + } constructor(driver: Driver) { this.driver = driver; @@ -17,7 +26,6 @@ class TokenOverviewPage { try { await this.driver.waitForMultipleSelectors([ this.sendButton, - this.receiveButton, this.swapButton, ]); } catch (e) { diff --git a/test/e2e/tests/tokens/send-erc20-to-contract.spec.ts b/test/e2e/tests/tokens/send-erc20-to-contract.spec.ts index b2ef89372081..5c7b59cbc215 100644 --- a/test/e2e/tests/tokens/send-erc20-to-contract.spec.ts +++ b/test/e2e/tests/tokens/send-erc20-to-contract.spec.ts @@ -31,7 +31,7 @@ describe('Send ERC20 token to contract address', function () { const homePage = new HomePage(driver); const assetListPage = new AssetListPage(driver); await homePage.check_pageIsLoaded(); - await assetListPage.clickOnAsset('ETH'); + await assetListPage.clickOnAsset('TST'); // Send TST const tokenOverviewPage = new TokenOverviewPage(driver); From faffc7340fea67b2110d99bae48722e048f7a6c7 Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Fri, 20 Dec 2024 06:45:28 +0000 Subject: [PATCH 09/16] update token list,sort and import --- .../e2e/page-objects/pages/home/asset-list.ts | 140 ++++++++++ ...t-tokens.spec.js => import-tokens.spec.ts} | 58 ++--- test/e2e/tests/tokens/token-list.spec.ts | 239 +++++++----------- test/e2e/tests/tokens/token-sort.spec.ts | 108 +++----- 4 files changed, 289 insertions(+), 256 deletions(-) rename test/e2e/tests/tokens/{import-tokens.spec.js => import-tokens.spec.ts} (54%) diff --git a/test/e2e/page-objects/pages/home/asset-list.ts b/test/e2e/page-objects/pages/home/asset-list.ts index 9db896e3a035..6553dd6b700b 100644 --- a/test/e2e/page-objects/pages/home/asset-list.ts +++ b/test/e2e/page-objects/pages/home/asset-list.ts @@ -24,6 +24,11 @@ class AssetListPage { private readonly currentNetworksTotal = `${this.currentNetworkOption} [data-testid="account-value-and-suffix"]`; + private readonly customTokenModalOption = { + text: 'Custom token', + tag: 'button', + }; + private readonly hideTokenButton = '[data-testid="asset-options__hide"]'; private readonly hideTokenConfirmationButton = @@ -43,16 +48,45 @@ class AssetListPage { private readonly networksToggle = '[data-testid="sort-by-networks"]'; + private sortByAlphabetically = '[data-testid="sortByAlphabetically"]'; + + private sortByDecliningBalance = '[data-testid="sortByDecliningBalance"]'; + + private sortByPopoverToggle = '[data-testid="sort-by-popover-toggle"]'; + + private readonly tokenAddressInput = + '[data-testid="import-tokens-modal-custom-address"]'; + private readonly tokenAmountValue = '[data-testid="multichain-token-list-item-value"]'; + private readonly tokenImportedSuccessMessage = { + text: 'Token imported', + tag: 'h6', + }; + private readonly tokenListItem = '[data-testid="multichain-token-list-button"]'; private readonly tokenOptionsButton = '[data-testid="import-token-button"]'; + private tokenPercentage(address: string): string { + return `[data-testid="token-increase-decrease-percentage-${address}"]`; + } + private readonly tokenSearchInput = 'input[placeholder="Search tokens"]'; + private readonly tokenSymbolInput = + '[data-testid="import-tokens-modal-custom-symbol"]'; + + private readonly modalWarningBanner = 'div.mm-banner-alert--severity-warning'; + + private readonly tokenIncreaseDecreaseValue = + '[data-testid="token-increase-decrease-value"]'; + + private readonly tokenIncreaseDecreasePercentageGeneral = + '[data-testid="token-increase-decrease-percentage"]'; + constructor(driver: Driver) { this.driver = driver; } @@ -103,6 +137,42 @@ class AssetListPage { return assets.length; } + async getTokenListNames(): Promise { + console.log(`Retrieving the list of token names`); + const tokenElements = await this.driver.findElements(this.tokenListItem); + const tokenNames = await Promise.all( + tokenElements.map(async (element) => { + return await element.getText(); + }), + ); + return tokenNames; + } + + async getAssetPercentageIncreaseDecrease( + assetAddress: string, + ): Promise { + console.log( + `Retrieving the percentage increase or decrease for ${assetAddress}`, + ); + const percentageElement = await this.driver.findElement( + this.tokenPercentage(assetAddress), + ); + const percentage = await percentageElement.getText(); + return percentage; + } + + async sortTokenList( + sortBy: 'alphabetically' | 'decliningBalance', + ): Promise { + console.log(`Sorting the token list by ${sortBy}`); + await this.driver.clickElement(this.sortByPopoverToggle); + if (sortBy === 'alphabetically') { + await this.driver.clickElement(this.sortByAlphabetically); + } else if (sortBy === 'decliningBalance') { + await this.driver.clickElement(this.sortByDecliningBalance); + } + } + /** * Hides a token by clicking on the token name, and confirming the hide modal. * @@ -119,6 +189,22 @@ class AssetListPage { ); } + async importCustomToken(tokenAddress: string, symbol: string): Promise { + console.log(`Creating custom token ${symbol} on homepage`); + await this.driver.clickElement(this.tokenOptionsButton); + await this.driver.clickElement(this.importTokensButton); + await this.driver.waitForSelector(this.importTokenModalTitle); + await this.driver.clickElement(this.customTokenModalOption); + await this.driver.waitForSelector(this.modalWarningBanner); + await this.driver.fill(this.tokenAddressInput, tokenAddress); + await this.driver.fill(this.tokenSymbolInput, symbol); + await this.driver.clickElement(this.importTokensNextButton); + await this.driver.clickElementAndWaitToDisappear( + this.confirmImportTokenButton, + ); + await this.driver.waitForSelector(this.tokenImportedSuccessMessage); + } + async importTokenBySearch(tokenName: string) { console.log(`Import token ${tokenName} on homepage by search`); await this.driver.clickElement(this.tokenOptionsButton); @@ -133,6 +219,24 @@ class AssetListPage { ); } + async importMultipleTokensBySearch(tokenNames: string[]) { + console.log( + `Importing tokens ${tokenNames.join(', ')} on homepage by search`, + ); + await this.driver.clickElement(this.tokenOptionsButton); + await this.driver.clickElement(this.importTokensButton); + await this.driver.waitForSelector(this.importTokenModalTitle); + + for (const name of tokenNames) { + await this.driver.fill(this.tokenSearchInput, name); + await this.driver.clickElement({ text: name, tag: 'p' }); + } + await this.driver.clickElement(this.importTokensNextButton); + await this.driver.clickElementAndWaitToDisappear( + this.confirmImportTokenButton, + ); + } + async openNetworksFilter(): Promise { console.log(`Opening the network filter`); await this.driver.clickElement(this.networksToggle); @@ -235,6 +339,42 @@ class AssetListPage { `Expected number of token items ${expectedNumber} is displayed.`, ); } + + /** + * Checks if the token increase/decrease percentage is displayed correctly for a specific token + * @param address - The token address to check + * @param expectedPercentage - The expected percentage value (e.g. '+0.02%') + */ + async check_tokenIncreasePercentage( + address: string, + expectedPercentage: string, + ): Promise { + console.log(`Checking token increase percentage for address ${address}`); + const isPresent = await this.driver.isElementPresentAndVisible({ + css: `[data-testid="token-increase-decrease-percentage-${address}"]`, + text: expectedPercentage, + }); + if (!isPresent) { + throw new Error( + `Token increase percentage ${expectedPercentage} not found for address ${address}`, + ); + } + } + + /** + * Checks if the token increase/decrease value is displayed correctly + * @param expectedValue - The expected value (e.g. '+$50.00') + */ + async check_tokenIncreaseValue(expectedValue: string): Promise { + console.log(`Checking token increase value ${expectedValue}`); + const isPresent = await this.driver.isElementPresentAndVisible({ + css: this.tokenIncreaseDecreaseValue, + text: expectedValue, + }); + if (!isPresent) { + throw new Error(`Token increase value ${expectedValue} not found`); + } + } } export default AssetListPage; diff --git a/test/e2e/tests/tokens/import-tokens.spec.js b/test/e2e/tests/tokens/import-tokens.spec.ts similarity index 54% rename from test/e2e/tests/tokens/import-tokens.spec.js rename to test/e2e/tests/tokens/import-tokens.spec.ts index b15c9ffb100a..9b8200dc2b99 100644 --- a/test/e2e/tests/tokens/import-tokens.spec.js +++ b/test/e2e/tests/tokens/import-tokens.spec.ts @@ -1,13 +1,16 @@ -const { strict: assert } = require('assert'); -const { +import AssetListPage from '../../page-objects/pages/home/asset-list'; +import HomePage from '../../page-objects/pages/home/homepage'; + +import { strict as assert } from 'assert'; +import { defaultGanacheOptions, withFixtures, unlockWallet, -} = require('../../helpers'); -const FixtureBuilder = require('../../fixture-builder'); +} from '../../helpers'; +import FixtureBuilder from '../../fixture-builder'; describe('Import flow', function () { - async function mockPriceFetch(mockServer) { + async function mockPriceFetch(mockServer: any) { return [ await mockServer .forGet('https://price.api.cx.metamask.io/v2/chains/1/spot-prices') @@ -60,47 +63,24 @@ describe('Import flow', function () { }) .build(), ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), + title: this.test?.fullTitle(), testSpecificMock: mockPriceFetch, }, async ({ driver }) => { await unlockWallet(driver); - await driver.assertElementNotPresent('.loading-overlay'); - - await driver.clickElement('[data-testid="import-token-button"]'); - await driver.clickElement('[data-testid="importTokens"]'); - - await driver.fill('input[placeholder="Search tokens"]', 'cha'); - - await driver.clickElement('.token-list__token_component'); - await driver.clickElement( - '.token-list__token_component:nth-of-type(2)', - ); - await driver.clickElement( - '.token-list__token_component:nth-of-type(3)', - ); - - await driver.clickElement('[data-testid="import-tokens-button-next"]'); - await driver.clickElement( - '[data-testid="import-tokens-modal-import-button"]', - ); - - // Wait for "loading tokens" to be gone - await driver.assertElementNotPresent( - '[data-testid="token-list-loading-message"]', - ); - - await driver.assertElementNotPresent( - '[data-testid="token-list-loading-message"]', - ); + const homePage = new HomePage(driver); + const assetListPage = new AssetListPage(driver); + await homePage.check_pageIsLoaded(); + await assetListPage.importMultipleTokensBySearch(['CHAIN', 'CHANGE', 'CHAI']); - await driver.clickElement('[data-testid="sort-by-networks"]'); - await driver.clickElement('[data-testid="network-filter-current"]'); + const tokenList = new AssetListPage(driver); + await tokenList.check_tokenItemNumber(5); // Linea & Mainnet Eth + await tokenList.check_tokenIsDisplayed('Ethereum'); + await tokenList.check_tokenIsDisplayed('Chain Games'); + await tokenList.check_tokenIsDisplayed('Changex'); + await tokenList.check_tokenIsDisplayed('Chai'); - const expectedTokenListElementsAreFound = - await driver.elementCountBecomesN('.multichain-token-list-item', 4); - assert.equal(expectedTokenListElementsAreFound, true); }, ); }); diff --git a/test/e2e/tests/tokens/token-list.spec.ts b/test/e2e/tests/tokens/token-list.spec.ts index f7b032c92a4c..6b55db3e1dd1 100644 --- a/test/e2e/tests/tokens/token-list.spec.ts +++ b/test/e2e/tests/tokens/token-list.spec.ts @@ -12,9 +12,12 @@ import { withFixtures, } from '../../helpers'; import { Driver } from '../../webdriver/driver'; +import HomePage from '../../page-objects/pages/home/homepage'; +import AssetListPage from '../../page-objects/pages/home/asset-list'; describe('Token List', function () { const chainId = CHAIN_IDS.MAINNET; + const lineaChainId = CHAIN_IDS.LINEA_MAINNET; const tokenAddress = '0x2EFA2Cb29C2341d8E5Ba7D3262C9e9d6f1Bf3711'; const symbol = 'foo'; @@ -26,73 +29,96 @@ describe('Token List', function () { }, }; - const importToken = async (driver: Driver) => { - await driver.clickElement(`[data-testid="import-token-button"]`); - await driver.clickElement(`[data-testid="importTokens"]`); - await clickNestedButton(driver, 'Custom token'); - await driver.fill( - '[data-testid="import-tokens-modal-custom-address"]', - tokenAddress, - ); - await driver.waitForSelector('p.mm-box--color-error-default'); - await driver.fill( - '[data-testid="import-tokens-modal-custom-symbol"]', - symbol, - ); - await driver.clickElement({ text: 'Next', tag: 'button' }); - await driver.clickElement( - '[data-testid="import-tokens-modal-import-button"]', - ); - await driver.findElement({ text: 'Token imported', tag: 'h6' }); + const mockEmptyPrices = async (mockServer: Mockttp, chainIdToMock: string) => { + return mockServer + .forGet( + `https://price.api.cx.metamask.io/v2/chains/${parseInt( + chainIdToMock, + 16, + )}/spot-prices`, + ) + .thenCallback(() => ({ + statusCode: 200, + json: {}, + })); + }; + + const mockEmptyHistoricalPrices = async (mockServer: Mockttp, address: string) => { + return mockServer + .forGet( + `https://price.api.cx.metamask.io/v1/chains/${chainId}/historical-prices/${address}`, + ) + .thenCallback(() => ({ + statusCode: 200, + json: {}, + })); + }; + + const mockSpotPrices = async ( + mockServer: Mockttp, + chainIdToMock: string, + prices: Record + ) => { + return mockServer + .forGet( + `https://price.api.cx.metamask.io/v2/chains/${parseInt( + chainIdToMock, + 16, + )}/spot-prices`, + ) + .thenCallback(() => ({ + statusCode: 200, + json: prices, + })); }; - it('should not shows percentage increase for an ERC20 token without prices available', async function () { + const mockHistoricalPrices = async ( + mockServer: Mockttp, + address: string, + price: number + ) => { + return mockServer + .forGet( + `https://price.api.cx.metamask.io/v1/chains/${chainId}/historical-prices/${toChecksumHexAddress( + address, + )}`, + ) + .thenCallback(() => ({ + statusCode: 200, + json: { + prices: [ + [1717566000000, price * 0.9], + [1717566322300, price], + [1717566611338, price * 1.1], + ], + }, + })); + }; + + it('should not show percentage increase for an ERC20 token without prices available', async function () { await withFixtures( { ...fixtures, title: (this as Context).test?.fullTitle(), testSpecificMock: async (mockServer: Mockttp) => [ - // Mock no current price - await mockServer - .forGet( - `https://price.api.cx.metamask.io/v2/chains/${parseInt( - chainId, - 16, - )}/spot-prices`, - ) - .thenCallback(() => ({ - statusCode: 200, - json: {}, - })), - // Mock no historical prices - await mockServer - .forGet( - `https://price.api.cx.metamask.io/v1/chains/${chainId}/historical-prices/${tokenAddress}`, - ) - .thenCallback(() => ({ - statusCode: 200, - json: {}, - })), + await mockEmptyPrices(mockServer, chainId), + await mockEmptyPrices(mockServer, lineaChainId), + await mockEmptyHistoricalPrices(mockServer, tokenAddress), ], }, async ({ driver }: { driver: Driver }) => { await unlockWallet(driver); - await importToken(driver); - // Verify native token increase - const testIdNative = `token-increase-decrease-percentage-${zeroAddress()}`; + const homePage = new HomePage(driver); + const assetListPage = new AssetListPage(driver); - // Verify native token increase - const testId = `token-increase-decrease-percentage-${tokenAddress}`; + await homePage.check_pageIsLoaded(); + await assetListPage.importCustomToken(tokenAddress, symbol); - const percentageNative = await ( - await driver.findElement(`[data-testid="${testIdNative}"]`) - ).getText(); + const percentageNative = await assetListPage.getAssetPercentageIncreaseDecrease(zeroAddress()); assert.equal(percentageNative, ''); - const percentage = await ( - await driver.findElement(`[data-testid="${testId}"]`) - ).getText(); + const percentage = await assetListPage.getAssetPercentageIncreaseDecrease(tokenAddress); assert.equal(percentage, ''); }, ); @@ -100,19 +126,8 @@ describe('Token List', function () { it('shows percentage increase for an ERC20 token with prices available', async function () { const ethConversionInUsd = 10000; - - // Prices are in ETH - const marketData = { - price: 0.123, - marketCap: 12, - pricePercentChange1d: 0.05, - }; - - const marketDataNative = { - price: 0.123, - marketCap: 12, - pricePercentChange1d: 0.02, - }; + const marketData = { price: 0.123, marketCap: 12, pricePercentChange1d: 0.05 }; + const marketDataNative = { price: 0.123, marketCap: 12, pricePercentChange1d: 0.02 }; await withFixtures( { @@ -120,91 +135,25 @@ describe('Token List', function () { title: (this as Context).test?.fullTitle(), ethConversionInUsd, testSpecificMock: async (mockServer: Mockttp) => [ - // Mock current price - await mockServer - .forGet( - `https://price.api.cx.metamask.io/v2/chains/${parseInt( - chainId, - 16, - )}/spot-prices`, - ) - .thenCallback(() => ({ - statusCode: 200, - json: { - [zeroAddress()]: marketDataNative, - [tokenAddress.toLowerCase()]: marketData, - }, - })), - // Mock historical prices - await mockServer - .forGet( - `https://price.api.cx.metamask.io/v1/chains/${chainId}/historical-prices/${toChecksumHexAddress( - tokenAddress, - )}`, - ) - .thenCallback(() => ({ - statusCode: 200, - json: { - prices: [ - [1717566000000, marketData.price * 0.9], - [1717566322300, marketData.price], - [1717566611338, marketData.price * 1.1], - ], - }, - })), + await mockSpotPrices(mockServer, chainId, { + [zeroAddress()]: marketDataNative, + [tokenAddress.toLowerCase()]: marketData, + }), + await mockHistoricalPrices(mockServer, tokenAddress, marketData.price), ], }, async ({ driver }: { driver: Driver }) => { await unlockWallet(driver); - await importToken(driver); - - // Verify native token increase - const testIdBase = 'token-increase-decrease-percentage'; - - const isETHIncreaseDOMPresentAndVisible = - await driver.isElementPresentAndVisible({ - css: `[data-testid="${testIdBase}-${zeroAddress()}"]`, - text: '+0.02%', - }); - assert.equal( - isETHIncreaseDOMPresentAndVisible, - true, - 'Invalid eth increase dom text content', - ); - - const isTokenIncreaseDecreasePercentageDOMPresent = - await driver.isElementPresentAndVisible({ - css: `[data-testid="${testIdBase}-${tokenAddress}"]`, - text: '+0.05%', - }); - assert.equal( - isTokenIncreaseDecreasePercentageDOMPresent, - true, - 'Invalid token increase dom text content', - ); - - // check increase balance for native token eth - const isExpectedIncreaseDecreaseValueDOMPresentAndVisible = - await driver.isElementPresentAndVisible({ - css: '[data-testid="token-increase-decrease-value"]', - text: '+$50.00', - }); - assert.equal( - isExpectedIncreaseDecreaseValueDOMPresentAndVisible, - true, - 'Invalid increase-decrease-value dom text content', - ); - - const isExpectedIncreaseDecreasePercentageDOMPresentAndVisible = - await driver.isElementPresentAndVisible({ - css: '[data-testid="token-increase-decrease-percentage"]', - text: '(+0.02%)', - }); - assert.equal( - isExpectedIncreaseDecreasePercentageDOMPresentAndVisible, - true, - 'Invalid increase-decrease-percentage dom text content', - ); + + const homePage = new HomePage(driver); + const assetListPage = new AssetListPage(driver); + + await homePage.check_pageIsLoaded(); + await assetListPage.importCustomToken(tokenAddress, symbol); + + await assetListPage.check_tokenIncreasePercentage(zeroAddress(), '+0.02%'); + await assetListPage.check_tokenIncreasePercentage(tokenAddress, '+0.05%'); + await assetListPage.check_tokenIncreaseValue('+$50.00'); }, ); }); diff --git a/test/e2e/tests/tokens/token-sort.spec.ts b/test/e2e/tests/tokens/token-sort.spec.ts index ff2d35a917dc..70e6d26c62fa 100644 --- a/test/e2e/tests/tokens/token-sort.spec.ts +++ b/test/e2e/tests/tokens/token-sort.spec.ts @@ -3,102 +3,66 @@ import { Context } from 'mocha'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import FixtureBuilder from '../../fixture-builder'; import { - clickNestedButton, defaultGanacheOptions, - regularDelayMs, unlockWallet, withFixtures, + regularDelayMs, } from '../../helpers'; import { Driver } from '../../webdriver/driver'; +import HomePage from '../../page-objects/pages/home/homepage'; +import AssetListPage from '../../page-objects/pages/home/asset-list'; -describe('Token List', function () { - const chainId = CHAIN_IDS.MAINNET; - const tokenAddress = '0x2EFA2Cb29C2341d8E5Ba7D3262C9e9d6f1Bf3711'; - const symbol = 'ABC'; +describe('Token List Sorting', function () { + const mainnetChainId = CHAIN_IDS.MAINNET; + const customTokenAddress = '0x2EFA2Cb29C2341d8E5Ba7D3262C9e9d6f1Bf3711'; + const customTokenSymbol = 'ABC'; - const fixtures = { - fixtures: new FixtureBuilder({ inputChainId: chainId }).build(), + const testFixtures = { + fixtures: new FixtureBuilder({ inputChainId: mainnetChainId }).build(), ganacheOptions: { ...defaultGanacheOptions, - chainId: parseInt(chainId, 16), + chainId: parseInt(mainnetChainId, 16), }, }; - const importToken = async (driver: Driver) => { - await driver.clickElement(`[data-testid="import-token-button"]`); - await driver.clickElement(`[data-testid="importTokens"]`); - await clickNestedButton(driver, 'Custom token'); - await driver.fill( - '[data-testid="import-tokens-modal-custom-address"]', - tokenAddress, - ); - await driver.waitForSelector('p.mm-box--color-error-default'); - await driver.fill( - '[data-testid="import-tokens-modal-custom-symbol"]', - symbol, - ); - await driver.delay(2000); - await driver.clickElement({ text: 'Next', tag: 'button' }); - await driver.clickElement( - '[data-testid="import-tokens-modal-import-button"]', - ); - await driver.findElement({ text: 'Token imported', tag: 'h6' }); - }; - - it('should sort alphabetically and by decreasing balance', async function () { + it('should sort tokens alphabetically and by decreasing balance', async function () { await withFixtures( { - ...fixtures, + ...testFixtures, title: (this as Context).test?.fullTitle(), }, async ({ driver }: { driver: Driver }) => { await unlockWallet(driver); - await importToken(driver); - - const tokenListBeforeSorting = await driver.findElements( - '[data-testid="multichain-token-list-button"]', - ); - const tokenSymbolsBeforeSorting = await Promise.all( - tokenListBeforeSorting.map(async (tokenElement) => { - return tokenElement.getText(); - }), - ); - - assert.ok(tokenSymbolsBeforeSorting[0].includes('Ethereum')); - - await driver.clickElement('[data-testid="sort-by-popover-toggle"]'); - await driver.clickElement('[data-testid="sortByAlphabetically"]'); - await driver.delay(regularDelayMs); - const tokenListAfterSortingAlphabetically = await driver.findElements( - '[data-testid="multichain-token-list-button"]', - ); - const tokenListSymbolsAfterSortingAlphabetically = await Promise.all( - tokenListAfterSortingAlphabetically.map(async (tokenElement) => { - return tokenElement.getText(); - }), - ); + const homePage = new HomePage(driver); + const assetListPage = new AssetListPage(driver); - assert.ok( - tokenListSymbolsAfterSortingAlphabetically[0].includes('ABC'), + await homePage.check_pageIsLoaded(); + await assetListPage.importCustomToken( + customTokenAddress, + customTokenSymbol, ); - await driver.clickElement('[data-testid="sort-by-popover-toggle"]'); - await driver.clickElement('[data-testid="sortByDecliningBalance"]'); + const initialTokenList = await assetListPage.getTokenListNames(); + assert.ok(initialTokenList[0].includes('Ethereum')); + await assetListPage.sortTokenList('alphabetically'); - await driver.delay(regularDelayMs); - const tokenListBeforeSortingByDecliningBalance = - await driver.findElements( - '[data-testid="multichain-token-list-button"]', - ); - - const tokenListAfterSortingByDecliningBalance = await Promise.all( - tokenListBeforeSortingByDecliningBalance.map(async (tokenElement) => { - return tokenElement.getText(); - }), + await driver.waitUntil( + async () => { + const sortedTokenList = await assetListPage.getTokenListNames(); + return sortedTokenList[0].includes(customTokenSymbol); + }, + { timeout: regularDelayMs, interval: 100 }, ); - assert.ok( - tokenListAfterSortingByDecliningBalance[0].includes('Ethereum'), + + await assetListPage.sortTokenList('decliningBalance'); + await driver.waitUntil( + async () => { + const sortedTokenListByBalance = + await assetListPage.getTokenListNames(); + return sortedTokenListByBalance[0].includes('Ethereum'); + }, + { timeout: regularDelayMs, interval: 100 }, ); }, ); From f8a0e0e72452234bd1964bc2ef4da137ca9eb009 Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Fri, 20 Dec 2024 06:53:54 +0000 Subject: [PATCH 10/16] lint --- .../modules/bridge-utils/bridge.util.test.ts | 4 +- .../e2e/page-objects/pages/home/asset-list.ts | 2 + .../page-objects/pages/token-overview-page.ts | 6 +-- test/e2e/tests/tokens/import-tokens.spec.ts | 11 ++-- test/e2e/tests/tokens/token-list.spec.ts | 52 ++++++++++++++----- 5 files changed, 54 insertions(+), 21 deletions(-) diff --git a/shared/modules/bridge-utils/bridge.util.test.ts b/shared/modules/bridge-utils/bridge.util.test.ts index 555de4fc2516..b9fea3db1ea8 100644 --- a/shared/modules/bridge-utils/bridge.util.test.ts +++ b/shared/modules/bridge-utils/bridge.util.test.ts @@ -149,7 +149,7 @@ describe('Bridge utils', () => { (fetchWithCache as jest.Mock).mockRejectedValue(mockError); - await expect(fetchBridgeFeatureFlags()).rejects.toThrowError(mockError); + await expect(fetchBridgeFeatureFlags()).rejects.toThrow(mockError); }); }); @@ -223,7 +223,7 @@ describe('Bridge utils', () => { (fetchWithCache as jest.Mock).mockRejectedValue(mockError); - await expect(fetchBridgeTokens('0xa')).rejects.toThrowError(mockError); + await expect(fetchBridgeTokens('0xa')).rejects.toThrow(mockError); }); }); diff --git a/test/e2e/page-objects/pages/home/asset-list.ts b/test/e2e/page-objects/pages/home/asset-list.ts index 6553dd6b700b..3f2574c69e97 100644 --- a/test/e2e/page-objects/pages/home/asset-list.ts +++ b/test/e2e/page-objects/pages/home/asset-list.ts @@ -342,6 +342,7 @@ class AssetListPage { /** * Checks if the token increase/decrease percentage is displayed correctly for a specific token + * * @param address - The token address to check * @param expectedPercentage - The expected percentage value (e.g. '+0.02%') */ @@ -363,6 +364,7 @@ class AssetListPage { /** * Checks if the token increase/decrease value is displayed correctly + * * @param expectedValue - The expected value (e.g. '+$50.00') */ async check_tokenIncreaseValue(expectedValue: string): Promise { diff --git a/test/e2e/page-objects/pages/token-overview-page.ts b/test/e2e/page-objects/pages/token-overview-page.ts index 2d8d5abf6bfc..474d8bca0717 100644 --- a/test/e2e/page-objects/pages/token-overview-page.ts +++ b/test/e2e/page-objects/pages/token-overview-page.ts @@ -6,17 +6,17 @@ class TokenOverviewPage { private readonly sendButton = { text: 'Send', css: '.icon-button', - } + }; private readonly receiveButton = { text: 'Receive', css: '.icon-button', - } + }; private readonly swapButton = { text: 'Swap', css: '.icon-button', - } + }; constructor(driver: Driver) { this.driver = driver; diff --git a/test/e2e/tests/tokens/import-tokens.spec.ts b/test/e2e/tests/tokens/import-tokens.spec.ts index 9b8200dc2b99..0a840a1ee304 100644 --- a/test/e2e/tests/tokens/import-tokens.spec.ts +++ b/test/e2e/tests/tokens/import-tokens.spec.ts @@ -1,16 +1,16 @@ import AssetListPage from '../../page-objects/pages/home/asset-list'; import HomePage from '../../page-objects/pages/home/homepage'; -import { strict as assert } from 'assert'; import { defaultGanacheOptions, withFixtures, unlockWallet, } from '../../helpers'; import FixtureBuilder from '../../fixture-builder'; +import { Mockttp } from '../../mock-e2e'; describe('Import flow', function () { - async function mockPriceFetch(mockServer: any) { + async function mockPriceFetch(mockServer: Mockttp) { return [ await mockServer .forGet('https://price.api.cx.metamask.io/v2/chains/1/spot-prices') @@ -72,7 +72,11 @@ describe('Import flow', function () { const homePage = new HomePage(driver); const assetListPage = new AssetListPage(driver); await homePage.check_pageIsLoaded(); - await assetListPage.importMultipleTokensBySearch(['CHAIN', 'CHANGE', 'CHAI']); + await assetListPage.importMultipleTokensBySearch([ + 'CHAIN', + 'CHANGE', + 'CHAI', + ]); const tokenList = new AssetListPage(driver); await tokenList.check_tokenItemNumber(5); // Linea & Mainnet Eth @@ -80,7 +84,6 @@ describe('Import flow', function () { await tokenList.check_tokenIsDisplayed('Chain Games'); await tokenList.check_tokenIsDisplayed('Changex'); await tokenList.check_tokenIsDisplayed('Chai'); - }, ); }); diff --git a/test/e2e/tests/tokens/token-list.spec.ts b/test/e2e/tests/tokens/token-list.spec.ts index 6b55db3e1dd1..6e4d01466471 100644 --- a/test/e2e/tests/tokens/token-list.spec.ts +++ b/test/e2e/tests/tokens/token-list.spec.ts @@ -6,7 +6,6 @@ import { CHAIN_IDS } from '../../../../shared/constants/network'; import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils'; import FixtureBuilder from '../../fixture-builder'; import { - clickNestedButton, defaultGanacheOptions, unlockWallet, withFixtures, @@ -29,7 +28,10 @@ describe('Token List', function () { }, }; - const mockEmptyPrices = async (mockServer: Mockttp, chainIdToMock: string) => { + const mockEmptyPrices = async ( + mockServer: Mockttp, + chainIdToMock: string, + ) => { return mockServer .forGet( `https://price.api.cx.metamask.io/v2/chains/${parseInt( @@ -43,7 +45,10 @@ describe('Token List', function () { })); }; - const mockEmptyHistoricalPrices = async (mockServer: Mockttp, address: string) => { + const mockEmptyHistoricalPrices = async ( + mockServer: Mockttp, + address: string, + ) => { return mockServer .forGet( `https://price.api.cx.metamask.io/v1/chains/${chainId}/historical-prices/${address}`, @@ -57,7 +62,10 @@ describe('Token List', function () { const mockSpotPrices = async ( mockServer: Mockttp, chainIdToMock: string, - prices: Record + prices: Record< + string, + { price: number; pricePercentChange1d: number; marketCap: number } + >, ) => { return mockServer .forGet( @@ -75,7 +83,7 @@ describe('Token List', function () { const mockHistoricalPrices = async ( mockServer: Mockttp, address: string, - price: number + price: number, ) => { return mockServer .forGet( @@ -115,10 +123,12 @@ describe('Token List', function () { await homePage.check_pageIsLoaded(); await assetListPage.importCustomToken(tokenAddress, symbol); - const percentageNative = await assetListPage.getAssetPercentageIncreaseDecrease(zeroAddress()); + const percentageNative = + await assetListPage.getAssetPercentageIncreaseDecrease(zeroAddress()); assert.equal(percentageNative, ''); - const percentage = await assetListPage.getAssetPercentageIncreaseDecrease(tokenAddress); + const percentage = + await assetListPage.getAssetPercentageIncreaseDecrease(tokenAddress); assert.equal(percentage, ''); }, ); @@ -126,8 +136,16 @@ describe('Token List', function () { it('shows percentage increase for an ERC20 token with prices available', async function () { const ethConversionInUsd = 10000; - const marketData = { price: 0.123, marketCap: 12, pricePercentChange1d: 0.05 }; - const marketDataNative = { price: 0.123, marketCap: 12, pricePercentChange1d: 0.02 }; + const marketData = { + price: 0.123, + marketCap: 12, + pricePercentChange1d: 0.05, + }; + const marketDataNative = { + price: 0.123, + marketCap: 12, + pricePercentChange1d: 0.02, + }; await withFixtures( { @@ -139,7 +157,11 @@ describe('Token List', function () { [zeroAddress()]: marketDataNative, [tokenAddress.toLowerCase()]: marketData, }), - await mockHistoricalPrices(mockServer, tokenAddress, marketData.price), + await mockHistoricalPrices( + mockServer, + tokenAddress, + marketData.price, + ), ], }, async ({ driver }: { driver: Driver }) => { @@ -151,8 +173,14 @@ describe('Token List', function () { await homePage.check_pageIsLoaded(); await assetListPage.importCustomToken(tokenAddress, symbol); - await assetListPage.check_tokenIncreasePercentage(zeroAddress(), '+0.02%'); - await assetListPage.check_tokenIncreasePercentage(tokenAddress, '+0.05%'); + await assetListPage.check_tokenIncreasePercentage( + zeroAddress(), + '+0.02%', + ); + await assetListPage.check_tokenIncreasePercentage( + tokenAddress, + '+0.05%', + ); await assetListPage.check_tokenIncreaseValue('+$50.00'); }, ); From 10f2f7a6488caf358f68a49126c665b9461604d9 Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Fri, 20 Dec 2024 07:28:10 +0000 Subject: [PATCH 11/16] use largeDelay --- shared/modules/bridge-utils/bridge.util.test.ts | 4 ++-- test/e2e/tests/tokens/token-sort.spec.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/shared/modules/bridge-utils/bridge.util.test.ts b/shared/modules/bridge-utils/bridge.util.test.ts index b9fea3db1ea8..555de4fc2516 100644 --- a/shared/modules/bridge-utils/bridge.util.test.ts +++ b/shared/modules/bridge-utils/bridge.util.test.ts @@ -149,7 +149,7 @@ describe('Bridge utils', () => { (fetchWithCache as jest.Mock).mockRejectedValue(mockError); - await expect(fetchBridgeFeatureFlags()).rejects.toThrow(mockError); + await expect(fetchBridgeFeatureFlags()).rejects.toThrowError(mockError); }); }); @@ -223,7 +223,7 @@ describe('Bridge utils', () => { (fetchWithCache as jest.Mock).mockRejectedValue(mockError); - await expect(fetchBridgeTokens('0xa')).rejects.toThrow(mockError); + await expect(fetchBridgeTokens('0xa')).rejects.toThrowError(mockError); }); }); diff --git a/test/e2e/tests/tokens/token-sort.spec.ts b/test/e2e/tests/tokens/token-sort.spec.ts index 70e6d26c62fa..ddf9c33cceb1 100644 --- a/test/e2e/tests/tokens/token-sort.spec.ts +++ b/test/e2e/tests/tokens/token-sort.spec.ts @@ -6,7 +6,7 @@ import { defaultGanacheOptions, unlockWallet, withFixtures, - regularDelayMs, + largeDelayMs, } from '../../helpers'; import { Driver } from '../../webdriver/driver'; import HomePage from '../../page-objects/pages/home/homepage'; @@ -52,7 +52,7 @@ describe('Token List Sorting', function () { const sortedTokenList = await assetListPage.getTokenListNames(); return sortedTokenList[0].includes(customTokenSymbol); }, - { timeout: regularDelayMs, interval: 100 }, + { timeout: largeDelayMs, interval: 100 }, ); await assetListPage.sortTokenList('decliningBalance'); @@ -62,7 +62,7 @@ describe('Token List Sorting', function () { await assetListPage.getTokenListNames(); return sortedTokenListByBalance[0].includes('Ethereum'); }, - { timeout: regularDelayMs, interval: 100 }, + { timeout: largeDelayMs, interval: 100 }, ); }, ); From 3c2f9705ef46779d4ba574539a3f01643b38de44 Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Fri, 20 Dec 2024 10:12:22 +0000 Subject: [PATCH 12/16] alphabetize token overview page, use better assertion for percentage --- .../e2e/page-objects/pages/home/asset-list.ts | 58 +++++++++++++------ .../page-objects/pages/token-overview-page.ts | 16 ++--- test/e2e/tests/tokens/token-list.spec.ts | 19 +++--- 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/test/e2e/page-objects/pages/home/asset-list.ts b/test/e2e/page-objects/pages/home/asset-list.ts index 3f2574c69e97..7f578a4ad43b 100644 --- a/test/e2e/page-objects/pages/home/asset-list.ts +++ b/test/e2e/page-objects/pages/home/asset-list.ts @@ -84,9 +84,6 @@ class AssetListPage { private readonly tokenIncreaseDecreaseValue = '[data-testid="token-increase-decrease-value"]'; - private readonly tokenIncreaseDecreasePercentageGeneral = - '[data-testid="token-increase-decrease-percentage"]'; - constructor(driver: Driver) { this.driver = driver; } @@ -341,40 +338,67 @@ class AssetListPage { } /** - * Checks if the token increase/decrease percentage is displayed correctly for a specific token + * Checks if the token's general increase or decrease percentage is displayed correctly * * @param address - The token address to check - * @param expectedPercentage - The expected percentage value (e.g. '+0.02%') + * @param expectedChange - The expected change percentage value (e.g. '+0.02%' or '-0.03%') */ - async check_tokenIncreasePercentage( + async check_tokenGeneralChangePercentage( address: string, - expectedPercentage: string, + expectedChange: string, ): Promise { - console.log(`Checking token increase percentage for address ${address}`); + console.log( + `Checking token general change percentage for address ${address}`, + ); const isPresent = await this.driver.isElementPresentAndVisible({ - css: `[data-testid="token-increase-decrease-percentage-${address}"]`, - text: expectedPercentage, + css: this.tokenPercentage(address), + text: expectedChange, }); if (!isPresent) { throw new Error( - `Token increase percentage ${expectedPercentage} not found for address ${address}`, + `Token general change percentage ${expectedChange} not found for address ${address}`, ); } } + /** + * Checks if the token's percentage change element does not exist + * + * @param address - The token address to check + */ + async check_tokenGeneralChangePercentageNotPresent( + address: string, + ): Promise { + console.log( + `Checking token general change percentage is not present for address ${address}`, + ); + const isPresent = await this.driver.isElementPresent({ + css: this.tokenPercentage(address), + }); + if (isPresent) { + throw new Error( + `Token general change percentage element should not exist for address ${address}`, + ); + } + } + /** - * Checks if the token increase/decrease value is displayed correctly + * Checks if the token's general increase or decrease value is displayed correctly * - * @param expectedValue - The expected value (e.g. '+$50.00') + * @param expectedChangeValue - The expected change value (e.g. '+$50.00' or '-$30.00') */ - async check_tokenIncreaseValue(expectedValue: string): Promise { - console.log(`Checking token increase value ${expectedValue}`); + async check_tokenGeneralChangeValue( + expectedChangeValue: string, + ): Promise { + console.log(`Checking token general change value ${expectedChangeValue}`); const isPresent = await this.driver.isElementPresentAndVisible({ css: this.tokenIncreaseDecreaseValue, - text: expectedValue, + text: expectedChangeValue, }); if (!isPresent) { - throw new Error(`Token increase value ${expectedValue} not found`); + throw new Error( + `Token general change value ${expectedChangeValue} not found`, + ); } } } diff --git a/test/e2e/page-objects/pages/token-overview-page.ts b/test/e2e/page-objects/pages/token-overview-page.ts index 474d8bca0717..46e93ed490c7 100644 --- a/test/e2e/page-objects/pages/token-overview-page.ts +++ b/test/e2e/page-objects/pages/token-overview-page.ts @@ -3,13 +3,13 @@ import { Driver } from '../../webdriver/driver'; class TokenOverviewPage { private driver: Driver; - private readonly sendButton = { - text: 'Send', + private readonly receiveButton = { + text: 'Receive', css: '.icon-button', }; - private readonly receiveButton = { - text: 'Receive', + private readonly sendButton = { + text: 'Send', css: '.icon-button', }; @@ -38,14 +38,14 @@ class TokenOverviewPage { console.log('Token overview page is loaded'); } - async clickSend(): Promise { - await this.driver.clickElement(this.sendButton); - } - async clickReceive(): Promise { await this.driver.clickElement(this.receiveButton); } + async clickSend(): Promise { + await this.driver.clickElement(this.sendButton); + } + async clickSwap(): Promise { await this.driver.clickElement(this.swapButton); } diff --git a/test/e2e/tests/tokens/token-list.spec.ts b/test/e2e/tests/tokens/token-list.spec.ts index 6e4d01466471..9a5269e1328f 100644 --- a/test/e2e/tests/tokens/token-list.spec.ts +++ b/test/e2e/tests/tokens/token-list.spec.ts @@ -123,13 +123,12 @@ describe('Token List', function () { await homePage.check_pageIsLoaded(); await assetListPage.importCustomToken(tokenAddress, symbol); - const percentageNative = - await assetListPage.getAssetPercentageIncreaseDecrease(zeroAddress()); - assert.equal(percentageNative, ''); - - const percentage = - await assetListPage.getAssetPercentageIncreaseDecrease(tokenAddress); - assert.equal(percentage, ''); + await assetListPage.check_tokenGeneralChangePercentageNotPresent( + zeroAddress(), + ); + await assetListPage.check_tokenGeneralChangePercentageNotPresent( + tokenAddress, + ); }, ); }); @@ -173,15 +172,15 @@ describe('Token List', function () { await homePage.check_pageIsLoaded(); await assetListPage.importCustomToken(tokenAddress, symbol); - await assetListPage.check_tokenIncreasePercentage( + await assetListPage.check_tokenGeneralChangePercentage( zeroAddress(), '+0.02%', ); - await assetListPage.check_tokenIncreasePercentage( + await assetListPage.check_tokenGeneralChangePercentage( tokenAddress, '+0.05%', ); - await assetListPage.check_tokenIncreaseValue('+$50.00'); + await assetListPage.check_tokenGeneralChangeValue('+$50.00'); }, ); }); From 86ae434204d942b2cb434d009529f0d5e84ecf65 Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Fri, 20 Dec 2024 10:25:45 +0000 Subject: [PATCH 13/16] update warning assertion --- test/e2e/page-objects/pages/send/send-token-page.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/test/e2e/page-objects/pages/send/send-token-page.ts b/test/e2e/page-objects/pages/send/send-token-page.ts index 29c3f322ee65..6b3dd2a78d78 100644 --- a/test/e2e/page-objects/pages/send/send-token-page.ts +++ b/test/e2e/page-objects/pages/send/send-token-page.ts @@ -209,13 +209,10 @@ class SendTokenPage { */ async check_warningMessage(warningText: string): Promise { console.log(`Checking if warning message "${warningText}" is displayed`); - const warning = await this.driver.findElement(this.warning); - const text = await warning.getText(); - assert.equal( - text, - warningText, - `Expected warning message to be "${warningText}", got "${text}"`, - ); + await this.driver.waitForSelector({ + css: this.warning, + text: warningText, + }); console.log('Warning message validation successful'); } } From 8ea70077355be9ee51fd0176b42134289c7e63eb Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Fri, 20 Dec 2024 10:52:35 +0000 Subject: [PATCH 14/16] linting --- .../e2e/page-objects/pages/home/asset-list.ts | 28 +++++++++---------- test/e2e/tests/tokens/token-list.spec.ts | 1 - 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/test/e2e/page-objects/pages/home/asset-list.ts b/test/e2e/page-objects/pages/home/asset-list.ts index 7f578a4ad43b..2c1ff4866f53 100644 --- a/test/e2e/page-objects/pages/home/asset-list.ts +++ b/test/e2e/page-objects/pages/home/asset-list.ts @@ -361,26 +361,26 @@ class AssetListPage { } } - /** + /** * Checks if the token's percentage change element does not exist * * @param address - The token address to check */ - async check_tokenGeneralChangePercentageNotPresent( - address: string, - ): Promise { - console.log( - `Checking token general change percentage is not present for address ${address}`, + async check_tokenGeneralChangePercentageNotPresent( + address: string, + ): Promise { + console.log( + `Checking token general change percentage is not present for address ${address}`, + ); + const isPresent = await this.driver.isElementPresent({ + css: this.tokenPercentage(address), + }); + if (isPresent) { + throw new Error( + `Token general change percentage element should not exist for address ${address}`, ); - const isPresent = await this.driver.isElementPresent({ - css: this.tokenPercentage(address), - }); - if (isPresent) { - throw new Error( - `Token general change percentage element should not exist for address ${address}`, - ); - } } + } /** * Checks if the token's general increase or decrease value is displayed correctly diff --git a/test/e2e/tests/tokens/token-list.spec.ts b/test/e2e/tests/tokens/token-list.spec.ts index 9a5269e1328f..4002142d595e 100644 --- a/test/e2e/tests/tokens/token-list.spec.ts +++ b/test/e2e/tests/tokens/token-list.spec.ts @@ -1,4 +1,3 @@ -import { strict as assert } from 'assert'; import { Mockttp } from 'mockttp'; import { Context } from 'mocha'; import { zeroAddress } from 'ethereumjs-util'; From a8ab1add7848bcef30465a7b5317baac04dd18f1 Mon Sep 17 00:00:00 2001 From: cmd-ob Date: Fri, 20 Dec 2024 12:25:55 +0000 Subject: [PATCH 15/16] remove getAssetPercentageIncreaseDecrease method --- test/e2e/page-objects/pages/home/asset-list.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test/e2e/page-objects/pages/home/asset-list.ts b/test/e2e/page-objects/pages/home/asset-list.ts index 2c1ff4866f53..c168a607dcdd 100644 --- a/test/e2e/page-objects/pages/home/asset-list.ts +++ b/test/e2e/page-objects/pages/home/asset-list.ts @@ -145,18 +145,6 @@ class AssetListPage { return tokenNames; } - async getAssetPercentageIncreaseDecrease( - assetAddress: string, - ): Promise { - console.log( - `Retrieving the percentage increase or decrease for ${assetAddress}`, - ); - const percentageElement = await this.driver.findElement( - this.tokenPercentage(assetAddress), - ); - const percentage = await percentageElement.getText(); - return percentage; - } async sortTokenList( sortBy: 'alphabetically' | 'decliningBalance', From c166dff475f6dba3f7c9c399eb966fafd2c1d09a Mon Sep 17 00:00:00 2001 From: Chloe Gao Date: Fri, 20 Dec 2024 14:23:12 +0100 Subject: [PATCH 16/16] fix lint --- test/e2e/page-objects/pages/home/asset-list.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/e2e/page-objects/pages/home/asset-list.ts b/test/e2e/page-objects/pages/home/asset-list.ts index c168a607dcdd..8c120b9879b7 100644 --- a/test/e2e/page-objects/pages/home/asset-list.ts +++ b/test/e2e/page-objects/pages/home/asset-list.ts @@ -145,7 +145,6 @@ class AssetListPage { return tokenNames; } - async sortTokenList( sortBy: 'alphabetically' | 'decliningBalance', ): Promise {