From 0f37ab01cf026fe0c5a8a77d8b4a095e60eb563c Mon Sep 17 00:00:00 2001 From: Chloe Gao Date: Thu, 12 Dec 2024 11:45:57 +0100 Subject: [PATCH 1/5] migrate tests --- test/e2e/constants.ts | 3 ++ test/e2e/page-objects/pages/home/homepage.ts | 7 +++ .../tests/portfolio/portfolio-site.spec.js | 3 +- .../tests/portfolio/portfolio-site.spec.ts | 46 +++++++++++++++++++ 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 test/e2e/tests/portfolio/portfolio-site.spec.ts diff --git a/test/e2e/constants.ts b/test/e2e/constants.ts index 7123d3e4114a..8296cdc3e3d1 100644 --- a/test/e2e/constants.ts +++ b/test/e2e/constants.ts @@ -70,3 +70,6 @@ export const DEFAULT_SOLANA_ACCOUNT = /* Default (mocked) SOLANA balance used by the Solana RPC provider */ export const DEFAULT_SOLANA_BALANCE = 1; // SOL + +/* Title of the mocked E2E test empty HTML page */ +export const EMPTY_E2E_TEST_PAGE_TITLE = 'E2E Test Page'; diff --git a/test/e2e/page-objects/pages/home/homepage.ts b/test/e2e/page-objects/pages/home/homepage.ts index 6b6197eed797..90a986df9344 100644 --- a/test/e2e/page-objects/pages/home/homepage.ts +++ b/test/e2e/page-objects/pages/home/homepage.ts @@ -29,6 +29,8 @@ class HomePage { private readonly popoverCloseButton = '[data-testid="popover-close"]'; + private readonly portfolioLink = '[data-testid="portfolio-link"]'; + private readonly sendButton = '[data-testid="eth-overview-send"]'; private readonly tokensTab = '[data-testid="account-overview__asset-tab"]'; @@ -79,6 +81,11 @@ class HomePage { await this.driver.clickElement(this.nftTab); } + async openPortfolioPage(): Promise { + console.log(`Open portfolio page on homepage`); + await this.driver.clickElement(this.portfolioLink); + } + async startSendFlow(): Promise { await this.driver.clickElement(this.sendButton); } diff --git a/test/e2e/tests/portfolio/portfolio-site.spec.js b/test/e2e/tests/portfolio/portfolio-site.spec.js index cba9c0452522..16ded9960dbf 100644 --- a/test/e2e/tests/portfolio/portfolio-site.spec.js +++ b/test/e2e/tests/portfolio/portfolio-site.spec.js @@ -4,6 +4,7 @@ const { defaultGanacheOptions, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); +import { DEFAULT_FIXTURE_ACCOUNT } from '../../constants'; const { emptyHtmlPage } = require('../../mock-e2e'); describe('Portfolio site', function () { @@ -33,7 +34,7 @@ describe('Portfolio site', function () { }, async ({ driver }) => { await unlockWallet(driver); - + throw new Error('test'); // Click Portfolio site await driver.clickElement('[data-testid="portfolio-link"]'); await driver.waitUntilXWindowHandles(2); diff --git a/test/e2e/tests/portfolio/portfolio-site.spec.ts b/test/e2e/tests/portfolio/portfolio-site.spec.ts new file mode 100644 index 000000000000..5c2d66876bb6 --- /dev/null +++ b/test/e2e/tests/portfolio/portfolio-site.spec.ts @@ -0,0 +1,46 @@ +import { withFixtures } from '../../helpers'; +import { EMPTY_E2E_TEST_PAGE_TITLE } from '../../constants'; +import FixtureBuilder from '../../fixture-builder'; +import { emptyHtmlPage } from '../../mock-e2e'; +import HomePage from '../../page-objects/pages/home/homepage'; +import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; + +describe('Portfolio site', function () { + async function mockPortfolioSite(mockServer: any) { + return await mockServer + .forGet('https://portfolio.metamask.io/') + .withQuery({ + metamaskEntry: 'ext_portfolio_button', + metametricsId: 'null', + }) + .thenCallback(() => { + return { + statusCode: 200, + body: emptyHtmlPage(), + }; + }); + } + + it('should link to the portfolio site @no-mmi', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder().build(), + title: this.test?.fullTitle(), + testSpecificMock: mockPortfolioSite, + }, + async ({ driver }) => { + await loginWithBalanceValidation(driver); + await new HomePage(driver).openPortfolioPage(); + + // Click Portfolio site + await driver.switchToWindowWithTitle(EMPTY_E2E_TEST_PAGE_TITLE); + + // Verify site + await driver.waitForUrl({ + url: 'https://portfolio.metamask.io/?metamaskEntry=ext_portfolio_button&metametricsId=null&metricsEnabled=false&marketingEnabled=false', + }); + }, + ); + }); +}); From ee6196e3af1c0ec50cbb0d1cc52c740d59a62a6e Mon Sep 17 00:00:00 2001 From: Chloe Gao Date: Thu, 12 Dec 2024 15:46:23 +0100 Subject: [PATCH 2/5] fix tests --- ...c.js => wallet_requestPermissions.spec.ts} | 41 +++++---------- ...ec.js => wallet_revokePermissions.spec.ts} | 34 ++++--------- test/e2e/page-objects/pages/test-dapp.ts | 51 +++++++++++++------ 3 files changed, 59 insertions(+), 67 deletions(-) rename test/e2e/json-rpc/{wallet_requestPermissions.spec.js => wallet_requestPermissions.spec.ts} (53%) rename test/e2e/json-rpc/{wallet_revokePermissions.spec.js => wallet_revokePermissions.spec.ts} (52%) diff --git a/test/e2e/json-rpc/wallet_requestPermissions.spec.js b/test/e2e/json-rpc/wallet_requestPermissions.spec.ts similarity index 53% rename from test/e2e/json-rpc/wallet_requestPermissions.spec.js rename to test/e2e/json-rpc/wallet_requestPermissions.spec.ts index 5484fdf73d80..a77880e1b7b7 100644 --- a/test/e2e/json-rpc/wallet_requestPermissions.spec.js +++ b/test/e2e/json-rpc/wallet_requestPermissions.spec.ts @@ -1,12 +1,8 @@ -const { strict: assert } = require('assert'); -const { - defaultGanacheOptions, - withFixtures, - switchToNotificationWindow, - switchToOrOpenDapp, - unlockWallet, -} = require('../helpers'); -const FixtureBuilder = require('../fixture-builder'); +import { strict as assert } from 'assert'; +import { withFixtures } from '../helpers'; +import FixtureBuilder from '../fixture-builder'; +import { loginWithBalanceValidation } from '../page-objects/flows/login.flow'; +import TestDapp from '../page-objects/pages/test-dapp'; describe('wallet_requestPermissions', function () { it('executes a request permissions on eth_accounts event', async function () { @@ -14,45 +10,34 @@ describe('wallet_requestPermissions', function () { { dapp: true, fixtures: new FixtureBuilder() - .withPermissionControllerConnectedToTestDapp() .build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.title, + title: this.test?.title, }, - async ({ driver }) => { - await unlockWallet(driver); + async ({ driver }: { driver: any }) => { + await loginWithBalanceValidation(driver); + const testDapp = new TestDapp(driver); + await testDapp.openTestDappPage(); // wallet_requestPermissions - await driver.openNewPage(`http://127.0.0.1:8080`); - const requestPermissionsRequest = JSON.stringify({ jsonrpc: '2.0', method: 'wallet_requestPermissions', params: [{ eth_accounts: {} }], }); - await driver.executeScript( `window.ethereum.request(${requestPermissionsRequest})`, ); - await switchToNotificationWindow(driver); - - await driver.clickElement({ - text: 'Connect', - tag: 'button', - }); - - await switchToOrOpenDapp(driver); + // confirm connect account + await testDapp.confirmConnectAccountModal(); const getPermissionsRequest = JSON.stringify({ method: 'wallet_getPermissions', }); - const getPermissions = await driver.executeScript( `return window.ethereum.request(${getPermissionsRequest})`, ); - - assert.strictEqual(getPermissions[0].parentCapability, 'eth_accounts'); + assert.strictEqual(getPermissions[1].parentCapability, 'eth_accounts'); }, ); }); diff --git a/test/e2e/json-rpc/wallet_revokePermissions.spec.js b/test/e2e/json-rpc/wallet_revokePermissions.spec.ts similarity index 52% rename from test/e2e/json-rpc/wallet_revokePermissions.spec.js rename to test/e2e/json-rpc/wallet_revokePermissions.spec.ts index 70d2fd3ba572..2ca353b2d742 100644 --- a/test/e2e/json-rpc/wallet_revokePermissions.spec.js +++ b/test/e2e/json-rpc/wallet_revokePermissions.spec.ts @@ -1,12 +1,8 @@ -const { strict: assert } = require('assert'); - -const { - withFixtures, - defaultGanacheOptions, - unlockWallet, - openDapp, -} = require('../helpers'); -const FixtureBuilder = require('../fixture-builder'); +import { strict as assert } from 'assert'; +import { ACCOUNT_1, withFixtures } from '../helpers'; +import FixtureBuilder from '../fixture-builder'; +import TestDapp from '../page-objects/pages/test-dapp'; +import { loginWithBalanceValidation } from '../page-objects/flows/login.flow'; describe('Revoke Dapp Permissions', function () { it('should revoke dapp permissions ', async function () { @@ -16,18 +12,13 @@ describe('Revoke Dapp Permissions', function () { fixtures: new FixtureBuilder() .withPermissionControllerConnectedToTestDapp() .build(), - ganacheOptions: defaultGanacheOptions, title: this.test?.fullTitle(), }, async ({ driver }) => { - await unlockWallet(driver); - - await openDapp(driver); - - await driver.findElement({ - text: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1', - css: '#accounts', - }); + await loginWithBalanceValidation(driver); + const testDapp = new TestDapp(driver); + await testDapp.openTestDappPage(); + await testDapp.check_ifAccountIsConnected(ACCOUNT_1); // wallet_revokePermissions request const revokePermissionsRequest = JSON.stringify({ @@ -43,15 +34,10 @@ describe('Revoke Dapp Permissions', function () { const result = await driver.executeScript( `return window.ethereum.request(${revokePermissionsRequest})`, ); - // Response of method call assert.deepEqual(result, null); - // TODO: Fix having to reload dapp as it is not the proper behavior in production, issue with test setup. - await driver.executeScript(`window.location.reload()`); - - // You cannot use driver.findElement() with an empty string, so use xpath - await driver.findElement({ xpath: '//span[@id="accounts"][.=""]' }); + await testDapp.check_ifAccountIsConnected(ACCOUNT_1, false); }, ); }); diff --git a/test/e2e/page-objects/pages/test-dapp.ts b/test/e2e/page-objects/pages/test-dapp.ts index c31ee497152e..3e1802a8ab89 100644 --- a/test/e2e/page-objects/pages/test-dapp.ts +++ b/test/e2e/page-objects/pages/test-dapp.ts @@ -267,6 +267,16 @@ class TestDapp { await this.driver.clickElement(this.erc20TokenTransferButton); } + async confirmConnectAccountModal() { + console.log('Confirm connect account modal in notification window'); + await this.driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await this.driver.waitForSelector(this.connectMetaMaskMessage); + await this.driver.clickElementAndWaitForWindowToClose( + this.confirmDialogButton, + ); + await this.driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); + } + /** * Connect account to test dapp. * @@ -275,17 +285,8 @@ class TestDapp { async connectAccount(publicAddress: string) { console.log('Connect account to test dapp'); await this.driver.clickElement(this.connectAccountButton); - await this.driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); - await this.driver.waitForSelector(this.connectMetaMaskMessage); - - await this.driver.clickElementAndWaitForWindowToClose( - this.confirmDialogButton, - ); - await this.driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp); - await this.driver.waitForSelector({ - css: this.connectedAccount, - text: publicAddress.toLowerCase(), - }); + await this.confirmConnectAccountModal(); + await this.check_ifAccountIsConnected(publicAddress); await this.driver.waitForSelector(this.localhostNetworkMessage); } @@ -309,10 +310,30 @@ class TestDapp { await this.driver.clickElement(this.revokePermissionButton); await this.driver.refresh(); await this.check_pageIsLoaded(); - await this.driver.assertElementNotPresent({ - css: this.connectedAccount, - text: publicAddress.toLowerCase(), - }); + await this.check_ifAccountIsConnected(publicAddress, false); + } + + /** + * Check if the account is connected to the test dapp. + * + * @param publicAddress - The public address to check if the account is connected to the test dapp. + * @param shouldBeConnected - Whether the account should be connected to the test dapp. Defaults to true. + */ + async check_ifAccountIsConnected( + publicAddress: string, + shouldBeConnected: boolean = true, + ) { + if (shouldBeConnected) { + await this.driver.waitForSelector({ + css: this.connectedAccount, + text: publicAddress.toLowerCase(), + }); + } else { + await this.driver.assertElementNotPresent({ + css: this.connectedAccount, + text: publicAddress.toLowerCase(), + }); + } } /** From b667ba698f1006e684544955cf213fe48e79d6b6 Mon Sep 17 00:00:00 2001 From: Chloe Gao Date: Tue, 17 Dec 2024 14:16:44 +0100 Subject: [PATCH 3/5] fix --- .../wallet_requestPermissions.spec.ts | 5 +- .../tests/portfolio/portfolio-site.spec.js | 51 ------------------- .../tests/portfolio/portfolio-site.spec.ts | 3 +- 3 files changed, 4 insertions(+), 55 deletions(-) delete mode 100644 test/e2e/tests/portfolio/portfolio-site.spec.js diff --git a/test/e2e/json-rpc/wallet_requestPermissions.spec.ts b/test/e2e/json-rpc/wallet_requestPermissions.spec.ts index a77880e1b7b7..d2a033dcf3c5 100644 --- a/test/e2e/json-rpc/wallet_requestPermissions.spec.ts +++ b/test/e2e/json-rpc/wallet_requestPermissions.spec.ts @@ -9,11 +9,10 @@ describe('wallet_requestPermissions', function () { await withFixtures( { dapp: true, - fixtures: new FixtureBuilder() - .build(), + fixtures: new FixtureBuilder().build(), title: this.test?.title, }, - async ({ driver }: { driver: any }) => { + async ({ driver }) => { await loginWithBalanceValidation(driver); const testDapp = new TestDapp(driver); await testDapp.openTestDappPage(); diff --git a/test/e2e/tests/portfolio/portfolio-site.spec.js b/test/e2e/tests/portfolio/portfolio-site.spec.js deleted file mode 100644 index 16ded9960dbf..000000000000 --- a/test/e2e/tests/portfolio/portfolio-site.spec.js +++ /dev/null @@ -1,51 +0,0 @@ -const { - withFixtures, - unlockWallet, - defaultGanacheOptions, -} = require('../../helpers'); -const FixtureBuilder = require('../../fixture-builder'); -import { DEFAULT_FIXTURE_ACCOUNT } from '../../constants'; -const { emptyHtmlPage } = require('../../mock-e2e'); - -describe('Portfolio site', function () { - async function mockPortfolioSite(mockServer) { - return await mockServer - .forGet('https://portfolio.metamask.io/') - .withQuery({ - metamaskEntry: 'ext_portfolio_button', - metametricsId: 'null', - }) - .thenCallback(() => { - return { - statusCode: 200, - body: emptyHtmlPage(), - }; - }); - } - - it('should link to the portfolio site @no-mmi', async function () { - await withFixtures( - { - dapp: true, - fixtures: new FixtureBuilder().build(), - ganacheOptions: defaultGanacheOptions, - title: this.test.fullTitle(), - testSpecificMock: mockPortfolioSite, - }, - async ({ driver }) => { - await unlockWallet(driver); - throw new Error('test'); - // Click Portfolio site - await driver.clickElement('[data-testid="portfolio-link"]'); - await driver.waitUntilXWindowHandles(2); - const windowHandles = await driver.getAllWindowHandles(); - await driver.switchToWindowWithTitle('E2E Test Page', windowHandles); - - // Verify site - await driver.waitForUrl({ - url: 'https://portfolio.metamask.io/?metamaskEntry=ext_portfolio_button&metametricsId=null&metricsEnabled=false&marketingEnabled=false', - }); - }, - ); - }); -}); diff --git a/test/e2e/tests/portfolio/portfolio-site.spec.ts b/test/e2e/tests/portfolio/portfolio-site.spec.ts index 5c2d66876bb6..f630de50f1da 100644 --- a/test/e2e/tests/portfolio/portfolio-site.spec.ts +++ b/test/e2e/tests/portfolio/portfolio-site.spec.ts @@ -1,3 +1,4 @@ +import { MockttpServer } from 'mockttp'; import { withFixtures } from '../../helpers'; import { EMPTY_E2E_TEST_PAGE_TITLE } from '../../constants'; import FixtureBuilder from '../../fixture-builder'; @@ -6,7 +7,7 @@ import HomePage from '../../page-objects/pages/home/homepage'; import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow'; describe('Portfolio site', function () { - async function mockPortfolioSite(mockServer: any) { + async function mockPortfolioSite(mockServer: MockttpServer) { return await mockServer .forGet('https://portfolio.metamask.io/') .withQuery({ From 0dfc59bd2696e10b9c9f51623bfa85da3f67c5ca Mon Sep 17 00:00:00 2001 From: Chloe Gao Date: Tue, 17 Dec 2024 17:42:06 +0100 Subject: [PATCH 4/5] fix lint --- .../json-rpc/wallet_revokePermissions.spec.ts | 4 +- test/e2e/page-objects/pages/test-dapp.ts | 40 +++++-------------- .../sendTx-revokePermissions.spec.ts | 6 +-- 3 files changed, 15 insertions(+), 35 deletions(-) diff --git a/test/e2e/json-rpc/wallet_revokePermissions.spec.ts b/test/e2e/json-rpc/wallet_revokePermissions.spec.ts index 2ca353b2d742..5c444b5ecf01 100644 --- a/test/e2e/json-rpc/wallet_revokePermissions.spec.ts +++ b/test/e2e/json-rpc/wallet_revokePermissions.spec.ts @@ -18,7 +18,7 @@ describe('Revoke Dapp Permissions', function () { await loginWithBalanceValidation(driver); const testDapp = new TestDapp(driver); await testDapp.openTestDappPage(); - await testDapp.check_ifAccountIsConnected(ACCOUNT_1); + await testDapp.check_connectedAccounts(ACCOUNT_1); // wallet_revokePermissions request const revokePermissionsRequest = JSON.stringify({ @@ -37,7 +37,7 @@ describe('Revoke Dapp Permissions', function () { // Response of method call assert.deepEqual(result, null); - await testDapp.check_ifAccountIsConnected(ACCOUNT_1, false); + await testDapp.check_connectedAccounts(ACCOUNT_1, false); }, ); }); diff --git a/test/e2e/page-objects/pages/test-dapp.ts b/test/e2e/page-objects/pages/test-dapp.ts index 67745f666c60..09c450c7a49a 100644 --- a/test/e2e/page-objects/pages/test-dapp.ts +++ b/test/e2e/page-objects/pages/test-dapp.ts @@ -292,7 +292,7 @@ class TestDapp { console.log('Connect account to test dapp'); await this.driver.clickElement(this.connectAccountButton); await this.confirmConnectAccountModal(); - await this.check_ifAccountIsConnected(publicAddress); + await this.check_connectedAccounts(publicAddress); await this.driver.waitForSelector(this.localhostNetworkMessage); } @@ -316,48 +316,30 @@ class TestDapp { await this.driver.clickElement(this.revokePermissionButton); await this.driver.refresh(); await this.check_pageIsLoaded(); - await this.check_ifAccountIsConnected(publicAddress, false); + await this.check_connectedAccounts(publicAddress, false); } /** - * Check if the account is connected to the test dapp. + * Check if the accounts connected to the test dapp. * - * @param publicAddress - The public address to check if the account is connected to the test dapp. - * @param shouldBeConnected - Whether the account should be connected to the test dapp. Defaults to true. + * @param connectedAccounts - Account addresses to check if connected to test dapp, separated by a comma. + * @param shouldBeConnected - Whether the accounts should be connected to test dapp. Defaults to true. */ - async check_ifAccountIsConnected( - publicAddress: string, + async check_connectedAccounts( + connectedAccounts: string, shouldBeConnected: boolean = true, ) { if (shouldBeConnected) { + console.log('Verify connected accounts:', connectedAccounts); await this.driver.waitForSelector({ css: this.connectedAccount, - text: publicAddress.toLowerCase(), + text: connectedAccounts.toLowerCase(), }); } else { + console.log('Verify accounts not connected:', connectedAccounts); await this.driver.assertElementNotPresent({ css: this.connectedAccount, - text: publicAddress.toLowerCase(), - }); - } - } - - /** - * Verifies the accounts connected to the test dapp. - * - * @param connectedAccounts - The expected connected accounts separated by a comma. If no accounts are connected we can omit the param. - */ - async check_connectedAccounts(connectedAccounts: string = '') { - console.log('Verify connected accounts'); - if (connectedAccounts) { - await this.driver.waitForSelector({ - css: this.connectedAccount, - text: connectedAccounts, - }); - } else { - await this.driver.waitForSelector({ - css: this.connectedAccount, - text: ' ', + text: connectedAccounts.toLowerCase(), }); } } diff --git a/test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.ts b/test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.ts index c5ff864df99c..9f5454404806 100644 --- a/test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.ts +++ b/test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.ts @@ -41,9 +41,7 @@ describe('Request Queuing', function () { // Open test dapp const testDapp = new TestDapp(driver); await testDapp.openTestDappPage(); - await testDapp.check_connectedAccounts( - DEFAULT_FIXTURE_ACCOUNT.toLowerCase(), - ); + await testDapp.check_connectedAccounts(DEFAULT_FIXTURE_ACCOUNT); // Trigger a tx await testDapp.clickSimpleSendButton(); @@ -71,7 +69,7 @@ describe('Request Queuing', function () { await driver.waitUntilXWindowHandles(2); // Cleared eth_accounts account label - await testDapp.check_connectedAccounts(); + await testDapp.check_connectedAccounts(DEFAULT_FIXTURE_ACCOUNT, false); }, ); }); From 8053e22f55f2f829cbaff5a325c59107bf8ea252 Mon Sep 17 00:00:00 2001 From: Chloe Gao Date: Wed, 18 Dec 2024 10:21:07 +0100 Subject: [PATCH 5/5] fix lint --- test/e2e/page-objects/pages/test-dapp.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/test/e2e/page-objects/pages/test-dapp.ts b/test/e2e/page-objects/pages/test-dapp.ts index fe29bd86c143..6b82926fd9ca 100644 --- a/test/e2e/page-objects/pages/test-dapp.ts +++ b/test/e2e/page-objects/pages/test-dapp.ts @@ -299,9 +299,20 @@ class TestDapp { }) { console.log('Connect account to test dapp'); await this.driver.clickElement(this.connectAccountButton); - await this.confirmConnectAccountModal(); - await this.check_connectedAccounts(publicAddress); - await this.driver.waitForSelector(this.localhostNetworkMessage); + if (connectAccountButtonEnabled) { + await this.confirmConnectAccountModal(); + } else { + await this.driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog); + await this.driver.waitForSelector(this.connectMetaMaskMessage); + const confirmConnectDialogButton = await this.driver.findElement( + this.confirmDialogButton, + ); + assert.equal(await confirmConnectDialogButton.isEnabled(), false); + } + if (publicAddress) { + await this.check_connectedAccounts(publicAddress); + await this.driver.waitForSelector(this.localhostNetworkMessage); + } } async createDepositTransaction() {