Skip to content

Commit

Permalink
✨ feat: Upgrade MetaMask to version 11.5.1
Browse files Browse the repository at this point in the history
  • Loading branch information
duckception committed Nov 27, 2023
1 parent 96a413e commit 7aeb8e5
Show file tree
Hide file tree
Showing 51 changed files with 347 additions and 378 deletions.
1 change: 0 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ export * from './createCache'
export * from './defineWalletSetup'
export * from './utils/createTempContextDir'
export * from './utils/removeTempContextDir'
export * from './utils/waitForExtensionOnLoadPage'
export * from './prepareExtension'
2 changes: 1 addition & 1 deletion packages/core/src/prepareExtension.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { downloadFile, ensureCacheDirExists, unzipArchive } from '.'

export const DEFAULT_METAMASK_VERSION = '10.25.0'
export const DEFAULT_METAMASK_VERSION = '11.5.1'
export const EXTENSION_DOWNLOAD_URL = `https://github.com/MetaMask/metamask-extension/releases/download/v${DEFAULT_METAMASK_VERSION}/metamask-chrome-${DEFAULT_METAMASK_VERSION}.zip`

// NOTE: This function is copied from `wallets/metamask/src/prepareExtension.ts` only TEMPORARILY!
Expand Down
1 change: 1 addition & 0 deletions packages/fixtures/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"scripts": {
"build": "pnpm run clean && pnpm run build:dist && pnpm run build:types",
"build:dist": "tsup",
"build:dist:watch": "tsup --watch",
"build:types": "tsc --emitDeclarationOnly",
"clean": "rimraf dist types",
"lint": "biome check . --apply",
Expand Down
13 changes: 11 additions & 2 deletions packages/fixtures/src/fixtures/testWithSynpress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type {
PlaywrightWorkerOptions
} from '@playwright/test'
import { chromium, test as base } from '@playwright/test'
import { defineWalletSetup, waitForExtensionOnLoadPage } from 'core'
import { defineWalletSetup } from 'core'
import { createTempContextDir, removeTempContextDir } from 'core'
import { CACHE_DIR_NAME, prepareExtension } from 'core'
import fs from 'fs-extra'
Expand Down Expand Up @@ -77,7 +77,16 @@ const synpressFixtures = (
slowMo: process.env.HEADLESS ? 0 : slowMo
})

_metamaskPage = await waitForExtensionOnLoadPage(context)
// TODO: This should be stored in a store to speed up the tests.
const extensionId = await getExtensionId(context, 'MetaMask')

// TODO: Not sure if this is the best approach. Time will tell.
// We're utilizing the blank page here.
_metamaskPage = context.pages()[0] as Page

await _metamaskPage.goto(`chrome-extension://${extensionId}/home.html`)

await _metamaskPage.reload()

await unlockWallet(_metamaskPage, walletSetup.walletPassword)

Expand Down
27 changes: 11 additions & 16 deletions wallets/metamask/src/fixture-actions/unlockForFixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,29 @@ import type { Page } from '@playwright/test'
import { errors as playwrightErrors } from '@playwright/test'
import { MetaMask } from '../metamask'
import { CrashPage, HomePage } from '../pages'
import { LoadingSelectors } from '../selectors'
import { waitFor } from '../utils/waitFor'
import { closePopover, closeRecoveryPhraseReminder } from '../pages/HomePage/actions'
import { waitForSpinnerToVanish } from '../utils/waitForSpinnerToVanish'

export async function unlockForFixture(page: Page, password: string) {
const metamask = new MetaMask(page.context(), page, password)

await metamask.unlock()

await page.locator(LoadingSelectors.spinner).waitFor({
state: 'hidden',
timeout: 3000 // TODO: Extract & Make this timeout configurable.
})
await waitForSpinnerToVanish(page)

await retryIfMetaMaskCrashAfterUnlock(page)

const recoveryPhraseReminder = page.locator(metamask.homePage.selectors.recoveryPhraseReminder.gotItButton)

// TODO: Extract & Make this timeout configurable.
const isRecoveryPhraseReminderVisible = await waitFor(() => recoveryPhraseReminder.isVisible(), 1000, false)
if (isRecoveryPhraseReminderVisible) {
await recoveryPhraseReminder.click()
}
await closePopover(page)
await closeRecoveryPhraseReminder(page)
}

