From eed6330a246007e94936449f4969cbea6cc46dba Mon Sep 17 00:00:00 2001 From: Daniel Izdebski Date: Thu, 16 Nov 2023 23:27:18 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(metamask):=20Add=20support=20f?= =?UTF-8?q?or=20approve=20permissions=20(#998)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wallets/metamask/src/metamask.ts | 16 +++++++++ .../actions/approvePermission.ts | 28 +++++++++++++++ .../pages/NotificationPage/actions/index.ts | 1 + .../src/pages/NotificationPage/page.ts | 25 ++++++++++++- .../pages/NotificationPage/selectors/index.ts | 4 ++- .../selectors/permissionPage.ts | 19 ++++++++++ .../e2e/metamask/approvePermission.spec.ts | 35 +++++++++++++++++++ .../e2e/metamask/rejectPermission.spec.ts | 21 +++++++++++ 8 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 wallets/metamask/src/pages/NotificationPage/actions/approvePermission.ts create mode 100644 wallets/metamask/src/pages/NotificationPage/selectors/permissionPage.ts create mode 100644 wallets/metamask/test/e2e/metamask/approvePermission.spec.ts create mode 100644 wallets/metamask/test/e2e/metamask/rejectPermission.spec.ts diff --git a/wallets/metamask/src/metamask.ts b/wallets/metamask/src/metamask.ts index e8b518cb1..f99f334ef 100644 --- a/wallets/metamask/src/metamask.ts +++ b/wallets/metamask/src/metamask.ts @@ -107,4 +107,20 @@ export class MetaMask { await this.notificationPage.rejectTransaction(this.extensionId) } + + async approvePermission(customSpendLimit?: number) { + if (!this.extensionId) { + throw NO_EXTENSION_ID_ERROR + } + + await this.notificationPage.approvePermission(this.extensionId, customSpendLimit) + } + + async rejectPermission() { + if (!this.extensionId) { + throw NO_EXTENSION_ID_ERROR + } + + await this.notificationPage.rejectPermission(this.extensionId) + } } diff --git a/wallets/metamask/src/pages/NotificationPage/actions/approvePermission.ts b/wallets/metamask/src/pages/NotificationPage/actions/approvePermission.ts new file mode 100644 index 000000000..6b221fccb --- /dev/null +++ b/wallets/metamask/src/pages/NotificationPage/actions/approvePermission.ts @@ -0,0 +1,28 @@ +import type { Page } from '@playwright/test' +import Selectors from '../selectors' + +const editTokenPermission = async (notificationPage: Page, customSpendLimit: number) => { + await notificationPage.locator(Selectors.PermissionPage.approve.editPermission.editPermissionButton).click() + + await notificationPage.locator(Selectors.PermissionPage.approve.editPermission.customSpendLimitButton).click() + + await notificationPage + .locator(Selectors.PermissionPage.approve.editPermission.customSpendLimitInput) + .fill(customSpendLimit.toString()) + + await notificationPage.locator(Selectors.PermissionPage.approve.editPermission.saveButton).click() +} + +const approveTokenPermission = async (notificationPage: Page) => { + await notificationPage.locator(Selectors.PermissionPage.approve.confirmButton).click() +} + +const rejectTokenPermission = async (notificationPage: Page) => { + await notificationPage.locator(Selectors.PermissionPage.approve.rejectButton).click() +} + +export const approvePermission = { + editSpendLimit: editTokenPermission, + approve: approveTokenPermission, + reject: rejectTokenPermission +} diff --git a/wallets/metamask/src/pages/NotificationPage/actions/index.ts b/wallets/metamask/src/pages/NotificationPage/actions/index.ts index a50a2449d..293eb9842 100644 --- a/wallets/metamask/src/pages/NotificationPage/actions/index.ts +++ b/wallets/metamask/src/pages/NotificationPage/actions/index.ts @@ -1,5 +1,6 @@ export * from './connectToDapp' export * from './signSimpleMessage' export * from './signStructuredMessage' +export * from './approvePermission' export * from './transaction' export * from './network' diff --git a/wallets/metamask/src/pages/NotificationPage/page.ts b/wallets/metamask/src/pages/NotificationPage/page.ts index d1a7a4f42..61303ed9b 100644 --- a/wallets/metamask/src/pages/NotificationPage/page.ts +++ b/wallets/metamask/src/pages/NotificationPage/page.ts @@ -1,7 +1,14 @@ import type { Page } from '@playwright/test' import { getNotificationPageAndWaitForLoad } from '../../utils/getNotificationPageAndWaitForLoad' import { waitFor } from '../../utils/waitFor' -import { connectToDapp, network, signSimpleMessage, signStructuredMessage, transaction } from './actions' +import { + approvePermission, + connectToDapp, + network, + signSimpleMessage, + signStructuredMessage, + transaction +} from './actions' import Selectors from './selectors' export class NotificationPage { @@ -91,4 +98,20 @@ export class NotificationPage { await transaction.reject(notificationPage) } + + async approvePermission(extensionId: string, customSpendLimit?: number) { + const notificationPage = await getNotificationPageAndWaitForLoad(this.page.context(), extensionId) + + if (customSpendLimit) { + await approvePermission.editSpendLimit(notificationPage, customSpendLimit) + } + + await approvePermission.approve(notificationPage) + } + + async rejectPermission(extensionId: string) { + const notificationPage = await getNotificationPageAndWaitForLoad(this.page.context(), extensionId) + + await approvePermission.reject(notificationPage) + } } diff --git a/wallets/metamask/src/pages/NotificationPage/selectors/index.ts b/wallets/metamask/src/pages/NotificationPage/selectors/index.ts index 576ff21a7..42a9037d4 100644 --- a/wallets/metamask/src/pages/NotificationPage/selectors/index.ts +++ b/wallets/metamask/src/pages/NotificationPage/selectors/index.ts @@ -1,9 +1,11 @@ import NetworkPage from './networkPage' +import PermissionPage from './permissionPage' import SignaturePage from './signaturePage' import TransactionPage from './transactionPage' export default { SignaturePage, NetworkPage, - TransactionPage + TransactionPage, + PermissionPage } diff --git a/wallets/metamask/src/pages/NotificationPage/selectors/permissionPage.ts b/wallets/metamask/src/pages/NotificationPage/selectors/permissionPage.ts new file mode 100644 index 000000000..5d9f3453b --- /dev/null +++ b/wallets/metamask/src/pages/NotificationPage/selectors/permissionPage.ts @@ -0,0 +1,19 @@ +import { createDataTestSelector } from '../../../utils/selectors/createDataTestSelector' + +const approve = { + editPermission: { + editPermissionButton: + '.confirm-approve-content__edit-submission-button-container .confirm-approve-content__medium-link-text.cursor-pointer', + customSpendLimitButton: + '.edit-approval-permission-modal-content .edit-approval-permission__edit-section__option:last-of-type .edit-approval-permission__edit-section__radio-button', + customSpendLimitInput: + '.edit-approval-permission-modal-content .edit-approval-permission__edit-section__option-input input', + saveButton: '.edit-approval-permission-modal-container .modal-container__footer > button.btn-primary' + }, + confirmButton: `.page-container__footer ${createDataTestSelector('page-container-footer-next')}`, + rejectButton: `.page-container__footer ${createDataTestSelector('page-container-footer-cancel')}` +} + +export default { + approve +} diff --git a/wallets/metamask/test/e2e/metamask/approvePermission.spec.ts b/wallets/metamask/test/e2e/metamask/approvePermission.spec.ts new file mode 100644 index 000000000..0cb69ec69 --- /dev/null +++ b/wallets/metamask/test/e2e/metamask/approvePermission.spec.ts @@ -0,0 +1,35 @@ +import { testWithMetaMask } from '../testWithMetaMask' + +const test = testWithMetaMask.extend<{ switchChainAndDeployToken: () => Promise }>({ + switchChainAndDeployToken: async ({ page, metamask }, use) => { + await use(async () => { + await page.locator('#addEthereumChain').click() + + await metamask.approveNewNetwork() + await metamask.approveSwitchNetwork() + + await expect(page.locator('#tokenAddresses')).toBeEmpty() + await page.locator('#createToken').click() + + await metamask.confirmTransaction() + }) + } +}) + +const { expect } = test + +test('should approve tokens with the default limit', async ({ page, metamask, switchChainAndDeployToken }) => { + await switchChainAndDeployToken() + + await page.locator('#approveTokens').click() + + await metamask.approvePermission() +}) + +test('should approve tokens with the custom limit', async ({ page, metamask, switchChainAndDeployToken }) => { + await switchChainAndDeployToken() + + await page.locator('#approveTokens').click() + + await metamask.approvePermission(420) +}) diff --git a/wallets/metamask/test/e2e/metamask/rejectPermission.spec.ts b/wallets/metamask/test/e2e/metamask/rejectPermission.spec.ts new file mode 100644 index 000000000..5e27d731e --- /dev/null +++ b/wallets/metamask/test/e2e/metamask/rejectPermission.spec.ts @@ -0,0 +1,21 @@ +import { testWithMetaMask } from '../testWithMetaMask' + +const test = testWithMetaMask + +const { expect } = test + +test('should reject approve request', async ({ page, metamask }) => { + await page.locator('#addEthereumChain').click() + + await metamask.approveNewNetwork() + await metamask.approveSwitchNetwork() + + await expect(page.locator('#tokenAddresses')).toBeEmpty() + await page.locator('#createToken').click() + + await metamask.confirmTransaction() + + await page.locator('#approveTokens').click() + + await metamask.rejectPermission() +})