diff --git a/wallets/metamask/cypress-no-wallet.config.ts b/wallets/metamask/cypress-no-wallet.config.ts new file mode 100644 index 00000000..bc2c214e --- /dev/null +++ b/wallets/metamask/cypress-no-wallet.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from 'cypress' +import configureSynpress from './src/cypress/configureSynpress' + +export default defineConfig({ + userAgent: 'synpress', + chromeWebSecurity: true, + e2e: { + baseUrl: 'http://localhost:9999', + specPattern: 'test/cypress/**/importWallet.cy.no-wallet.{js,jsx,ts,tsx}', + supportFile: 'src/cypress/support/e2e.{js,jsx,ts,tsx}', + testIsolation: false, + async setupNodeEvents(on, config) { + return configureSynpress(on, config, false) + } + } +}) diff --git a/wallets/metamask/package.json b/wallets/metamask/package.json index 51f8db10..749c0874 100644 --- a/wallets/metamask/package.json +++ b/wallets/metamask/package.json @@ -30,6 +30,7 @@ "test": "vitest run", "test:coverage": "vitest run --coverage", "test:cypress:headful": "cypress run --browser chrome --headed", + "test:cypress:headful:no-wallet": "cypress run --browser chrome --headed --config-file ./cypress-no-wallet.config.ts", "test:playwright:headful": "playwright test", "test:playwright:headless": "HEADLESS=true playwright test", "test:playwright:headless:ui": "HEADLESS=true playwright test --ui", diff --git a/wallets/metamask/src/cypress/MetaMask.ts b/wallets/metamask/src/cypress/MetaMask.ts index 2b087a15..86595594 100644 --- a/wallets/metamask/src/cypress/MetaMask.ts +++ b/wallets/metamask/src/cypress/MetaMask.ts @@ -37,10 +37,21 @@ export default class MetaMask { } async connectToDapp(accounts?: string[]) { - return this.metamaskPlaywright - .connectToDapp(accounts) - .then(() => true) - .catch(() => false) + await this.metamaskPlaywright.connectToDapp(accounts) + + return true + } + + async importWallet(seedPhrase: string) { + await this.metamaskPlaywright.importWallet(seedPhrase) + + return true + } + + async importWalletFromPrivateKey(privateKey: string) { + await this.metamaskPlaywright.importWalletFromPrivateKey(privateKey) + + return true } async addNewAccount(accountName: string) { @@ -324,6 +335,16 @@ export default class MetaMask { }) } + async goBackToHomePage() { + await this.metamaskPlaywright.openSettings() + + await expect(this.metamaskExtensionPage.locator(HomePageSelectors.copyAccountAddressButton)).not.toBeVisible() + + await this.metamaskPlaywright.goBackToHomePage() + + await expect(this.metamaskExtensionPage.locator(HomePageSelectors.copyAccountAddressButton)).toBeVisible() + } + // Lock/Unlock async lock() { diff --git a/wallets/metamask/src/cypress/configureSynpress.ts b/wallets/metamask/src/cypress/configureSynpress.ts index 81be45bf..20f12c2a 100644 --- a/wallets/metamask/src/cypress/configureSynpress.ts +++ b/wallets/metamask/src/cypress/configureSynpress.ts @@ -19,7 +19,11 @@ let metamaskExtensionPage: Page // TODO: Implement if needed to change the focus between pages // let cypressPage: Page -export default function configureSynpress(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) { +export default function configureSynpress( + on: Cypress.PluginEvents, + config: Cypress.PluginConfigOptions, + importDefaultWallet = true +) { const browsers = config.browsers.filter((b) => b.name === 'chrome') if (browsers.length === 0) { throw new Error('No Chrome browser found in the configuration') @@ -47,7 +51,7 @@ export default function configureSynpress(on: Cypress.PluginEvents, config: Cypr metamaskExtensionId: _metamaskExtensionId, extensionPage: _extensionPage, cypressPage: _cypressPage - } = await importMetaMaskWallet(rdpPort) + } = await importMetaMaskWallet(rdpPort, importDefaultWallet) if (_extensionPage && _metamaskExtensionId) { context = _context metamaskExtensionId = _metamaskExtensionId @@ -63,8 +67,12 @@ export default function configureSynpress(on: Cypress.PluginEvents, config: Cypr // Synpress API on('task', { - // Account + // Wallet connectToDapp: () => metamask?.connectToDapp(), + importWallet: (seedPhrase: string) => metamask?.importWallet(seedPhrase), + importWalletFromPrivateKey: (privateKey: string) => metamask?.importWalletFromPrivateKey(privateKey), + + // Account getAccount: () => metamask?.getAccount(), getAccountAddress: () => metamask?.getAccountAddress(), addNewAccount: (accountName: string) => metamask?.addNewAccount(accountName), @@ -124,7 +132,11 @@ export default function configureSynpress(on: Cypress.PluginEvents, config: Cypr // Lock/Unlock lock: () => metamask?.lock(), - unlock: () => metamask?.unlock() + unlock: () => metamask?.unlock(), + + // Others + + goBackToHomePage: () => metamask?.goBackToHomePage() }) return { diff --git a/wallets/metamask/src/cypress/support/importMetaMaskWallet.ts b/wallets/metamask/src/cypress/support/importMetaMaskWallet.ts index b69ab35d..b4b82e1a 100644 --- a/wallets/metamask/src/cypress/support/importMetaMaskWallet.ts +++ b/wallets/metamask/src/cypress/support/importMetaMaskWallet.ts @@ -4,7 +4,7 @@ import getPlaywrightMetamask from '../getPlaywrightMetamask' const SEED_PHRASE = 'test test test test test test test test test test test junk' -export default async function importMetaMaskWallet(port: number) { +export default async function importMetaMaskWallet(port: number, importDefaultWallet = true) { const debuggerDetails = await fetch(`http://127.0.0.1:${port}/json/version`) const debuggerDetailsConfig = (await debuggerDetails.json()) as { @@ -28,7 +28,7 @@ export default async function importMetaMaskWallet(port: number) { const metamask = getPlaywrightMetamask(context, extensionPage, metamaskExtensionId) - await metamask.importWallet(SEED_PHRASE) + if (importDefaultWallet) await metamask.importWallet(SEED_PHRASE) cypressPage = context.pages()[extensionPageIndex === 1 ? 0 : 1] as Page await cypressPage.bringToFront() diff --git a/wallets/metamask/src/cypress/support/synpressCommands.ts b/wallets/metamask/src/cypress/support/synpressCommands.ts index 68c048df..cb4308b7 100644 --- a/wallets/metamask/src/cypress/support/synpressCommands.ts +++ b/wallets/metamask/src/cypress/support/synpressCommands.ts @@ -16,6 +16,9 @@ import type { Network } from '../../type/Network' declare global { namespace Cypress { interface Chainable { + importWallet(seedPhrase: string): Chainable + importWalletFromPrivateKey(privateKey: string): Chainable + getAccount(): Chainable getNetwork(): Chainable @@ -60,16 +63,21 @@ declare global { lock(): Chainable unlock(): Chainable + + goBackToHomePage(): Chainable } } } export default function synpressCommands() { - Cypress.Commands.add('getAccount', () => { - return cy.task('getAccount') + // Wallet + + Cypress.Commands.add('importWallet', (seedPhrase: string) => { + return cy.task('importWallet', seedPhrase) }) - Cypress.Commands.add('getNetwork', () => { - return cy.task('getNetwork') + + Cypress.Commands.add('importWalletFromPrivateKey', (privateKey: string) => { + return cy.task('importWalletFromPrivateKey', privateKey) }) Cypress.Commands.add('connectToDapp', () => { @@ -78,6 +86,9 @@ export default function synpressCommands() { // Account + Cypress.Commands.add('getAccount', () => { + return cy.task('getAccount') + }) Cypress.Commands.add('addNewAccount', (accountName: string) => { return cy.task('addNewAccount', accountName) }) @@ -93,6 +104,9 @@ export default function synpressCommands() { // Network + Cypress.Commands.add('getNetwork', () => { + return cy.task('getNetwork') + }) Cypress.Commands.add('switchNetwork', (networkName: string, isTestnet = false) => { return cy.task('switchNetwork', { networkName, isTestnet }) }) @@ -158,6 +172,15 @@ export default function synpressCommands() { return cy.task('rejectTokenPermission') }) + // Lock/Unlock + + Cypress.Commands.add('lock', () => { + return cy.task('lock') + }) + Cypress.Commands.add('unlock', () => { + return cy.task('unlock') + }) + // Others Cypress.Commands.add('providePublicEncryptionKey', () => { @@ -187,11 +210,7 @@ export default function synpressCommands() { Cypress.Commands.add('closeTransactionDetails', () => { return cy.task('closeTransactionDetails') }) - - Cypress.Commands.add('lock', () => { - return cy.task('lock') - }) - Cypress.Commands.add('unlock', () => { - return cy.task('unlock') + Cypress.Commands.add('goBackToHomePage', () => { + return cy.task('goBackToHomePage') }) } diff --git a/wallets/metamask/test/cypress/importWallet.cy.no-wallet.ts b/wallets/metamask/test/cypress/importWallet.cy.no-wallet.ts new file mode 100644 index 00000000..a2ff04ef --- /dev/null +++ b/wallets/metamask/test/cypress/importWallet.cy.no-wallet.ts @@ -0,0 +1,10 @@ +const SEED_PHRASE = 'test test test test test test test test test test test junk' + +describe('MetaMask Wallet Import', () => { + it('should go through the onboarding flow and import wallet from seed phrase', () => { + cy.importWallet(SEED_PHRASE) + + cy.getAccount().should('eq', 'Account 1') + cy.getAccountAddress().should('eq', '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266') + }) +}) diff --git a/wallets/metamask/test/cypress/importWalletFromPrivateKey.cy.ts b/wallets/metamask/test/cypress/importWalletFromPrivateKey.cy.ts new file mode 100644 index 00000000..21b9f6c9 --- /dev/null +++ b/wallets/metamask/test/cypress/importWalletFromPrivateKey.cy.ts @@ -0,0 +1,7 @@ +describe('Import wallet from private key', () => { + it('should import a new wallet from private key', () => { + cy.importWalletFromPrivateKey('ea084c575a01e2bbefcca3db101eaeab1d8af15554640a510c73692db24d0a6a') + + cy.getAccountAddress().should('eq', '0xa2ce797cA71d0EaE1be5a7EffD27Fd6C38126801') + }) +})