async function retryIfMetaMaskCrashAfterUnlock(page: Page) {
const isHomePageVisible = await page.locator(HomePage.selectors.logo).isVisible()
const homePageLogoLocator = page.locator(HomePage.selectors.logo)

const isHomePageLogoVisible = await homePageLogoLocator.isVisible()
const isPopoverVisible = await page.locator(HomePage.selectors.popover.closeButton).isVisible()

if (!isHomePageVisible) {
if (!isHomePageLogoVisible && !isPopoverVisible) {
if (await page.locator(CrashPage.selectors.header).isVisible()) {
const errors = await page.locator(CrashPage.selectors.errors).allTextContents()

Expand All @@ -39,7 +34,7 @@ async function retryIfMetaMaskCrashAfterUnlock(page: Page) {
await page.reload()

try {
await page.locator(HomePage.selectors.logo).waitFor({
await homePageLogoLocator.waitFor({
state: 'visible',
timeout: 10_000 // TODO: Extract & Make this timeout configurable.
})
Expand Down
6 changes: 3 additions & 3 deletions wallets/metamask/src/metamask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export class MetaMask {
await this.notificationPage.rejectTransaction(this.extensionId)
}

async approvePermission(spendLimit?: 'default' | 'max' | number) {
async approvePermission(spendLimit?: 'max' | number) {
if (!this.extensionId) {
throw NO_EXTENSION_ID_ERROR
}
Expand Down Expand Up @@ -158,8 +158,8 @@ export class MetaMask {
await this.homePage.toggleShowTestNetworks()
}

async toggleImprovedTokenAllowanceExperience() {
await this.homePage.toggleImprovedTokenAllowanceExperience()
async toggleDismissSecretRecoveryPhraseReminder() {
await this.homePage.toggleDismissSecretRecoveryPhraseReminder()
}

// ---- EXPERIMENTAL FEATURES ----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@ import { waitFor } from '../../../utils/waitFor'
import Selectors from '../selectors'

export async function importWalletFromPrivateKey(page: Page, privateKey: string) {
await page.locator(Selectors.accountMenu.accountMenuButton).click()
await page.locator(Selectors.accountMenu.importAccountButton).click()
await page.locator(Selectors.importAccountScreen.privateKeyInput).fill(privateKey)
await page.locator(Selectors.accountMenu.accountButton).click()

const importButton = page.locator(Selectors.importAccountScreen.importButton)
await page.locator(Selectors.accountMenu.addAccountMenu.addAccountButton).click()
await page.locator(Selectors.accountMenu.addAccountMenu.importAccountButton).click()

await page.locator(Selectors.accountMenu.addAccountMenu.importAccountMenu.privateKeyInput).fill(privateKey)

const importButton = page.locator(Selectors.accountMenu.addAccountMenu.importAccountMenu.importButton)
await importButton.click()

// TODO: Extract & make configurable
const isHidden = await waitFor(() => importButton.isHidden(), 1000, false)
const isImportButtonHidden = await waitFor(() => importButton.isHidden(), 1_000, false)

if (!isHidden) {
const errorText = await page.locator(Selectors.importAccountScreen.error).textContent({
timeout: 1000 // TODO: Extract & make configurable
if (!isImportButtonHidden) {
const errorText = await page.locator(Selectors.accountMenu.addAccountMenu.importAccountMenu.error).textContent({
timeout: 1_000 // TODO: Extract & make configurable
})

throw new Error(`[ImportWalletFromPrivateKey] Importing failed due to error: ${errorText}`)
Expand Down
2 changes: 2 additions & 0 deletions wallets/metamask/src/pages/HomePage/actions/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export * from './popups'
export * from './lock'
export * from './importWalletFromPrivateKey'
export * from './switchAccount'
export * from './settings'
export * from './switchNetwork'
export * from './addNetwork'
export * from './toggleShowTestNetworks'
4 changes: 2 additions & 2 deletions wallets/metamask/src/pages/HomePage/actions/lock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import type { Page } from '@playwright/test'
import Selectors from '../selectors'

export async function lock(page: Page) {
await page.locator(Selectors.accountMenu.accountMenuButton).click()
await page.locator(Selectors.accountMenu.lockButton).click()
await page.locator(Selectors.threeDotsMenu.threeDotsButton).click()
await page.locator(Selectors.threeDotsMenu.lockButton).click()
}
11 changes: 11 additions & 0 deletions wallets/metamask/src/pages/HomePage/actions/popups/closePopover.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { Page } from '@playwright/test'
import { clickLocatorIfCondition } from '../../../../utils/closePopup'
import Selectors from '../../selectors'

// Closes the popover with news, rainbows, unicorns, and other stuff.
export async function closePopover(page: Page) {
const closeButtonLocator = page.locator(Selectors.popover.closeButton)

// TODO: Extract & make configurable
await clickLocatorIfCondition(closeButtonLocator, () => closeButtonLocator.isVisible(), 1_000)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Page } from '@playwright/test'
import { clickLocatorIfCondition } from '../../../../utils/closePopup'
import Selectors from '../../selectors'

export async function closeRecoveryPhraseReminder(page: Page) {
const closeButtonLocator = page.locator(Selectors.recoveryPhraseReminder.gotItButton)

// TODO: Extract & make configurable
await clickLocatorIfCondition(closeButtonLocator, () => closeButtonLocator.isVisible(), 1_000)
}
2 changes: 2 additions & 0 deletions wallets/metamask/src/pages/HomePage/actions/popups/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './closePopover'
export * from './closeRecoveryPhraseReminder'
58 changes: 8 additions & 50 deletions wallets/metamask/src/pages/HomePage/actions/settings.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,28 @@
import type { Locator, Page } from '@playwright/test'
import { waitFor } from '../../../utils/waitFor'
import type { Page } from '@playwright/test'
import { toggle } from '../../../utils/toggle'
import Selectors from '../selectors'
import type { SettingsSidebarMenus } from '../selectors/settings'

async function openSettings(page: Page) {
await page.locator(Selectors.accountMenu.accountMenuButton).click()
await page.locator(Selectors.accountMenu.settingsButton).click()
await page.locator(Selectors.threeDotsMenu.threeDotsButton).click()
await page.locator(Selectors.threeDotsMenu.settingsButton).click()
}

async function openSidebarMenu(page: Page, menu: SettingsSidebarMenus) {
await page.locator(Selectors.settings.sidebarMenu(menu)).click()
}

async function toggle(toggleLocator: Locator) {
// TODO: Extract timeout
const classes = await toggleLocator.getAttribute('class', { timeout: 3_000 })

if (!classes) {
throw new Error('[ToggleShowTestNetworks] Toggle class returned null')
}

const isOn = classes.includes('toggle-button--on')

await toggleLocator.click()

const waitForAction = async () => {
const classes = await toggleLocator.getAttribute('class')

if (!classes) {
throw new Error('[ToggleShowTestNetworks] Toggle class returned null inside waitFor')
}

if (isOn) {
return classes.includes('toggle-button--off')
}

return classes.includes('toggle-button--on')
}

// TODO: Extract timeout
await waitFor(waitForAction, 3_000, true)
}

async function toggleShowTestNetworks(page: Page) {
// .nth(0) -> Show conversion on test networks
// .nth(1) -> Show test networks
const toggleLocator = page.locator(Selectors.settings.advanced.showTestNetworksToggle).nth(1)
await toggle(toggleLocator)
}

async function toggleImprovedTokenAllowanceExperience(page: Page) {
const toggleLocator = page.locator(Selectors.settings.experimental.toggleImprovedTokenAllowanceExperience)
async function toggleDismissSecretRecoveryPhraseReminder(page: Page) {
const toggleLocator = page.locator(Selectors.settings.advanced.dismissSecretRecoveryPhraseReminderToggle)
await toggle(toggleLocator)
}

const advanced = {
toggleShowTestNetworks
}

const experimental = {
toggleImprovedTokenAllowanceExperience
toggleDismissSecretRecoveryPhraseReminder
}

export const settings = {
openSettings,
openSidebarMenu,
advanced,
experimental
advanced
}
7 changes: 4 additions & 3 deletions wallets/metamask/src/pages/HomePage/actions/switchAccount.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type { Page } from '@playwright/test'
import { allTextContents } from '../../../utils/allTextContents'
import Selectors from '../selectors'

export async function switchAccount(page: Page, accountName: string) {
await page.locator(Selectors.accountMenu.accountMenuButton).click()
await page.locator(Selectors.accountMenu.accountButton).click()

const accountNamesLocators = await page.locator(Selectors.accountMenu.accountNamesSelector).all()
const accountNamesLocators = await page.locator(Selectors.accountMenu.accountNames).all()

const accountNames = await page.locator(Selectors.accountMenu.accountNamesSelector).allTextContents()
const accountNames = await allTextContents(accountNamesLocators)

const seekedAccountNames = accountNames.filter((name) => name.toLocaleLowerCase() === accountName.toLocaleLowerCase())

Expand Down
7 changes: 6 additions & 1 deletion wallets/metamask/src/pages/HomePage/actions/switchNetwork.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import type { Page } from '@playwright/test'
import { allTextContents } from '../../../utils/allTextContents'
import Selectors from '../selectors'
import { closeRecoveryPhraseReminder } from './popups'

export async function switchNetwork(page: Page, networkName: string) {
await page.locator(Selectors.networkDropdown.dropdownButton).click()

const networkLocators = await page.locator(Selectors.networkDropdown.networks).all()

const networkNames = await page.locator(Selectors.networkDropdown.networks).allTextContents()
const networkNames = await allTextContents(networkLocators)

const seekedNetworkNames = networkNames.filter((name) => name.toLocaleLowerCase() === networkName.toLocaleLowerCase())

Expand All @@ -19,4 +21,7 @@ export async function switchNetwork(page: Page, networkName: string) {

// biome-ignore lint/style/noNonNullAssertion: this non-null assertion is intentional
await networkLocators[accountIndex]!.click() // TODO: handle the undefined here better

// TODO: This is not really needed if we do `metamask.toggleDismissSecretRecoveryPhraseReminder()` by default. Figure this out!
await closeRecoveryPhraseReminder(page)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { Page } from '@playwright/test'
import { toggle } from '../../../utils/toggle'
import Selectors from '../selectors'

// Toggling this through the network dropdown instead of the settings page is a better approach.
// This is in most cases the faster approach, but it's also more reliable.
export async function toggleShowTestNetworks(page: Page) {
await page.locator(Selectors.networkDropdown.dropdownButton).click()

await toggle(page.locator(Selectors.networkDropdown.showTestNetworksToggle))
}
16 changes: 12 additions & 4 deletions wallets/metamask/src/pages/HomePage/page.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import type { Page } from '@playwright/test'
import { addNetwork, importWalletFromPrivateKey, lock, settings, switchAccount, switchNetwork } from './actions'
import {
addNetwork,
importWalletFromPrivateKey,
lock,
settings,
switchAccount,
switchNetwork,
toggleShowTestNetworks
} from './actions'
import type { Network } from './actions'
import Selectors from './selectors'
import type { SettingsSidebarMenus } from './selectors/settings'
Expand Down Expand Up @@ -39,11 +47,11 @@ export class HomePage {
}

async toggleShowTestNetworks() {
await settings.advanced.toggleShowTestNetworks(this.page)
await toggleShowTestNetworks(this.page)
}

async toggleImprovedTokenAllowanceExperience() {
await settings.experimental.toggleImprovedTokenAllowanceExperience(this.page)
async toggleDismissSecretRecoveryPhraseReminder() {
await settings.advanced.toggleDismissSecretRecoveryPhraseReminder(this.page)
}

async switchNetwork(networkName: string) {
Expand Down
Loading

0 comments on commit 7aeb8e5

Please sign in to comment.