Skip to content

Commit 41b46a0

Browse files
authored
test: [POM] Migrate portfolio e2e tests and permission requests tests to TS and Page Object Model (#29274)
## **Description** - Migrate portfolio e2e tests and permission requests e2e tests to TS and Page Object Model ``` test/e2e/tests/portfolio/portfolio-site.spec.ts test/e2e/json-rpc/wallet_revokePermissions.spec.ts test/e2e/json-rpc/wallet_requestPermissions.spec.ts ``` - Remove unused ganach setup [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27155?quickstart=1) ## **Related issues** ## **Manual testing steps** Check code readability, make sure tests pass. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
1 parent acdaefe commit 41b46a0

File tree

7 files changed

+75
-95
lines changed

7 files changed

+75
-95
lines changed

test/e2e/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,6 @@ export const DEFAULT_SOLANA_ACCOUNT =
7070

7171
/* Default (mocked) SOLANA balance used by the Solana RPC provider */
7272
export const DEFAULT_SOLANA_BALANCE = 1; // SOL
73+
74+
/* Title of the mocked E2E test empty HTML page */
75+
export const EMPTY_E2E_TEST_PAGE_TITLE = 'E2E Test Page';

test/e2e/json-rpc/wallet_requestPermissions.spec.js renamed to test/e2e/json-rpc/wallet_requestPermissions.spec.ts

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,42 @@
1-
const { strict: assert } = require('assert');
2-
const {
3-
defaultGanacheOptions,
4-
withFixtures,
5-
switchToNotificationWindow,
6-
switchToOrOpenDapp,
7-
unlockWallet,
8-
} = require('../helpers');
9-
const FixtureBuilder = require('../fixture-builder');
1+
import { strict as assert } from 'assert';
2+
import { withFixtures } from '../helpers';
3+
import FixtureBuilder from '../fixture-builder';
4+
import { loginWithBalanceValidation } from '../page-objects/flows/login.flow';
5+
import TestDapp from '../page-objects/pages/test-dapp';
106

117
describe('wallet_requestPermissions', function () {
128
it('executes a request permissions on eth_accounts event', async function () {
139
await withFixtures(
1410
{
1511
dapp: true,
16-
fixtures: new FixtureBuilder()
17-
.withPermissionControllerConnectedToTestDapp()
18-
.build(),
19-
ganacheOptions: defaultGanacheOptions,
20-
title: this.test.title,
12+
fixtures: new FixtureBuilder().build(),
13+
title: this.test?.title,
2114
},
2215
async ({ driver }) => {
23-
await unlockWallet(driver);
16+
await loginWithBalanceValidation(driver);
17+
const testDapp = new TestDapp(driver);
18+
await testDapp.openTestDappPage();
2419

2520
// wallet_requestPermissions
26-
await driver.openNewPage(`http://127.0.0.1:8080`);
27-
2821
const requestPermissionsRequest = JSON.stringify({
2922
jsonrpc: '2.0',
3023
method: 'wallet_requestPermissions',
3124
params: [{ eth_accounts: {} }],
3225
});
33-
3426
await driver.executeScript(
3527
`window.ethereum.request(${requestPermissionsRequest})`,
3628
);
3729

38-
await switchToNotificationWindow(driver);
39-
40-
await driver.clickElement({
41-
text: 'Connect',
42-
tag: 'button',
43-
});
44-
45-
await switchToOrOpenDapp(driver);
30+
// confirm connect account
31+
await testDapp.confirmConnectAccountModal();
4632

4733
const getPermissionsRequest = JSON.stringify({
4834
method: 'wallet_getPermissions',
4935
});
50-
5136
const getPermissions = await driver.executeScript(
5237
`return window.ethereum.request(${getPermissionsRequest})`,
5338
);
54-
55-
assert.strictEqual(getPermissions[0].parentCapability, 'eth_accounts');
39+
assert.strictEqual(getPermissions[1].parentCapability, 'eth_accounts');
5640
},
5741
);
5842
});

test/e2e/json-rpc/wallet_revokePermissions.spec.js renamed to test/e2e/json-rpc/wallet_revokePermissions.spec.ts

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
const { strict: assert } = require('assert');
2-
3-
const {
4-
withFixtures,
5-
defaultGanacheOptions,
6-
unlockWallet,
7-
openDapp,
8-
} = require('../helpers');
9-
const FixtureBuilder = require('../fixture-builder');
1+
import { strict as assert } from 'assert';
2+
import { ACCOUNT_1, withFixtures } from '../helpers';
3+
import FixtureBuilder from '../fixture-builder';
4+
import TestDapp from '../page-objects/pages/test-dapp';
5+
import { loginWithBalanceValidation } from '../page-objects/flows/login.flow';
106

117
describe('Revoke Dapp Permissions', function () {
128
it('should revoke dapp permissions ', async function () {
@@ -16,18 +12,13 @@ describe('Revoke Dapp Permissions', function () {
1612
fixtures: new FixtureBuilder()
1713
.withPermissionControllerConnectedToTestDapp()
1814
.build(),
19-
ganacheOptions: defaultGanacheOptions,
2015
title: this.test?.fullTitle(),
2116
},
2217
async ({ driver }) => {
23-
await unlockWallet(driver);
24-
25-
await openDapp(driver);
26-
27-
await driver.findElement({
28-
text: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1',
29-
css: '#accounts',
30-
});
18+
await loginWithBalanceValidation(driver);
19+
const testDapp = new TestDapp(driver);
20+
await testDapp.openTestDappPage();
21+
await testDapp.check_connectedAccounts(ACCOUNT_1);
3122

3223
// wallet_revokePermissions request
3324
const revokePermissionsRequest = JSON.stringify({
@@ -43,15 +34,10 @@ describe('Revoke Dapp Permissions', function () {
4334
const result = await driver.executeScript(
4435
`return window.ethereum.request(${revokePermissionsRequest})`,
4536
);
46-
4737
// Response of method call
4838
assert.deepEqual(result, null);
4939

50-
// TODO: Fix having to reload dapp as it is not the proper behavior in production, issue with test setup.
51-
await driver.executeScript(`window.location.reload()`);
52-
53-
// You cannot use driver.findElement() with an empty string, so use xpath
54-
await driver.findElement({ xpath: '//span[@id="accounts"][.=""]' });
40+
await testDapp.check_connectedAccounts(ACCOUNT_1, false);
5541
},
5642
);
5743
});

test/e2e/page-objects/pages/home/homepage.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class HomePage {
3939
testId: 'popover-close',
4040
};
4141

42+
private readonly portfolioLink = '[data-testid="portfolio-link"]';
43+
4244
private readonly privacyBalanceToggle = {
4345
testId: 'sensitive-toggle',
4446
};
@@ -99,6 +101,11 @@ class HomePage {
99101
await this.driver.clickElement(this.nftTab);
100102
}
101103

104+
async openPortfolioPage(): Promise<void> {
105+
console.log(`Open portfolio page on homepage`);
106+
await this.driver.clickElement(this.portfolioLink);
107+
}
108+
102109
async refreshErc20TokenList(): Promise<void> {
103110
console.log(`Refresh the ERC20 token list`);
104111
await this.driver.clickElement(this.erc20TokenDropdown);

test/e2e/page-objects/pages/test-dapp.ts

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,16 @@ class TestDapp {
273273
await this.driver.clickElement(this.erc20TokenTransferButton);
274274
}
275275

276+
async confirmConnectAccountModal() {
277+
console.log('Confirm connect account modal in notification window');
278+
await this.driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
279+
await this.driver.waitForSelector(this.connectMetaMaskMessage);
280+
await this.driver.clickElementAndWaitForWindowToClose(
281+
this.confirmDialogButton,
282+
);
283+
await this.driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
284+
}
285+
276286
/**
277287
* Connect account to test dapp.
278288
*
@@ -289,25 +299,18 @@ class TestDapp {
289299
}) {
290300
console.log('Connect account to test dapp');
291301
await this.driver.clickElement(this.connectAccountButton);
292-
await this.driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
293-
await this.driver.waitForSelector(this.connectMetaMaskMessage);
294302
if (connectAccountButtonEnabled) {
295-
await this.driver.clickElementAndWaitForWindowToClose(
296-
this.confirmDialogButton,
297-
);
303+
await this.confirmConnectAccountModal();
298304
} else {
305+
await this.driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
306+
await this.driver.waitForSelector(this.connectMetaMaskMessage);
299307
const confirmConnectDialogButton = await this.driver.findElement(
300308
this.confirmDialogButton,
301309
);
302310
assert.equal(await confirmConnectDialogButton.isEnabled(), false);
303311
}
304-
305312
if (publicAddress) {
306-
await this.driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
307-
await this.driver.waitForSelector({
308-
css: this.connectedAccount,
309-
text: publicAddress.toLowerCase(),
310-
});
313+
await this.check_connectedAccounts(publicAddress);
311314
await this.driver.waitForSelector(this.localhostNetworkMessage);
312315
}
313316
}
@@ -332,28 +335,30 @@ class TestDapp {
332335
await this.driver.clickElement(this.revokePermissionButton);
333336
await this.driver.refresh();
334337
await this.check_pageIsLoaded();
335-
await this.driver.assertElementNotPresent({
336-
css: this.connectedAccount,
337-
text: publicAddress.toLowerCase(),
338-
});
338+
await this.check_connectedAccounts(publicAddress, false);
339339
}
340340

341341
/**
342-
* Verifies the accounts connected to the test dapp.
342+
* Check if the accounts connected to the test dapp.
343343
*
344-
* @param connectedAccounts - The expected connected accounts separated by a comma. If no accounts are connected we can omit the param.
344+
* @param connectedAccounts - Account addresses to check if connected to test dapp, separated by a comma.
345+
* @param shouldBeConnected - Whether the accounts should be connected to test dapp. Defaults to true.
345346
*/
346-
async check_connectedAccounts(connectedAccounts: string = '') {
347-
console.log('Verify connected accounts');
348-
if (connectedAccounts) {
347+
async check_connectedAccounts(
348+
connectedAccounts: string,
349+
shouldBeConnected: boolean = true,
350+
) {
351+
if (shouldBeConnected) {
352+
console.log('Verify connected accounts:', connectedAccounts);
349353
await this.driver.waitForSelector({
350354
css: this.connectedAccount,
351-
text: connectedAccounts,
355+
text: connectedAccounts.toLowerCase(),
352356
});
353357
} else {
354-
await this.driver.waitForSelector({
358+
console.log('Verify accounts not connected:', connectedAccounts);
359+
await this.driver.assertElementNotPresent({
355360
css: this.connectedAccount,
356-
text: ' ',
361+
text: connectedAccounts.toLowerCase(),
357362
});
358363
}
359364
}

test/e2e/tests/portfolio/portfolio-site.spec.js renamed to test/e2e/tests/portfolio/portfolio-site.spec.ts

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
const {
2-
withFixtures,
3-
unlockWallet,
4-
defaultGanacheOptions,
5-
} = require('../../helpers');
6-
const FixtureBuilder = require('../../fixture-builder');
7-
const { emptyHtmlPage } = require('../../mock-e2e');
1+
import { MockttpServer } from 'mockttp';
2+
import { withFixtures } from '../../helpers';
3+
import { EMPTY_E2E_TEST_PAGE_TITLE } from '../../constants';
4+
import FixtureBuilder from '../../fixture-builder';
5+
import { emptyHtmlPage } from '../../mock-e2e';
6+
import HomePage from '../../page-objects/pages/home/homepage';
7+
import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow';
88

99
describe('Portfolio site', function () {
10-
async function mockPortfolioSite(mockServer) {
10+
async function mockPortfolioSite(mockServer: MockttpServer) {
1111
return await mockServer
1212
.forGet('https://portfolio.metamask.io/')
1313
.withQuery({
@@ -27,18 +27,15 @@ describe('Portfolio site', function () {
2727
{
2828
dapp: true,
2929
fixtures: new FixtureBuilder().build(),
30-
ganacheOptions: defaultGanacheOptions,
31-
title: this.test.fullTitle(),
30+
title: this.test?.fullTitle(),
3231
testSpecificMock: mockPortfolioSite,
3332
},
3433
async ({ driver }) => {
35-
await unlockWallet(driver);
34+
await loginWithBalanceValidation(driver);
35+
await new HomePage(driver).openPortfolioPage();
3636

3737
// Click Portfolio site
38-
await driver.clickElement('[data-testid="portfolio-link"]');
39-
await driver.waitUntilXWindowHandles(2);
40-
const windowHandles = await driver.getAllWindowHandles();
41-
await driver.switchToWindowWithTitle('E2E Test Page', windowHandles);
38+
await driver.switchToWindowWithTitle(EMPTY_E2E_TEST_PAGE_TITLE);
4239

4340
// Verify site
4441
await driver.waitForUrl({

test/e2e/tests/request-queuing/sendTx-revokePermissions.spec.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ describe('Request Queuing', function () {
4141
// Open test dapp
4242
const testDapp = new TestDapp(driver);
4343
await testDapp.openTestDappPage();
44-
await testDapp.check_connectedAccounts(
45-
DEFAULT_FIXTURE_ACCOUNT.toLowerCase(),
46-
);
44+
await testDapp.check_connectedAccounts(DEFAULT_FIXTURE_ACCOUNT);
4745

4846
// Trigger a tx
4947
await testDapp.clickSimpleSendButton();
@@ -71,7 +69,7 @@ describe('Request Queuing', function () {
7169
await driver.waitUntilXWindowHandles(2);
7270

7371
// Cleared eth_accounts account label
74-
await testDapp.check_connectedAccounts();
72+
await testDapp.check_connectedAccounts(DEFAULT_FIXTURE_ACCOUNT, false);
7573
},
7674
);
7775
});

0 commit comments

Comments
 (0)