From 11af60dedce9df888b18dd838c5c73f4f0d2f81e Mon Sep 17 00:00:00 2001 From: juan-langa Date: Tue, 17 Dec 2024 21:11:45 +0100 Subject: [PATCH] Phantom - confirmTransaction function updates and tests --- wallets/phantom/src/cypress/Phantom.ts | 4 +- .../actions/approvePermission.ts | 2 +- .../NotificationPage/actions/transaction.ts | 84 +++---------------- .../playwright/pages/NotificationPage/page.ts | 6 +- .../pages/NotificationPage/transactionPage.ts | 38 +-------- wallets/phantom/src/type/GasSettings.ts | 7 +- .../playwright/e2e/confirmTransaction.spec.ts | 30 +++++++ 7 files changed, 53 insertions(+), 118 deletions(-) create mode 100644 wallets/phantom/test/playwright/e2e/confirmTransaction.spec.ts diff --git a/wallets/phantom/src/cypress/Phantom.ts b/wallets/phantom/src/cypress/Phantom.ts index 2ba44acda..a55979178 100644 --- a/wallets/phantom/src/cypress/Phantom.ts +++ b/wallets/phantom/src/cypress/Phantom.ts @@ -60,8 +60,8 @@ export default class Phantom { * @param accounts - Optional array of account addresses to connect * @returns True if the connection was successful */ - async connectToDapp(accounts?: string[]): Promise { - await this.phantomPlaywright.connectToDapp(accounts) + async connectToDapp(account?: string): Promise { + await this.phantomPlaywright.connectToDapp(account) return true } diff --git a/wallets/phantom/src/playwright/pages/NotificationPage/actions/approvePermission.ts b/wallets/phantom/src/playwright/pages/NotificationPage/actions/approvePermission.ts index bba71a048..ee36b6ac7 100644 --- a/wallets/phantom/src/playwright/pages/NotificationPage/actions/approvePermission.ts +++ b/wallets/phantom/src/playwright/pages/NotificationPage/actions/approvePermission.ts @@ -23,7 +23,7 @@ const approveTokenPermission = async (notificationPage: Page, gasSetting: GasSet } const rejectTokenPermission = async (notificationPage: Page) => { - await notificationPage.locator(Selectors.ActionFooter.rejectActionButton).click() + await notificationPage.locator(Selectors.ActionFooter.cancelActionButton).click() } export const approvePermission = { diff --git a/wallets/phantom/src/playwright/pages/NotificationPage/actions/transaction.ts b/wallets/phantom/src/playwright/pages/NotificationPage/actions/transaction.ts index 672429366..e6812142a 100644 --- a/wallets/phantom/src/playwright/pages/NotificationPage/actions/transaction.ts +++ b/wallets/phantom/src/playwright/pages/NotificationPage/actions/transaction.ts @@ -26,8 +26,8 @@ const confirmTransaction = async (notificationPage: Page, options: GasSettings) } } - // By default, the `site` gas setting is used. - if (gasSetting === 'site') { + // By default, the `Average` gas setting is used. + if (gasSetting === 'Average') { await notificationPage.locator(Selectors.ActionFooter.confirmActionButton).click() await handleNftSetApprovalForAll(notificationPage) @@ -38,81 +38,17 @@ const confirmTransaction = async (notificationPage: Page, options: GasSettings) // TODO: This button can be invisible in case of a network issue. Verify this, and handle in the future. await notificationPage.locator(Selectors.TransactionPage.editGasFeeMenu.editGasFeeButton).click() - const estimationNotAvailableErrorMessage = (gasSetting: string) => - `[ConfirmTransaction] Estimated fee is not available for the "${gasSetting}" gas setting. By default, Phantom would use the "site" gas setting in this case, however, this is not YOUR intention.` - - const handleLowMediumOrAggressiveGasSetting = async ( - gasSetting: string, - selectors: { button: string; maxFee: string } - ) => { - if ((await notificationPage.locator(selectors.maxFee).textContent()) === '--') { - throw new Error(estimationNotAvailableErrorMessage(gasSetting)) - } - - await notificationPage.locator(selectors.button).click() - } - - if (gasSetting === 'low') { - await handleLowMediumOrAggressiveGasSetting(gasSetting, Selectors.TransactionPage.editGasFeeMenu.lowGasFee) - } else if (gasSetting === 'market') { - await handleLowMediumOrAggressiveGasSetting(gasSetting, Selectors.TransactionPage.editGasFeeMenu.marketGasFee) - } else if (gasSetting === 'aggressive') { - await handleLowMediumOrAggressiveGasSetting(gasSetting, Selectors.TransactionPage.editGasFeeMenu.aggressiveGasFee) - } else { - await notificationPage.locator(Selectors.TransactionPage.editGasFeeMenu.advancedGasFeeButton).click() - - await notificationPage.locator(Selectors.TransactionPage.editGasFeeMenu.advancedGasFeeMenu.maxBaseFeeInput).fill('') - await notificationPage - .locator(Selectors.TransactionPage.editGasFeeMenu.advancedGasFeeMenu.maxBaseFeeInput) - .fill(gasSetting.maxBaseFee.toString()) - - await notificationPage - .locator(Selectors.TransactionPage.editGasFeeMenu.advancedGasFeeMenu.priorityFeeInput) - .fill('') - await notificationPage - .locator(Selectors.TransactionPage.editGasFeeMenu.advancedGasFeeMenu.priorityFeeInput) - .fill(gasSetting.priorityFee.toString()) - - if (gasSetting.gasLimit) { - await notificationPage - .locator(Selectors.TransactionPage.editGasFeeMenu.advancedGasFeeMenu.gasLimitEditButton) - .click() - - await notificationPage.locator(Selectors.TransactionPage.editGasFeeMenu.advancedGasFeeMenu.gasLimitInput).fill('') - await notificationPage - .locator(Selectors.TransactionPage.editGasFeeMenu.advancedGasFeeMenu.gasLimitInput) - .fill(gasSetting.gasLimit.toString()) - - const gasLimitErrorLocator = notificationPage.locator( - Selectors.TransactionPage.editGasFeeMenu.advancedGasFeeMenu.gasLimitError - ) - const isGasLimitErrorHidden = await waitFor(() => gasLimitErrorLocator.isHidden(), 1_000, false) // TODO: Extract & make configurable - - if (!isGasLimitErrorHidden) { - const errorText = await gasLimitErrorLocator.textContent({ - timeout: 1_000 // TODO: Extract & make configurable - }) - - throw new Error(`[ConfirmTransaction] Invalid gas limit: ${errorText}`) - } - } - - await notificationPage.locator(Selectors.TransactionPage.editGasFeeMenu.advancedGasFeeMenu.saveButton).click() + const handleSlowOrFastGasSetting = async (selector: string) => { + await notificationPage.locator(selector).click() } - // We wait until the tooltip is not visible anymore. This indicates a gas setting was changed. - // Ideally, we would wait until the edit button changes its text, i.e., "Site" -> "Aggressive", however, this is not possible right now. - // For some unknown reason, if the manual gas setting is too high (>1 ETH), the edit button displays "Site" instead of "Advanced" ¯\_(ツ)_/¯ - const waitForAction = async () => { - const isTooltipVisible = await notificationPage - .locator(Selectors.TransactionPage.editGasFeeMenu.editGasFeeButtonToolTip) - .isVisible() - - return !isTooltipVisible + if (gasSetting === 'Slow') { + await handleSlowOrFastGasSetting(Selectors.TransactionPage.editGasFeeMenu.slowGasFeeButton) + } else if (gasSetting === 'Fast') { + await handleSlowOrFastGasSetting(Selectors.TransactionPage.editGasFeeMenu.fastGasFeeButton) } - // TODO: Extract & make configurable - await waitFor(waitForAction, 3_000, true) + await notificationPage.locator(Selectors.TransactionPage.editGasFeeMenu.saveButton).click() await notificationPage.locator(Selectors.ActionFooter.confirmActionButton).click() @@ -154,7 +90,7 @@ const confirmTransactionAndWaitForMining = async (walletPage: Page, notification } const rejectTransaction = async (notificationPage: Page) => { - await notificationPage.locator(Selectors.ActionFooter.rejectActionButton).click() + await notificationPage.locator(Selectors.ActionFooter.cancelActionButton).click() } export const transaction = { diff --git a/wallets/phantom/src/playwright/pages/NotificationPage/page.ts b/wallets/phantom/src/playwright/pages/NotificationPage/page.ts index 59cecc7e1..73dfd6e4e 100644 --- a/wallets/phantom/src/playwright/pages/NotificationPage/page.ts +++ b/wallets/phantom/src/playwright/pages/NotificationPage/page.ts @@ -77,7 +77,7 @@ export class NotificationPage { async confirmTransaction(extensionId: string, options?: { gasSetting?: GasSettings }) { const notificationPage = await getNotificationPageAndWaitForLoad(this.page.context(), extensionId) - await transaction.confirm(notificationPage, options?.gasSetting ?? 'site') + await transaction.confirm(notificationPage, options?.gasSetting ?? 'Average') } async rejectTransaction(extensionId: string) { @@ -89,7 +89,7 @@ export class NotificationPage { async confirmTransactionAndWaitForMining(extensionId: string, options?: { gasSetting?: GasSettings }) { const notificationPage = await getNotificationPageAndWaitForLoad(this.page.context(), extensionId) - await transaction.confirmAndWaitForMining(this.page, notificationPage, options?.gasSetting ?? 'site') + await transaction.confirmAndWaitForMining(this.page, notificationPage, options?.gasSetting ?? 'Average') } async approveTokenPermission( @@ -102,7 +102,7 @@ export class NotificationPage { await approvePermission.editTokenPermission(notificationPage, options.spendLimit) } - await approvePermission.approve(notificationPage, options?.gasSetting ?? 'site') + await approvePermission.approve(notificationPage, options?.gasSetting ?? 'Average') } async rejectTokenPermission(extensionId: string) { diff --git a/wallets/phantom/src/selectors/pages/NotificationPage/transactionPage.ts b/wallets/phantom/src/selectors/pages/NotificationPage/transactionPage.ts index ed4a9c9c0..1748add70 100644 --- a/wallets/phantom/src/selectors/pages/NotificationPage/transactionPage.ts +++ b/wallets/phantom/src/selectors/pages/NotificationPage/transactionPage.ts @@ -1,38 +1,8 @@ -import { createDataTestSelector } from '../../createDataTestSelector' - -const advancedGasFeeMenu = { - maxBaseFeeInput: createDataTestSelector('base-fee-input'), - priorityFeeInput: createDataTestSelector('priority-fee-input'), - gasLimitEditButton: createDataTestSelector('advanced-gas-fee-edit'), - gasLimitInput: createDataTestSelector('gas-limit-input'), - gasLimitError: `div:has(> ${createDataTestSelector('gas-limit-input')}) + .form-field__error`, - saveButton: '.popover-footer > button.btn-primary' -} - -const lowGasFee = { - button: createDataTestSelector('edit-gas-fee-item-low'), - maxFee: `${createDataTestSelector('edit-gas-fee-item-low')} .edit-gas-item__fee-estimate` -} - -const marketGasFee = { - button: createDataTestSelector('edit-gas-fee-item-medium'), - maxFee: `${createDataTestSelector('edit-gas-fee-item-medium')} .edit-gas-item__fee-estimate` -} - -const aggressiveGasFee = { - button: createDataTestSelector('edit-gas-fee-item-high'), - maxFee: `${createDataTestSelector('edit-gas-fee-item-high')} .edit-gas-item__fee-estimate` -} - const editGasFeeMenu = { - editGasFeeButton: createDataTestSelector('edit-gas-fee-icon'), - editGasFeeButtonToolTip: '.edit-gas-fee-button .info-tooltip', - lowGasFee, - marketGasFee, - aggressiveGasFee, - siteSuggestedGasFeeButton: createDataTestSelector('edit-gas-fee-item-dappSuggested'), - advancedGasFeeButton: createDataTestSelector('edit-gas-fee-item-custom'), - advancedGasFeeMenu + editGasFeeButton: 'div > div p:has-text("Network Fee")', + slowGasFeeButton: 'div > div p:has-text("Slow")', + fastGasFeeButton: 'div > div p:has-text("Fast")', + saveButton: 'button:has-text("Save")' } const nftApproveAllConfirmationPopup = { diff --git a/wallets/phantom/src/type/GasSettings.ts b/wallets/phantom/src/type/GasSettings.ts index 7ffb8a370..e1ecd9870 100644 --- a/wallets/phantom/src/type/GasSettings.ts +++ b/wallets/phantom/src/type/GasSettings.ts @@ -1,10 +1,9 @@ import { z } from 'zod' export const GasSettingValidation = z.union([ - z.literal('low'), - z.literal('market'), - z.literal('aggressive'), - z.literal('site'), + z.literal('Slow'), + z.literal('Fast'), + z.literal('Average'), z .object({ maxBaseFee: z.number(), diff --git a/wallets/phantom/test/playwright/e2e/confirmTransaction.spec.ts b/wallets/phantom/test/playwright/e2e/confirmTransaction.spec.ts new file mode 100644 index 000000000..52ebbc335 --- /dev/null +++ b/wallets/phantom/test/playwright/e2e/confirmTransaction.spec.ts @@ -0,0 +1,30 @@ +import { connectPhantomToTestDapp } from '../commonSteps/connectPhantomToTestDapp' +import synpress from '../synpress' + +const test = synpress + +const { expect } = test + +test('should confirm contract deployment with default gas setting', async ({ page, phantom }) => { + connectPhantomToTestDapp(page, phantom) + + await expect(page.locator('#tokenAddresses')).toBeEmpty() + await page.locator('#createToken').click() + + await phantom.confirmTransaction() + + await expect(page.locator('#tokenAddresses')).toContainText('Creation Failed') +}) + +;(['Slow', 'Fast'] as const).forEach((gasSetting) => { + test(`should confirm contract deployment with ${gasSetting} gas setting`, async ({ page, phantom }) => { + connectPhantomToTestDapp(page, phantom) + + await expect(page.locator('#tokenAddresses')).toBeEmpty() + await page.locator('#createToken').click() + + await phantom.confirmTransaction({ gasSetting }) + + await expect(page.locator('#tokenAddresses')).toContainText('Creation Failed') + }) +})