From 5973755cd48208fa06668d84324fe9b03c81ea4b Mon Sep 17 00:00:00 2001 From: styler <63294765+matstyler@users.noreply.github.com> Date: Sun, 13 Oct 2024 23:54:29 +0200 Subject: [PATCH] :memo: chore: New documentation (#1230) * feat: New documentation * fix: format * chore: API documentation * fix: build * fix: build v2 * fix: minor fixes --- docs/.vitepress/config.ts | 2 +- docs/.vitepress/sidebar.ts | 9 +- docs/api/classes/EthereumWalletMock.md | 189 ---- docs/api/classes/MetaMask.md | 646 ------------- docs/api/cypress/classes/MetaMask.md | 771 ++++++++++++++++ .../configureSynpressForEthereumWalletMock.md | 331 +++++++ .../functions/configureSynpressForMetaMask.md | 350 +++++++ docs/api/cypress/functions/initMetaMask.md | 29 + docs/api/cypress/index.md | 10 + .../cypress/support/functions/mockEthereum.md | 36 + .../synpressCommandsForEthereumWalletMock.md | 22 + .../functions/synpressCommandsForMetaMask.md | 11 + docs/api/cypress/support/index.md | 9 + .../functions/ethereumWalletMockFixtures.md | 16 - docs/api/index.md | 15 +- .../functions/defineWalletSetup.md | 0 .../{ => index}/functions/testWithSynpress.md | 0 docs/api/index/index.md | 8 + .../playwright/classes/EthereumWalletMock.md | 258 ++++++ docs/api/playwright/classes/MetaMask.md | 855 ++++++++++++++++++ .../functions/ethereumWalletMockFixtures.md | 181 ++++ .../functions/getExtensionId.md | 0 .../functions/metaMaskFixtures.md | 0 docs/api/playwright/functions/mockEthereum.md | 16 + .../playwright/functions/unlockForFixture.md | 19 + docs/api/playwright/index.md | 16 + .../variables/DEFAULT_NETWORK_ID.md | 9 + docs/api/playwright/variables/PRIVATE_KEY.md | 9 + docs/api/playwright/variables/web3MockPath.md | 9 + docs/api/typedoc-sidebar.json | 92 +- docs/docs/getting-started.md | 56 +- docs/docs/guides/playwright.md | 2 +- docs/docs/introduction.md | 2 +- docs/docs/migration-guide.md | 241 ++++- docs/docs/setupCypress.md | 122 +++ docs/docs/setupPlaywright.md | 138 +++ docs/docs/typescript.md | 22 +- docs/tsconfig.json | 8 +- docs/typedoc.json | 7 +- examples/ethereum-wallet-mock/tsconfig.json | 4 +- packages/core/src/testWithSynpress.ts | 23 +- release/src/cypress/index.ts | 6 +- .../src/cypress/support/mockEthereum.ts | 29 +- .../src/cypress/support/synpressCommands.ts | 84 +- .../src/cypress/utils/configureSynpress.ts | 18 + .../src/playwright/EthereumWalletMock.ts | 57 +- .../src/playwright/constants.ts | 13 +- wallets/metamask/src/cypress/MetaMask.ts | 322 +++++-- .../metamask/src/cypress/configureSynpress.ts | 32 + .../src/cypress/support/initMetaMask.ts | 13 +- .../src/cypress/support/synpressCommands.ts | 192 +++- wallets/metamask/src/playwright/MetaMask.ts | 294 ++++-- 52 files changed, 4469 insertions(+), 1134 deletions(-) delete mode 100644 docs/api/classes/EthereumWalletMock.md delete mode 100644 docs/api/classes/MetaMask.md create mode 100644 docs/api/cypress/classes/MetaMask.md create mode 100644 docs/api/cypress/functions/configureSynpressForEthereumWalletMock.md create mode 100644 docs/api/cypress/functions/configureSynpressForMetaMask.md create mode 100644 docs/api/cypress/functions/initMetaMask.md create mode 100644 docs/api/cypress/index.md create mode 100644 docs/api/cypress/support/functions/mockEthereum.md create mode 100644 docs/api/cypress/support/functions/synpressCommandsForEthereumWalletMock.md create mode 100644 docs/api/cypress/support/functions/synpressCommandsForMetaMask.md create mode 100644 docs/api/cypress/support/index.md delete mode 100644 docs/api/functions/ethereumWalletMockFixtures.md rename docs/api/{ => index}/functions/defineWalletSetup.md (100%) rename docs/api/{ => index}/functions/testWithSynpress.md (100%) create mode 100644 docs/api/index/index.md create mode 100644 docs/api/playwright/classes/EthereumWalletMock.md create mode 100644 docs/api/playwright/classes/MetaMask.md create mode 100644 docs/api/playwright/functions/ethereumWalletMockFixtures.md rename docs/api/{ => playwright}/functions/getExtensionId.md (100%) rename docs/api/{ => playwright}/functions/metaMaskFixtures.md (100%) create mode 100644 docs/api/playwright/functions/mockEthereum.md create mode 100644 docs/api/playwright/functions/unlockForFixture.md create mode 100644 docs/api/playwright/index.md create mode 100644 docs/api/playwright/variables/DEFAULT_NETWORK_ID.md create mode 100644 docs/api/playwright/variables/PRIVATE_KEY.md create mode 100644 docs/api/playwright/variables/web3MockPath.md create mode 100644 docs/docs/setupCypress.md create mode 100644 docs/docs/setupPlaywright.md diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index abd32544a..b4b97f326 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -21,7 +21,7 @@ export default defineConfig({ // https://vitepress.dev/reference/default-theme-config nav: [ { text: 'Docs', link: '/docs/getting-started' }, - { text: 'API', link: '/api/' }, + { text: 'API', link: '/api/index/' }, { text: 'Examples', link: 'https://github.com/Synthetixio/synpress/tree/new-dawn/examples' }, { text: pkg.version, diff --git a/docs/.vitepress/sidebar.ts b/docs/.vitepress/sidebar.ts index 3538e1ffb..329f62f67 100644 --- a/docs/.vitepress/sidebar.ts +++ b/docs/.vitepress/sidebar.ts @@ -7,7 +7,14 @@ export const sidebar: DefaultTheme.Sidebar = { text: 'Introduction', items: [ { text: 'Why Synpress?', link: '/docs/introduction' }, - { text: 'Getting Started', link: '/docs/getting-started' }, + { + text: 'Getting Started', + link: '/docs/getting-started', + items: [ + { text: 'Start with Playwright', link: '/docs/setupPlaywright' }, + { text: 'Start with Cypress', link: '/docs/setupCypress' } + ] + }, { text: 'Migration Guide', link: '/docs/migration-guide' }, { text: 'TypeScript', link: '/docs/typescript' }, { text: 'Platform Compatibility', link: '/docs/platform-compatibility' }, diff --git a/docs/api/classes/EthereumWalletMock.md b/docs/api/classes/EthereumWalletMock.md deleted file mode 100644 index 6e8f76df6..000000000 --- a/docs/api/classes/EthereumWalletMock.md +++ /dev/null @@ -1,189 +0,0 @@ -# Class: EthereumWalletMock - -## Constructors - -### new EthereumWalletMock() - -```ts -new EthereumWalletMock(page): EthereumWalletMock -``` - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `page` | `Page` | - -#### Returns - -[`EthereumWalletMock`](EthereumWalletMock.md) - -## Properties - -| Property | Modifier | Type | -| :------ | :------ | :------ | -| `page` | `readonly` | `Page` | -| `seedPhrase` | `public` | `string` | -| `wallet` | `public` | `WalletMock` | - -## Methods - -### addNetwork() - -```ts -addNetwork(network): Promise -``` - -Adds a new network. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `network` | `Network` | The network object to use for adding the new network. | - -#### Returns - -`Promise`\<`any`\> - -*** - -### addNewAccount() - -```ts -addNewAccount(): Promise -``` - -Adds a new account. This account is based on the initially imported seed phrase. - -#### Returns - -`Promise`\<`any`\> - -*** - -### connectToDapp() - -```ts -connectToDapp(wallet?): Promise -``` - -Connects wallet to the dapp. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `wallet`? | `WalletMock` | The wallet to connect to the dapp. | - -#### Returns - -`Promise`\<`any`\> - -*** - -### getAccountAddress() - -```ts -getAccountAddress(): Promise -``` - -Retrieves the current account address. - -#### Returns - -`Promise`\<`undefined` \| `string`\> - -*** - -### getAllAccounts() - -```ts -getAllAccounts(): Promise -``` - -Retrieves the current account address. - -#### Returns - -`Promise`\<`string`[]\> - -*** - -### importWallet() - -```ts -importWallet(seedPhrase): Promise -``` - -Imports a wallet using the given seed phrase. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `seedPhrase` | `string` | The seed phrase to import. | - -#### Returns - -`Promise`\<`any`\> - -*** - -### importWalletFromPrivateKey() - -```ts -importWalletFromPrivateKey(privateKey): Promise -``` - -Imports a wallet using the given private key. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `privateKey` | \`0x$\{string\}\` | The private key to import. | - -#### Returns - -`Promise`\<`any`\> - -*** - -### switchAccount() - -```ts -switchAccount(accountAddress): Promise -``` - -Switches to the account with the given name. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `accountAddress` | `string` | The name of the account to switch to. | - -#### Returns - -`Promise`\<`any`\> - -*** - -### switchNetwork() - -```ts -switchNetwork(networkName): Promise -``` - -Switches to the network with the given name. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `networkName` | `string` | The name of the network to switch to. | - -#### Returns - -`Promise`\<`void`\> diff --git a/docs/api/classes/MetaMask.md b/docs/api/classes/MetaMask.md deleted file mode 100644 index 6b5658daf..000000000 --- a/docs/api/classes/MetaMask.md +++ /dev/null @@ -1,646 +0,0 @@ -# Class: MetaMask - -This class is the heart of Synpress's MetaMask API. - -## Constructors - -### new MetaMask() - -```ts -new MetaMask( - context, - page, - password, - extensionId?): MetaMask -``` - -Class constructor. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `context` | `BrowserContext` | The browser context. | -| `page` | `Page` | The MetaMask tab page. | -| `password` | `string` | The password of the MetaMask wallet. | -| `extensionId`? | `string` | The extension ID of the MetaMask extension. Optional if no interaction with the dapp is required. | - -#### Returns - -[`MetaMask`](MetaMask.md) - -A new instance of the MetaMask class. - -## Properties - -| Property | Modifier | Type | Description | -| :------ | :------ | :------ | :------ | -| `context` | `readonly` | `BrowserContext` | The browser context. | -| `extensionId?` | `readonly` | `string` | The extension ID of the MetaMask extension. Optional if no interaction with the dapp is required. | -| `page` | `readonly` | `Page` | The MetaMask tab page. | -| `password` | `readonly` | `string` | The password of the MetaMask wallet. | -| `settingsPage` | `readonly` | `SettingsPage` | - | - -## Methods - -### addNetwork() - -```ts -addNetwork(network): Promise -``` - -Adds a new network. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `network` | `object` | The network object to use for adding the new network. | -| `network.blockExplorerUrl`? | `string` | The block explorer URL of the network. | -| `network.chainId` | `number` | The chain ID of the network. | -| `network.name` | `string` | The name of the network. | -| `network.rpcUrl` | `string` | The RPC URL of the network. | -| `network.symbol` | `string` | The currency symbol of the network. | - -#### Returns - -`Promise`\<`void`\> - -*** - -### addNewAccount() - -```ts -addNewAccount(accountName): Promise -``` - -Adds a new account with the given name. This account is based on the initially imported seed phrase. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `accountName` | `string` | The name of the new account. | - -#### Returns - -`Promise`\<`void`\> - -*** - -### addNewToken() - -```ts -addNewToken(): Promise -``` - -#### Returns - -`Promise`\<`void`\> - -*** - -### approveNewNetwork() - -```ts -approveNewNetwork(): Promise -``` - -Approves a new network request. - -#### Returns - -`Promise`\<`void`\> - -*** - -### approveSwitchNetwork() - -```ts -approveSwitchNetwork(): Promise -``` - -Approves a switch network request. - -#### Returns - -`Promise`\<`void`\> - -*** - -### approveTokenPermission() - -```ts -approveTokenPermission(options?): Promise -``` - -Approves a permission request to spend tokens. - -::: warning -For NFT approvals, use `confirmTransaction` method. -::: - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `options`? | `object` | The permission options. | -| `options.gasSetting`? | \| `"low"` \| `"market"` \| `"aggressive"` \| `"site"` \| \{ `"gasLimit"`: `number`; `"maxBaseFee"`: `number`; `"priorityFee"`: `number`; \} | The gas setting to use for the approval transaction. | -| `options.spendLimit`? | `number` \| `"max"` | The spend limit to use for the permission. | - -#### Returns - -`Promise`\<`void`\> - -*** - -### confirmSignature() - -```ts -confirmSignature(): Promise -``` - -Confirms a signature request. This function supports all types of commonly used signatures. - -#### Returns - -`Promise`\<`void`\> - -*** - -### confirmSignatureWithRisk() - -```ts -confirmSignatureWithRisk(): Promise -``` - -Confirms a signature request with potential risk. - -#### Returns - -`Promise`\<`void`\> - -*** - -### confirmTransaction() - -```ts -confirmTransaction(options?): Promise -``` - -Confirms a transaction request. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `options`? | `object` | The transaction options. | -| `options.gasSetting`? | \| `"low"` \| `"market"` \| `"aggressive"` \| `"site"` \| \{ `"gasLimit"`: `number`; `"maxBaseFee"`: `number`; `"priorityFee"`: `number`; \} | The gas setting to use for the transaction. | - -#### Returns - -`Promise`\<`void`\> - -*** - -### connectToDapp() - -```ts -connectToDapp(accounts?): Promise -``` - -Connects to the dapp using the currently selected account. - -#### Parameters - -| Parameter | Type | -| :------ | :------ | -| `accounts`? | `string`[] | - -#### Returns - -`Promise`\<`void`\> - -*** - -### decrypt() - -```ts -decrypt(): Promise -``` - -#### Returns - -`Promise`\<`void`\> - -*** - -### disableEthSign() - -```ts -disableEthSign(): Promise -``` - -Disables the eth_sign feature in MetaMask advanced settings. - -#### Returns - -`Promise`\<`void`\> - -*** - -### getAccountAddress() - -```ts -getAccountAddress(): Promise -``` - -Retrieves the current account address. - -#### Returns - -`Promise`\<`string`\> - -*** - -### goBackToHomePage() - -```ts -goBackToHomePage(): Promise -``` - -Goes back to the home page of MetaMask tab. - -#### Returns - -`Promise`\<`void`\> - -*** - -### importWallet() - -```ts -importWallet(seedPhrase): Promise -``` - -Imports a wallet using the given seed phrase. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `seedPhrase` | `string` | The seed phrase to import. | - -#### Returns - -`Promise`\<`void`\> - -*** - -### importWalletFromPrivateKey() - -```ts -importWalletFromPrivateKey(privateKey): Promise -``` - -Imports a wallet using the given private key. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `privateKey` | `string` | The private key to import. | - -#### Returns - -`Promise`\<`void`\> - -*** - -### lock() - -```ts -lock(): Promise -``` - -Locks MetaMask. - -#### Returns - -`Promise`\<`void`\> - -*** - -### openSettings() - -```ts -openSettings(): Promise -``` - -Opens the settings page. - -#### Returns - -`Promise`\<`void`\> - -*** - -### openSidebarMenu() - -```ts -openSidebarMenu(menu): Promise -``` - -Opens a given menu in the sidebar. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `menu` | `SettingsSidebarMenus` | The menu to open. | - -#### Returns - -`Promise`\<`void`\> - -*** - -### providePublicEncryptionKey() - -```ts -providePublicEncryptionKey(): Promise -``` - -#### Returns - -`Promise`\<`void`\> - -*** - -### rejectNewNetwork() - -```ts -rejectNewNetwork(): Promise -``` - -Rejects a new network request. - -#### Returns - -`Promise`\<`void`\> - -*** - -### rejectSignature() - -```ts -rejectSignature(): Promise -``` - -Rejects a signature request. This function supports all types of commonly used signatures. - -#### Returns - -`Promise`\<`void`\> - -*** - -### rejectSwitchNetwork() - -```ts -rejectSwitchNetwork(): Promise -``` - -Rejects a switch network request. - -#### Returns - -`Promise`\<`void`\> - -*** - -### rejectTokenPermission() - -```ts -rejectTokenPermission(): Promise -``` - -Rejects a permission request to spend tokens. - -::: warning -For NFT approvals, use `confirmTransaction` method. -::: - -#### Returns - -`Promise`\<`void`\> - -*** - -### rejectTransaction() - -```ts -rejectTransaction(): Promise -``` - -Rejects a transaction request. - -#### Returns - -`Promise`\<`void`\> - -*** - -### resetAccount() - -```ts -resetAccount(): Promise -``` - -Resets the account. - -::: warning -This function requires the correct menu to be already opened. -::: - -#### Returns - -`Promise`\<`void`\> - -*** - -### switchAccount() - -```ts -switchAccount(accountName): Promise -``` - -Switches to the account with the given name. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `accountName` | `string` | The name of the account to switch to. | - -#### Returns - -`Promise`\<`void`\> - -*** - -### switchNetwork() - -```ts -switchNetwork(networkName, isTestnet?): Promise -``` - -Switches to the network with the given name. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `networkName` | `string` | The name of the network to switch to. | -| `isTestnet`? | `boolean` | If switch to a test network. | - -#### Returns - -`Promise`\<`void`\> - -*** - -### toggleDismissSecretRecoveryPhraseReminder() - -```ts -toggleDismissSecretRecoveryPhraseReminder(): Promise -``` - -Toggles the "Dismiss Secret Recovery Phrase Reminder" setting. - -::: warning -This function requires the correct menu to be already opened. -::: - -#### Returns - -`Promise`\<`void`\> - -*** - -### toggleShowTestNetworks() - -```ts -toggleShowTestNetworks(): Promise -``` - -Toggles the "Show Test Networks" setting. - -::: warning -This function requires the correct menu to be already opened. -::: - -#### Returns - -`Promise`\<`void`\> - -*** - -### unlock() - -```ts -unlock(): Promise -``` - -Unlocks MetaMask. - -#### Returns - -`Promise`\<`void`\> - -*** - -### unsafe\_enableEthSign() - -```ts -unsafe_enableEthSign(): Promise -``` - -Enables the eth_sign feature in MetaMask advanced settings. -This method is marked as unsafe because enabling eth_sign can have security implications. - -#### Returns - -`Promise`\<`void`\> - -## Experimental Methods - -### closeTransactionDetails() - -`Experimental` - -```ts -closeTransactionDetails(): Promise -``` - -Closes the currently opened transaction details. - -#### Returns - -`Promise`\<`void`\> - -*** - -### confirmTransactionAndWaitForMining() - -`Experimental` - -```ts -confirmTransactionAndWaitForMining(options?): Promise -``` - -Confirms a transaction request and waits for the transaction to be mined. -This function utilizes the "Activity" tab of the MetaMask tab. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `options`? | `object` | The transaction options. | -| `options.gasSetting`? | \| `"low"` \| `"market"` \| `"aggressive"` \| `"site"` \| \{ `"gasLimit"`: `number`; `"maxBaseFee"`: `number`; `"priorityFee"`: `number`; \} | The gas setting to use for the transaction. | - -#### Returns - -`Promise`\<`void`\> - -*** - -### openTransactionDetails() - -`Experimental` - -```ts -openTransactionDetails(txIndex): Promise -``` - -Opens the transaction details. - -#### Parameters - -| Parameter | Type | Description | -| :------ | :------ | :------ | -| `txIndex` | `number` | The index of the transaction in the "Activity" tab. Starts from `0`. | - -#### Returns - -`Promise`\<`void`\> - -## Selectors - -| Property | Modifier | Type | Description | -| :------ | :------ | :------ | :------ | -| `crashPage` | `readonly` | `CrashPage` | This property can be used to access selectors for a given page. | -| `homePage` | `readonly` | `HomePage` | This property can be used to access selectors for a given page. | -| `lockPage` | `readonly` | `LockPage` | This property can be used to access selectors for a given page. | -| `notificationPage` | `readonly` | `NotificationPage` | This property can be used to access selectors for a given page. | -| `onboardingPage` | `readonly` | `OnboardingPage` | This property can be used to access selectors for a given page. | diff --git a/docs/api/cypress/classes/MetaMask.md b/docs/api/cypress/classes/MetaMask.md new file mode 100644 index 000000000..f3b2f6473 --- /dev/null +++ b/docs/api/cypress/classes/MetaMask.md @@ -0,0 +1,771 @@ +# Class: MetaMask + +MetaMask class for interacting with the MetaMask extension in Cypress tests. + +## Constructors + +### new MetaMask() + +```ts +new MetaMask( + context, + metamaskExtensionPage, + metamaskExtensionId): MetaMask +``` + +Creates an instance of MetaMask. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `context` | `BrowserContext` | The browser context | +| `metamaskExtensionPage` | `Page` | The MetaMask extension page | +| `metamaskExtensionId` | `string` | The MetaMask extension ID | + +#### Returns + +[`MetaMask`](MetaMask.md) + +## Properties + +| Property | Modifier | Type | Description | +| :------ | :------ | :------ | :------ | +| `metamaskExtensionPage` | `readonly` | `Page` | The MetaMask extension page | +| `metamaskPlaywright` | `readonly` | [`MetaMask`](../../playwright/classes/MetaMask.md) | The MetaMask instance for Playwright | + +## Methods + +### addNetwork() + +```ts +addNetwork(network): Promise +``` + +Adds a new network to MetaMask. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `network` | `object` | The network configuration to add | +| `network.blockExplorerUrl`? | `string` | - | +| `network.chainId` | `number` | - | +| `network.name` | `string` | - | +| `network.rpcUrl` | `string` | - | +| `network.symbol` | `string` | - | + +#### Returns + +`Promise`\<`boolean`\> + +True if the network was added successfully + +*** + +### addNewAccount() + +```ts +addNewAccount(accountName): Promise +``` + +Adds a new account with the given name. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `accountName` | `string` | The name for the new account | + +#### Returns + +`Promise`\<`boolean`\> + +True if the account was added successfully + +*** + +### addNewToken() + +```ts +addNewToken(): Promise +``` + +Adds a new token to MetaMask. + +#### Returns + +`Promise`\<`boolean`\> + +True if the token was added successfully + +*** + +### approveNewNetwork() + +```ts +approveNewNetwork(): Promise +``` + +Approves adding a new network. + +#### Returns + +`Promise`\<`boolean`\> + +True if the new network was approved successfully + +*** + +### approveSwitchNetwork() + +```ts +approveSwitchNetwork(): Promise +``` + +Approves switching to a new network. + +#### Returns + +`Promise`\<`boolean`\> + +True if the network switch was approved successfully + +*** + +### approveTokenPermission() + +```ts +approveTokenPermission(options?): Promise +``` + +Approves token permission. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `options`? | `object` | Optional settings for token approval | +| `options.gasSetting`? | \| `"low"` \| `"market"` \| `"aggressive"` \| `"site"` \| \{ `"gasLimit"`: `number`; `"maxBaseFee"`: `number`; `"priorityFee"`: `number`; \} | Gas settings for the transaction | +| `options.spendLimit`? | `number` \| `"max"` | The spend limit for the token (number or 'max') | + +#### Returns + +`Promise`\<`boolean`\> + +True if the permission was approved, false otherwise + +*** + +### closeTransactionDetails() + +```ts +closeTransactionDetails(): Promise +``` + +Closes the transaction details view. + +#### Returns + +`Promise`\<`boolean`\> + +True if the transaction details were closed successfully, false otherwise + +*** + +### confirmSignature() + +```ts +confirmSignature(): Promise +``` + +Confirms a signature request. + +#### Returns + +`Promise`\<`boolean`\> + +True if the signature was confirmed successfully, false otherwise + +*** + +### confirmTransaction() + +```ts +confirmTransaction(options?): Promise +``` + +Confirms a transaction. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `options`? | `object` | Optional gas settings for the transaction | +| `options.gasSetting`? | \| `"low"` \| `"market"` \| `"aggressive"` \| `"site"` \| \{ `"gasLimit"`: `number`; `"maxBaseFee"`: `number`; `"priorityFee"`: `number`; \} | - | + +#### Returns + +`Promise`\<`boolean`\> + +True if the transaction was confirmed successfully + +*** + +### confirmTransactionAndWaitForMining() + +```ts +confirmTransactionAndWaitForMining(): Promise +``` + +Confirms a transaction and waits for it to be mined. + +#### Returns + +`Promise`\<`boolean`\> + +True if the transaction was confirmed and mined successfully, false otherwise + +*** + +### connectToAnvil() + +```ts +connectToAnvil(options): Promise +``` + +Connects to an Anvil node. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `options` | `object` | Object containing the RPC URL and chain ID | +| `options.chainId` | `number` | The chain ID of the Anvil node | +| `options.rpcUrl` | `string` | The RPC URL of the Anvil node | + +#### Returns + +`Promise`\<`boolean`\> + +True if the connection was successful, false otherwise + +*** + +### connectToDapp() + +```ts +connectToDapp(accounts?): Promise +``` + +Connects MetaMask to a dApp. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `accounts`? | `string`[] | Optional array of account addresses to connect | + +#### Returns + +`Promise`\<`boolean`\> + +True if the connection was successful + +*** + +### createAnvilNode() + +```ts +createAnvilNode(options?): Promise<{ + "anvil": Anvil; + "chainId": number; + "rpcUrl": string; +}> +``` + +Creates an Anvil node for testing. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `options`? | `CreateAnvilOptions` | Optional Anvil node creation options | + +#### Returns + +`Promise`\<\{ + `"anvil"`: `Anvil`; + `"chainId"`: `number`; + `"rpcUrl"`: `string`; + \}\> + +Object containing the Anvil instance, RPC URL, and chain ID + +| Member | Type | +| :------ | :------ | +| `anvil` | `Anvil` | +| `chainId` | `number` | +| `rpcUrl` | `string` | + +*** + +### decrypt() + +```ts +decrypt(): Promise +``` + +Decrypts a message. + +#### Returns + +`Promise`\<`boolean`\> + +True if the message was decrypted successfully, false otherwise + +*** + +### deployToken() + +```ts +deployToken(): Promise +``` + +Deploys a token. + +#### Returns + +`Promise`\<`boolean`\> + +True if the token was deployed successfully + +*** + +### emptyAnvilNode() + +```ts +emptyAnvilNode(): Promise +``` + +Empties the Anvil node pool. + +#### Returns + +`Promise`\<`boolean`\> + +True if the operation was successful + +*** + +### getAccount() + +```ts +getAccount(): Promise +``` + +Gets the current account name. + +#### Returns + +`Promise`\<`string`\> + +The current account name + +*** + +### getAccountAddress() + +```ts +getAccountAddress(): Promise +``` + +Gets the current account address. + +#### Returns + +`Promise`\<`string`\> + +The current account address + +*** + +### getNetwork() + +```ts +getNetwork(): Promise +``` + +Gets the current network name. + +#### Returns + +`Promise`\<`string`\> + +The current network name + +*** + +### goBackToHomePage() + +```ts +goBackToHomePage(): Promise +``` + +Navigates back to the home page. + +#### Returns + +`Promise`\<`boolean`\> + +True if the navigation was successful + +*** + +### importWallet() + +```ts +importWallet(seedPhrase): Promise +``` + +Imports a wallet using a seed phrase. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `seedPhrase` | `string` | The seed phrase to import | + +#### Returns + +`Promise`\<`boolean`\> + +True if the import was successful + +*** + +### importWalletFromPrivateKey() + +```ts +importWalletFromPrivateKey(privateKey): Promise +``` + +Imports a wallet using a private key. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `privateKey` | `string` | The private key to import | + +#### Returns + +`Promise`\<`boolean`\> + +True if the import was successful + +*** + +### lock() + +```ts +lock(): Promise +``` + +Locks the MetaMask wallet. + +#### Returns + +`Promise`\<`boolean`\> + +True if the wallet was locked successfully + +*** + +### openSettings() + +```ts +openSettings(): Promise +``` + +Opens the settings page. + +#### Returns + +`Promise`\<`boolean`\> + +True if the settings page was opened successfully + +*** + +### openSidebarMenu() + +```ts +openSidebarMenu(menu): Promise +``` + +Opens a specific sidebar menu in the settings. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `menu` | `SettingsSidebarMenus` | The menu to open | + +#### Returns + +`Promise`\<`boolean`\> + +True if the menu was opened successfully + +*** + +### openTransactionDetails() + +```ts +openTransactionDetails(txIndex): Promise +``` + +Opens the details of a specific transaction. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `txIndex` | `number` | The index of the transaction to open | + +#### Returns + +`Promise`\<`boolean`\> + +True if the transaction details were opened successfully, false otherwise + +*** + +### providePublicEncryptionKey() + +```ts +providePublicEncryptionKey(): Promise +``` + +Provides a public encryption key. + +#### Returns + +`Promise`\<`boolean`\> + +True if the key was provided successfully, false otherwise + +*** + +### rejectNewNetwork() + +```ts +rejectNewNetwork(): Promise +``` + +Rejects adding a new network. + +#### Returns + +`Promise`\<`boolean`\> + +True if the new network was rejected successfully + +*** + +### rejectSignature() + +```ts +rejectSignature(): Promise +``` + +Rejects a signature request. + +#### Returns + +`Promise`\<`boolean`\> + +True if the signature was rejected successfully + +*** + +### rejectSwitchNetwork() + +```ts +rejectSwitchNetwork(): Promise +``` + +Rejects switching to a new network. + +#### Returns + +`Promise`\<`boolean`\> + +True if the network switch was rejected successfully + +*** + +### rejectTokenPermission() + +```ts +rejectTokenPermission(): Promise +``` + +Rejects token permission. + +#### Returns + +`Promise`\<`boolean`\> + +True if the permission was rejected successfully + +*** + +### rejectTransaction() + +```ts +rejectTransaction(): Promise +``` + +Rejects a transaction. + +#### Returns + +`Promise`\<`boolean`\> + +True if the transaction was rejected successfully + +*** + +### renameAccount() + +```ts +renameAccount(options): Promise +``` + +Renames an account. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `options` | `object` | Object containing the current and new account names | +| `options.currentAccountName` | `string` | The current name of the account | +| `options.newAccountName` | `string` | The new name for the account | + +#### Returns + +`Promise`\<`boolean`\> + +True if the rename was successful + +*** + +### resetAccount() + +```ts +resetAccount(): Promise +``` + +Resets the current account. + +#### Returns + +`Promise`\<`boolean`\> + +True if the reset was successful + +*** + +### switchAccount() + +```ts +switchAccount(accountName): Promise +``` + +Switches to the account with the given name. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `accountName` | `string` | The name of the account to switch to | + +#### Returns + +`Promise`\<`boolean`\> + +True if the switch was successful + +*** + +### switchNetwork() + +```ts +switchNetwork(options): Promise +``` + +Switches to the specified network. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `options` | `object` | Object containing the network name and testnet flag | +| `options.isTestnet`? | `boolean` | Whether the network is a testnet (default: false) | +| `options.networkName` | `string` | The name of the network to switch to | + +#### Returns + +`Promise`\<`boolean`\> + +True if the switch was successful, false otherwise + +*** + +### toggleDismissSecretRecoveryPhraseReminder() + +```ts +toggleDismissSecretRecoveryPhraseReminder(): Promise +``` + +Toggles the dismissal of the secret recovery phrase reminder. + +#### Returns + +`Promise`\<`boolean`\> + +True if the toggle was successful + +*** + +### toggleShowTestNetworks() + +```ts +toggleShowTestNetworks(): Promise +``` + +Toggles the display of test networks. + +#### Returns + +`Promise`\<`boolean`\> + +True if the toggle was successful + +*** + +### unlock() + +```ts +unlock(): Promise +``` + +Unlocks the MetaMask wallet. + +#### Returns + +`Promise`\<`boolean`\> + +True if the wallet was unlocked successfully diff --git a/docs/api/cypress/functions/configureSynpressForEthereumWalletMock.md b/docs/api/cypress/functions/configureSynpressForEthereumWalletMock.md new file mode 100644 index 000000000..988c3653d --- /dev/null +++ b/docs/api/cypress/functions/configureSynpressForEthereumWalletMock.md @@ -0,0 +1,331 @@ +# Function: configureSynpressForEthereumWalletMock() + +```ts +function configureSynpressForEthereumWalletMock(on, config): { + "animationDistanceThreshold": number; + "arch": string; + "autoOpen": boolean; + "baseUrl": string | null; + "blockHosts": string | string[] | null; + "browser": Cypress.Browser; + "browserUrl": string; + "browsers": Cypress.Browser[]; + "chromeWebSecurity": boolean; + "clientCertificates": Cypress.ClientCertificate[]; + "clientRoute": string; + "component": Cypress.ComponentConfigOptions; + "configFile": string; + "cypressBinaryRoot": string; + "cypressEnv": string; + "defaultCommandTimeout": number; + "devServerPublicPathRoute": string; + "downloadsFolder": string; + "e2e": Cypress.EndToEndConfigOptions; + "env": {}; + "excludeSpecPattern": string | string[]; + "execTimeout": number; + "experimentalCspAllowList": boolean | Cypress.experimentalCspAllowedDirectives[]; + "experimentalFetchPolyfill": boolean; + "experimentalInteractiveRunEvents": boolean; + "experimentalMemoryManagement": boolean; + "experimentalModifyObstructiveThirdPartyCode": boolean; + "experimentalSkipDomainInjection": string[] | null; + "experimentalSourceRewriting": boolean; + "experimentalStudio": boolean; + "experimentalWebKitSupport": boolean; + "fileServerFolder": string; + "fixturesFolder": string | false; + "hideCommandLog": boolean; + "hideRunnerUi": boolean; + "hosts": {} | null; + "includeShadowDom": boolean; + "indexHtmlFile": string; + "isInteractive": boolean; + "isNewProject": boolean; + "isTextTerminal": boolean; + "modifyObstructiveCode": boolean; + "morgan": boolean; + "namespace": string; + "numTestsKeptInMemory": number; + "pageLoadTimeout": number; + "parentTestsFolder": string; + "parentTestsFolderDisplay": string; + "platform": "linux" | "darwin" | "win32"; + "port": number | null; + "projectId": string | null; + "projectName": string; + "projectRoot": string; + "protocolEnabled": boolean; + "proxyUrl": string; + "redirectionLimit": number; + "remote": Cypress.RemoteState; + "repoRoot": string | null; + "report": boolean; + "reporter": string; + "reporterOptions": {}; + "reporterRoute": string; + "reporterUrl": string; + "requestTimeout": number; + "resolvedNodePath": string; + "resolvedNodeVersion": string; + "responseTimeout": number; + "retries": Cypress.Nullable; + "runMode": Cypress.Nullable; + } | Cypress.RetryStrategyWithModeSpecs>; + "screenshotOnRunFailure": boolean; + "screenshotsFolder": string | false; + "scrollBehavior": Cypress.scrollBehaviorOptions; + "setupNodeEvents": (on, config) => void | Cypress.PluginConfigOptions | Promise; + "slowTestThreshold": number; + "socketId": string | null; + "socketIoCookie": string; + "socketIoRoute": string; + "spec": Cypress.Spec | null; + "specPattern": string | string[]; + "specs": Cypress.Spec[]; + "supportFile": string | false; + "supportFolder": string; + "taskTimeout": number; + "testIsolation": boolean; + "testingType": Cypress.TestingType; + "trashAssetsBeforeRuns": boolean; + "userAgent": string | null; + "version": string; + "video": boolean; + "videoCompression": number | boolean; + "videosFolder": string; + "viewportHeight": number; + "viewportWidth": number; + "waitForAnimations": boolean; + "watchForFileChanges": boolean; +} +``` + +Configures Synpress for use with the Ethereum Wallet Mock. + +This function sets up the necessary configurations and hooks for running +Cypress tests with the Ethereum Wallet Mock. It performs the following tasks: + +1. Filters the available browsers to ensure only Chrome is used. +2. Sets up a 'before:browser:launch' hook to enable debug mode and establish + a Playwright connection. +3. Sets up a 'before:spec' hook to initialize the Ethereum Wallet Mock before + each test spec runs. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `on` | `PluginEvents` | Cypress plugin event handler | +| `config` | `PluginConfigOptions` | Cypress plugin configuration options | + +## Returns + +```ts +{ + "animationDistanceThreshold": number; + "arch": string; + "autoOpen": boolean; + "baseUrl": string | null; + "blockHosts": string | string[] | null; + "browser": Cypress.Browser; + "browserUrl": string; + "browsers": Cypress.Browser[]; + "chromeWebSecurity": boolean; + "clientCertificates": Cypress.ClientCertificate[]; + "clientRoute": string; + "component": Cypress.ComponentConfigOptions; + "configFile": string; + "cypressBinaryRoot": string; + "cypressEnv": string; + "defaultCommandTimeout": number; + "devServerPublicPathRoute": string; + "downloadsFolder": string; + "e2e": Cypress.EndToEndConfigOptions; + "env": {}; + "excludeSpecPattern": string | string[]; + "execTimeout": number; + "experimentalCspAllowList": boolean | Cypress.experimentalCspAllowedDirectives[]; + "experimentalFetchPolyfill": boolean; + "experimentalInteractiveRunEvents": boolean; + "experimentalMemoryManagement": boolean; + "experimentalModifyObstructiveThirdPartyCode": boolean; + "experimentalSkipDomainInjection": string[] | null; + "experimentalSourceRewriting": boolean; + "experimentalStudio": boolean; + "experimentalWebKitSupport": boolean; + "fileServerFolder": string; + "fixturesFolder": string | false; + "hideCommandLog": boolean; + "hideRunnerUi": boolean; + "hosts": {} | null; + "includeShadowDom": boolean; + "indexHtmlFile": string; + "isInteractive": boolean; + "isNewProject": boolean; + "isTextTerminal": boolean; + "modifyObstructiveCode": boolean; + "morgan": boolean; + "namespace": string; + "numTestsKeptInMemory": number; + "pageLoadTimeout": number; + "parentTestsFolder": string; + "parentTestsFolderDisplay": string; + "platform": "linux" | "darwin" | "win32"; + "port": number | null; + "projectId": string | null; + "projectName": string; + "projectRoot": string; + "protocolEnabled": boolean; + "proxyUrl": string; + "redirectionLimit": number; + "remote": Cypress.RemoteState; + "repoRoot": string | null; + "report": boolean; + "reporter": string; + "reporterOptions": {}; + "reporterRoute": string; + "reporterUrl": string; + "requestTimeout": number; + "resolvedNodePath": string; + "resolvedNodeVersion": string; + "responseTimeout": number; + "retries": Cypress.Nullable; + "runMode": Cypress.Nullable; + } | Cypress.RetryStrategyWithModeSpecs>; + "screenshotOnRunFailure": boolean; + "screenshotsFolder": string | false; + "scrollBehavior": Cypress.scrollBehaviorOptions; + "setupNodeEvents": (on, config) => void | Cypress.PluginConfigOptions | Promise; + "slowTestThreshold": number; + "socketId": string | null; + "socketIoCookie": string; + "socketIoRoute": string; + "spec": Cypress.Spec | null; + "specPattern": string | string[]; + "specs": Cypress.Spec[]; + "supportFile": string | false; + "supportFolder": string; + "taskTimeout": number; + "testIsolation": boolean; + "testingType": Cypress.TestingType; + "trashAssetsBeforeRuns": boolean; + "userAgent": string | null; + "version": string; + "video": boolean; + "videoCompression": number | boolean; + "videosFolder": string; + "viewportHeight": number; + "viewportWidth": number; + "waitForAnimations": boolean; + "watchForFileChanges": boolean; +} +``` + +Modified Cypress configuration + +| Member | Type | +| :------ | :------ | +| `animationDistanceThreshold` | `number` | +| `arch` | `string` | +| `autoOpen` | `boolean` | +| `baseUrl` | `string` \| `null` | +| `blockHosts` | `string` \| `string`[] \| `null` | +| `browser` | `Cypress.Browser` | +| `browserUrl` | `string` | +| `browsers` | `Cypress.Browser`[] | +| `chromeWebSecurity` | `boolean` | +| `clientCertificates` | `Cypress.ClientCertificate`[] | +| `clientRoute` | `string` | +| `component` | `Cypress.ComponentConfigOptions`\<`any`\> | +| `configFile` | `string` | +| `cypressBinaryRoot` | `string` | +| `cypressEnv` | `string` | +| `defaultCommandTimeout` | `number` | +| `devServerPublicPathRoute` | `string` | +| `downloadsFolder` | `string` | +| `e2e` | `Cypress.EndToEndConfigOptions` | +| `env` | \{\} | +| `excludeSpecPattern` | `string` \| `string`[] | +| `execTimeout` | `number` | +| `experimentalCspAllowList` | `boolean` \| `Cypress.experimentalCspAllowedDirectives`[] | +| `experimentalFetchPolyfill` | `boolean` | +| `experimentalInteractiveRunEvents` | `boolean` | +| `experimentalMemoryManagement` | `boolean` | +| `experimentalModifyObstructiveThirdPartyCode` | `boolean` | +| `experimentalSkipDomainInjection` | `string`[] \| `null` | +| `experimentalSourceRewriting` | `boolean` | +| `experimentalStudio` | `boolean` | +| `experimentalWebKitSupport` | `boolean` | +| `fileServerFolder` | `string` | +| `fixturesFolder` | `string` \| `false` | +| `hideCommandLog` | `boolean` | +| `hideRunnerUi` | `boolean` | +| `hosts` | \{\} \| `null` | +| `includeShadowDom` | `boolean` | +| `indexHtmlFile` | `string` | +| `isInteractive` | `boolean` | +| `isNewProject` | `boolean` | +| `isTextTerminal` | `boolean` | +| `modifyObstructiveCode` | `boolean` | +| `morgan` | `boolean` | +| `namespace` | `string` | +| `numTestsKeptInMemory` | `number` | +| `pageLoadTimeout` | `number` | +| `parentTestsFolder` | `string` | +| `parentTestsFolderDisplay` | `string` | +| `platform` | `"linux"` \| `"darwin"` \| `"win32"` | +| `port` | `number` \| `null` | +| `projectId` | `string` \| `null` | +| `projectName` | `string` | +| `projectRoot` | `string` | +| `protocolEnabled` | `boolean` | +| `proxyUrl` | `string` | +| `redirectionLimit` | `number` | +| `remote` | `Cypress.RemoteState` | +| `repoRoot` | `string` \| `null` | +| `report` | `boolean` | +| `reporter` | `string` | +| `reporterOptions` | \{\} | +| `reporterRoute` | `string` | +| `reporterUrl` | `string` | +| `requestTimeout` | `number` | +| `resolvedNodePath` | `string` | +| `resolvedNodeVersion` | `string` | +| `responseTimeout` | `number` | +| `retries` | `Cypress.Nullable`\<`number` \| \{ + `"openMode"`: `Cypress.Nullable`\<`number`\>; + `"runMode"`: `Cypress.Nullable`\<`number`\>; + \} \| `Cypress.RetryStrategyWithModeSpecs`\> | +| `screenshotOnRunFailure` | `boolean` | +| `screenshotsFolder` | `string` \| `false` | +| `scrollBehavior` | `Cypress.scrollBehaviorOptions` | +| `setupNodeEvents` | (`on`, `config`) => `void` \| `Cypress.PluginConfigOptions` \| `Promise`\<`void` \| `Cypress.PluginConfigOptions`\> | +| `slowTestThreshold` | `number` | +| `socketId` | `string` \| `null` | +| `socketIoCookie` | `string` | +| `socketIoRoute` | `string` | +| `spec` | `Cypress.Spec` \| `null` | +| `specPattern` | `string` \| `string`[] | +| `specs` | `Cypress.Spec`[] | +| `supportFile` | `string` \| `false` | +| `supportFolder` | `string` | +| `taskTimeout` | `number` | +| `testIsolation` | `boolean` | +| `testingType` | `Cypress.TestingType` | +| `trashAssetsBeforeRuns` | `boolean` | +| `userAgent` | `string` \| `null` | +| `version` | `string` | +| `video` | `boolean` | +| `videoCompression` | `number` \| `boolean` | +| `videosFolder` | `string` | +| `viewportHeight` | `number` | +| `viewportWidth` | `number` | +| `waitForAnimations` | `boolean` | +| `watchForFileChanges` | `boolean` | + +## Throws + +Error If no Chrome browser is found in the configuration diff --git a/docs/api/cypress/functions/configureSynpressForMetaMask.md b/docs/api/cypress/functions/configureSynpressForMetaMask.md new file mode 100644 index 000000000..c64912712 --- /dev/null +++ b/docs/api/cypress/functions/configureSynpressForMetaMask.md @@ -0,0 +1,350 @@ +# Function: configureSynpressForMetaMask() + +```ts +function configureSynpressForMetaMask( + on, + config, + importDefaultWallet?): { + "animationDistanceThreshold": number; + "arch": string; + "autoOpen": boolean; + "baseUrl": string | null; + "blockHosts": string | string[] | null; + "browser": Cypress.Browser; + "browserUrl": string; + "browsers": Cypress.Browser[]; + "chromeWebSecurity": boolean; + "clientCertificates": Cypress.ClientCertificate[]; + "clientRoute": string; + "component": Cypress.ComponentConfigOptions; + "configFile": string; + "cypressBinaryRoot": string; + "cypressEnv": string; + "defaultCommandTimeout": number; + "devServerPublicPathRoute": string; + "downloadsFolder": string; + "e2e": Cypress.EndToEndConfigOptions; + "env": {}; + "excludeSpecPattern": string | string[]; + "execTimeout": number; + "experimentalCspAllowList": boolean | Cypress.experimentalCspAllowedDirectives[]; + "experimentalFetchPolyfill": boolean; + "experimentalInteractiveRunEvents": boolean; + "experimentalMemoryManagement": boolean; + "experimentalModifyObstructiveThirdPartyCode": boolean; + "experimentalSkipDomainInjection": string[] | null; + "experimentalSourceRewriting": boolean; + "experimentalStudio": boolean; + "experimentalWebKitSupport": boolean; + "fileServerFolder": string; + "fixturesFolder": string | false; + "hideCommandLog": boolean; + "hideRunnerUi": boolean; + "hosts": {} | null; + "includeShadowDom": boolean; + "indexHtmlFile": string; + "isInteractive": boolean; + "isNewProject": boolean; + "isTextTerminal": boolean; + "modifyObstructiveCode": boolean; + "morgan": boolean; + "namespace": string; + "numTestsKeptInMemory": number; + "pageLoadTimeout": number; + "parentTestsFolder": string; + "parentTestsFolderDisplay": string; + "platform": "darwin" | "linux" | "win32"; + "port": number | null; + "projectId": string | null; + "projectName": string; + "projectRoot": string; + "protocolEnabled": boolean; + "proxyUrl": string; + "redirectionLimit": number; + "remote": Cypress.RemoteState; + "repoRoot": string | null; + "report": boolean; + "reporter": string; + "reporterOptions": {}; + "reporterRoute": string; + "reporterUrl": string; + "requestTimeout": number; + "resolvedNodePath": string; + "resolvedNodeVersion": string; + "responseTimeout": number; + "retries": Cypress.Nullable; + "runMode": Cypress.Nullable; + } | Cypress.RetryStrategyWithModeSpecs>; + "screenshotOnRunFailure": boolean; + "screenshotsFolder": string | false; + "scrollBehavior": Cypress.scrollBehaviorOptions; + "setupNodeEvents": (on, config) => void | Cypress.PluginConfigOptions | Promise; + "slowTestThreshold": number; + "socketId": string | null; + "socketIoCookie": string; + "socketIoRoute": string; + "spec": Cypress.Spec | null; + "specPattern": string | string[]; + "specs": Cypress.Spec[]; + "supportFile": string | false; + "supportFolder": string; + "taskTimeout": number; + "testIsolation": boolean; + "testingType": Cypress.TestingType; + "trashAssetsBeforeRuns": boolean; + "userAgent": string | null; + "version": string; + "video": boolean; + "videoCompression": number | boolean; + "videosFolder": string; + "viewportHeight": number; + "viewportWidth": number; + "waitForAnimations": boolean; + "watchForFileChanges": boolean; +} +``` + +Configures Synpress for use with MetaMask. + +This function sets up the necessary configurations and hooks for running +Cypress tests with MetaMask. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `on` | `PluginEvents` | Cypress plugin event handler | +| `config` | `PluginConfigOptions` | Cypress plugin configuration options | +| `importDefaultWallet`? | `boolean` | Whether to import the default wallet | + +## Returns + +```ts +{ + "animationDistanceThreshold": number; + "arch": string; + "autoOpen": boolean; + "baseUrl": string | null; + "blockHosts": string | string[] | null; + "browser": Cypress.Browser; + "browserUrl": string; + "browsers": Cypress.Browser[]; + "chromeWebSecurity": boolean; + "clientCertificates": Cypress.ClientCertificate[]; + "clientRoute": string; + "component": Cypress.ComponentConfigOptions; + "configFile": string; + "cypressBinaryRoot": string; + "cypressEnv": string; + "defaultCommandTimeout": number; + "devServerPublicPathRoute": string; + "downloadsFolder": string; + "e2e": Cypress.EndToEndConfigOptions; + "env": {}; + "excludeSpecPattern": string | string[]; + "execTimeout": number; + "experimentalCspAllowList": boolean | Cypress.experimentalCspAllowedDirectives[]; + "experimentalFetchPolyfill": boolean; + "experimentalInteractiveRunEvents": boolean; + "experimentalMemoryManagement": boolean; + "experimentalModifyObstructiveThirdPartyCode": boolean; + "experimentalSkipDomainInjection": string[] | null; + "experimentalSourceRewriting": boolean; + "experimentalStudio": boolean; + "experimentalWebKitSupport": boolean; + "fileServerFolder": string; + "fixturesFolder": string | false; + "hideCommandLog": boolean; + "hideRunnerUi": boolean; + "hosts": {} | null; + "includeShadowDom": boolean; + "indexHtmlFile": string; + "isInteractive": boolean; + "isNewProject": boolean; + "isTextTerminal": boolean; + "modifyObstructiveCode": boolean; + "morgan": boolean; + "namespace": string; + "numTestsKeptInMemory": number; + "pageLoadTimeout": number; + "parentTestsFolder": string; + "parentTestsFolderDisplay": string; + "platform": "darwin" | "linux" | "win32"; + "port": number | null; + "projectId": string | null; + "projectName": string; + "projectRoot": string; + "protocolEnabled": boolean; + "proxyUrl": string; + "redirectionLimit": number; + "remote": Cypress.RemoteState; + "repoRoot": string | null; + "report": boolean; + "reporter": string; + "reporterOptions": {}; + "reporterRoute": string; + "reporterUrl": string; + "requestTimeout": number; + "resolvedNodePath": string; + "resolvedNodeVersion": string; + "responseTimeout": number; + "retries": Cypress.Nullable; + "runMode": Cypress.Nullable; + } | Cypress.RetryStrategyWithModeSpecs>; + "screenshotOnRunFailure": boolean; + "screenshotsFolder": string | false; + "scrollBehavior": Cypress.scrollBehaviorOptions; + "setupNodeEvents": (on, config) => void | Cypress.PluginConfigOptions | Promise; + "slowTestThreshold": number; + "socketId": string | null; + "socketIoCookie": string; + "socketIoRoute": string; + "spec": Cypress.Spec | null; + "specPattern": string | string[]; + "specs": Cypress.Spec[]; + "supportFile": string | false; + "supportFolder": string; + "taskTimeout": number; + "testIsolation": boolean; + "testingType": Cypress.TestingType; + "trashAssetsBeforeRuns": boolean; + "userAgent": string | null; + "version": string; + "video": boolean; + "videoCompression": number | boolean; + "videosFolder": string; + "viewportHeight": number; + "viewportWidth": number; + "waitForAnimations": boolean; + "watchForFileChanges": boolean; +} +``` + +Modified Cypress configuration + +| Member | Type | +| :------ | :------ | +| `animationDistanceThreshold` | `number` | +| `arch` | `string` | +| `autoOpen` | `boolean` | +| `baseUrl` | `string` \| `null` | +| `blockHosts` | `string` \| `string`[] \| `null` | +| `browser` | `Cypress.Browser` | +| `browserUrl` | `string` | +| `browsers` | `Cypress.Browser`[] | +| `chromeWebSecurity` | `boolean` | +| `clientCertificates` | `Cypress.ClientCertificate`[] | +| `clientRoute` | `string` | +| `component` | `Cypress.ComponentConfigOptions`\<`any`\> | +| `configFile` | `string` | +| `cypressBinaryRoot` | `string` | +| `cypressEnv` | `string` | +| `defaultCommandTimeout` | `number` | +| `devServerPublicPathRoute` | `string` | +| `downloadsFolder` | `string` | +| `e2e` | `Cypress.EndToEndConfigOptions` | +| `env` | \{\} | +| `excludeSpecPattern` | `string` \| `string`[] | +| `execTimeout` | `number` | +| `experimentalCspAllowList` | `boolean` \| `Cypress.experimentalCspAllowedDirectives`[] | +| `experimentalFetchPolyfill` | `boolean` | +| `experimentalInteractiveRunEvents` | `boolean` | +| `experimentalMemoryManagement` | `boolean` | +| `experimentalModifyObstructiveThirdPartyCode` | `boolean` | +| `experimentalSkipDomainInjection` | `string`[] \| `null` | +| `experimentalSourceRewriting` | `boolean` | +| `experimentalStudio` | `boolean` | +| `experimentalWebKitSupport` | `boolean` | +| `fileServerFolder` | `string` | +| `fixturesFolder` | `string` \| `false` | +| `hideCommandLog` | `boolean` | +| `hideRunnerUi` | `boolean` | +| `hosts` | \{\} \| `null` | +| `includeShadowDom` | `boolean` | +| `indexHtmlFile` | `string` | +| `isInteractive` | `boolean` | +| `isNewProject` | `boolean` | +| `isTextTerminal` | `boolean` | +| `modifyObstructiveCode` | `boolean` | +| `morgan` | `boolean` | +| `namespace` | `string` | +| `numTestsKeptInMemory` | `number` | +| `pageLoadTimeout` | `number` | +| `parentTestsFolder` | `string` | +| `parentTestsFolderDisplay` | `string` | +| `platform` | `"darwin"` \| `"linux"` \| `"win32"` | +| `port` | `number` \| `null` | +| `projectId` | `string` \| `null` | +| `projectName` | `string` | +| `projectRoot` | `string` | +| `protocolEnabled` | `boolean` | +| `proxyUrl` | `string` | +| `redirectionLimit` | `number` | +| `remote` | `Cypress.RemoteState` | +| `repoRoot` | `string` \| `null` | +| `report` | `boolean` | +| `reporter` | `string` | +| `reporterOptions` | \{\} | +| `reporterRoute` | `string` | +| `reporterUrl` | `string` | +| `requestTimeout` | `number` | +| `resolvedNodePath` | `string` | +| `resolvedNodeVersion` | `string` | +| `responseTimeout` | `number` | +| `retries` | `Cypress.Nullable`\<`number` \| \{ + `"openMode"`: `Cypress.Nullable`\<`number`\>; + `"runMode"`: `Cypress.Nullable`\<`number`\>; + \} \| `Cypress.RetryStrategyWithModeSpecs`\> | +| `screenshotOnRunFailure` | `boolean` | +| `screenshotsFolder` | `string` \| `false` | +| `scrollBehavior` | `Cypress.scrollBehaviorOptions` | +| `setupNodeEvents` | (`on`, `config`) => `void` \| `Cypress.PluginConfigOptions` \| `Promise`\<`void` \| `Cypress.PluginConfigOptions`\> | +| `slowTestThreshold` | `number` | +| `socketId` | `string` \| `null` | +| `socketIoCookie` | `string` | +| `socketIoRoute` | `string` | +| `spec` | `Cypress.Spec` \| `null` | +| `specPattern` | `string` \| `string`[] | +| `specs` | `Cypress.Spec`[] | +| `supportFile` | `string` \| `false` | +| `supportFolder` | `string` | +| `taskTimeout` | `number` | +| `testIsolation` | `boolean` | +| `testingType` | `Cypress.TestingType` | +| `trashAssetsBeforeRuns` | `boolean` | +| `userAgent` | `string` \| `null` | +| `version` | `string` | +| `video` | `boolean` | +| `videoCompression` | `number` \| `boolean` | +| `videosFolder` | `string` | +| `viewportHeight` | `number` | +| `viewportWidth` | `number` | +| `waitForAnimations` | `boolean` | +| `watchForFileChanges` | `boolean` | + +## Throws + +Error If no Chrome browser is found in the configuration + +## Remarks + +This function performs the following tasks: + +1. Filters the available browsers to ensure only Chrome is used. +2. Sets up a 'before:browser:launch' hook to enable debug mode, establish + a Playwright connection, and initialize MetaMask. +3. Sets up a 'before:spec' hook to import the MetaMask wallet before + each test spec runs. +4. Provides task handlers for various MetaMask-related operations. + +## Example + +```typescript +import { configureSynpress } from './configureSynpress'; + +export default (on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) => { + return configureSynpress(on, config); +}; +``` diff --git a/docs/api/cypress/functions/initMetaMask.md b/docs/api/cypress/functions/initMetaMask.md new file mode 100644 index 000000000..f7b5a7078 --- /dev/null +++ b/docs/api/cypress/functions/initMetaMask.md @@ -0,0 +1,29 @@ +# Function: initMetaMask() + +```ts +function initMetaMask(): Promise<{ + "browserArgs": string[]; + "extensions": string[]; +}> +``` + +Initializes MetaMask for Cypress tests. + +This function prepares the MetaMask extension for use in Cypress tests. +It sets up the necessary browser arguments and extension paths. + +## Returns + +`Promise`\<\{ + `"browserArgs"`: `string`[]; + `"extensions"`: `string`[]; + \}\> + +An object containing the extension path and browser arguments. + +| Member | Type | +| :------ | :------ | +| `browserArgs` | `string`[] | +| `extensions` | `string`[] | + +## Async diff --git a/docs/api/cypress/index.md b/docs/api/cypress/index.md new file mode 100644 index 000000000..30ad88589 --- /dev/null +++ b/docs/api/cypress/index.md @@ -0,0 +1,10 @@ +# cypress + +## Index + +| Member | Description | +| :------ | :------ | +| [MetaMask](classes/MetaMask.md) | MetaMask class for interacting with the MetaMask extension in Cypress tests. | +| [configureSynpressForEthereumWalletMock](functions/configureSynpressForEthereumWalletMock.md) | Configures Synpress for use with the Ethereum Wallet Mock. | +| [configureSynpressForMetaMask](functions/configureSynpressForMetaMask.md) | Configures Synpress for use with MetaMask. | +| [initMetaMask](functions/initMetaMask.md) | Initializes MetaMask for Cypress tests. | diff --git a/docs/api/cypress/support/functions/mockEthereum.md b/docs/api/cypress/support/functions/mockEthereum.md new file mode 100644 index 000000000..c44407445 --- /dev/null +++ b/docs/api/cypress/support/functions/mockEthereum.md @@ -0,0 +1,36 @@ +# Function: mockEthereum() + +```ts +function mockEthereum(): void +``` + +Mock Ethereum Environment for Cypress Tests + +This module provides a function to set up a mocked Ethereum environment +for Cypress tests. It utilizes the Web3Mock library to simulate Ethereum +blockchain interactions and MetaMask wallet behavior. + +## Returns + +`void` + +## Remarks + +Key features: +- Mocks the Ethereum blockchain environment +- Simulates MetaMask wallet functionality +- Automatically applied before each test suite + +This function is typically called in the Cypress support file or test +setup to ensure all tests run in a controlled, mocked Ethereum environment. +It allows for consistent and predictable testing of Ethereum-based +applications without the need for a real blockchain or wallet. + +## Example + +```typescript +// In your Cypress support file +import { mockEthereum } from '@synthetixio/synpress'; + +mockEthereum(); +``` diff --git a/docs/api/cypress/support/functions/synpressCommandsForEthereumWalletMock.md b/docs/api/cypress/support/functions/synpressCommandsForEthereumWalletMock.md new file mode 100644 index 000000000..1dd0b0022 --- /dev/null +++ b/docs/api/cypress/support/functions/synpressCommandsForEthereumWalletMock.md @@ -0,0 +1,22 @@ +# Function: synpressCommandsForEthereumWalletMock() + +```ts +function synpressCommandsForEthereumWalletMock(): void +``` + +Initializes Synpress commands for the Ethereum Wallet Mock. + +This function adds custom Cypress commands for interacting with a mocked Ethereum wallet. +These commands include wallet import, account management, network operations, and dApp connections. + +## Returns + +`void` + +## Example + +```typescript +import { synpressCommandsForEthereumWalletMock } from '@synthetixio/synpress'; + +synpressCommandsForEthereumWalletMock(); +``` diff --git a/docs/api/cypress/support/functions/synpressCommandsForMetaMask.md b/docs/api/cypress/support/functions/synpressCommandsForMetaMask.md new file mode 100644 index 000000000..b79edc8be --- /dev/null +++ b/docs/api/cypress/support/functions/synpressCommandsForMetaMask.md @@ -0,0 +1,11 @@ +# Function: synpressCommandsForMetaMask() + +```ts +function synpressCommandsForMetaMask(): void +``` + +Initializes Synpress commands for MetaMask + +## Returns + +`void` diff --git a/docs/api/cypress/support/index.md b/docs/api/cypress/support/index.md new file mode 100644 index 000000000..5bc7d7cc1 --- /dev/null +++ b/docs/api/cypress/support/index.md @@ -0,0 +1,9 @@ +# cypress/support + +## Index + +| Member | Description | +| :------ | :------ | +| [mockEthereum](functions/mockEthereum.md) | Mock Ethereum Environment for Cypress Tests | +| [synpressCommandsForEthereumWalletMock](functions/synpressCommandsForEthereumWalletMock.md) | Initializes Synpress commands for the Ethereum Wallet Mock. | +| [synpressCommandsForMetaMask](functions/synpressCommandsForMetaMask.md) | Initializes Synpress commands for MetaMask | diff --git a/docs/api/functions/ethereumWalletMockFixtures.md b/docs/api/functions/ethereumWalletMockFixtures.md deleted file mode 100644 index 06498e8ef..000000000 --- a/docs/api/functions/ethereumWalletMockFixtures.md +++ /dev/null @@ -1,16 +0,0 @@ -# Function: ethereumWalletMockFixtures() - -```ts -function ethereumWalletMockFixtures(title, testFunction): void -``` - -## Parameters - -| Parameter | Type | -| :------ | :------ | -| `title` | `string` | -| `testFunction` | (`args`, `testInfo`) => `void` \| `Promise`\<`void`\> | - -## Returns - -`void` diff --git a/docs/api/index.md b/docs/api/index.md index 908a38999..af6738c51 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -1,11 +1,8 @@ # @synthetixio/synpress -| Member | Description | -| :------ |:--------------------------------------------------------------------------------------------------------------| -| [EthereumWalletMock](classes/EthereumWalletMock.md) | This class in the mocked wallet communication hub. It should be used to fetch and change mock state. | -| [MetaMask](classes/MetaMask.md) | This class is the heart of Synpress's MetaMask API. | -| [ethereumWalletMockFixtures](functions/ethereumWalletMockFixtures.md) | Set of fixtures to improve mocked wallets developer experience.
| -| [metaMaskFixtures](functions/metaMaskFixtures.md) | Multile fixtures to speedup MetaMask testing. | -| [defineWalletSetup](functions/defineWalletSetup.md) | This function is used to define how a wallet should be set up. | -| [getExtensionId](functions/getExtensionId.md) | Returns the extension ID for the given extension name. The ID is fetched from the `chrome://extensions` page. | -| [testWithSynpress](functions/testWithSynpress.md) | Simple & beautiful - entry point to the framework. | +| Member | Description | +| :------ | :------ | +| [cypress](cypress/index.md) | - | +| [cypress/support](cypress/support/index.md) | - | +| [index](index/index.md) | - | +| [playwright](playwright/index.md) | - | diff --git a/docs/api/functions/defineWalletSetup.md b/docs/api/index/functions/defineWalletSetup.md similarity index 100% rename from docs/api/functions/defineWalletSetup.md rename to docs/api/index/functions/defineWalletSetup.md diff --git a/docs/api/functions/testWithSynpress.md b/docs/api/index/functions/testWithSynpress.md similarity index 100% rename from docs/api/functions/testWithSynpress.md rename to docs/api/index/functions/testWithSynpress.md diff --git a/docs/api/index/index.md b/docs/api/index/index.md new file mode 100644 index 000000000..007b85964 --- /dev/null +++ b/docs/api/index/index.md @@ -0,0 +1,8 @@ +# index + +## Index + +| Member | Description | +| :------ | :------ | +| [defineWalletSetup](functions/defineWalletSetup.md) | This function is used to define how a wallet should be set up. | +| [testWithSynpress](functions/testWithSynpress.md) | - | diff --git a/docs/api/playwright/classes/EthereumWalletMock.md b/docs/api/playwright/classes/EthereumWalletMock.md new file mode 100644 index 000000000..217a83ec8 --- /dev/null +++ b/docs/api/playwright/classes/EthereumWalletMock.md @@ -0,0 +1,258 @@ +# Class: EthereumWalletMock + +Mock implementation of an Ethereum wallet for testing purposes. +Simulates wallet behavior in a controlled environment, allowing for consistent +and reproducible tests without relying on actual blockchain interactions. + +## Extends + +- `EthereumWalletMockAbstract` + +## Constructors + +### new EthereumWalletMock() + +```ts +new EthereumWalletMock(page, wallet?): EthereumWalletMock +``` + +Creates an instance of EthereumWalletMock. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `page` | `Page` | The Playwright Page object to interact with. | +| `wallet`? | `WalletMock` | The type of wallet to mock. | + +#### Returns + +[`EthereumWalletMock`](EthereumWalletMock.md) + +#### Overrides + +`EthereumWalletMockAbstract.constructor` + +## Properties + +| Property | Type | Description | Inherited from | +| :------ | :------ | :------ | :------ | +| `page` | `Page` | The Playwright Page object to interact with. | - | +| `seedPhrase` | `undefined` \| `string` | - | `EthereumWalletMockAbstract.seedPhrase` | +| `wallet` | `WalletMock` | - | `EthereumWalletMockAbstract.wallet` | + +## Methods + +### addNetwork() + +```ts +addNetwork(network): Promise +``` + +Adds a new network. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `network` | `Network` | The network object to use for adding the new network. | + +#### Returns + +`Promise`\<`void`\> + +A promise that resolves when the network is added. + +#### Overrides + +`EthereumWalletMockAbstract.addNetwork` + +*** + +### addNewAccount() + +```ts +addNewAccount(): Promise +``` + +Adds a new account based on the initially imported seed phrase. + +#### Returns + +`Promise`\<`void`\> + +A promise that resolves when the new account is added. + +#### Overrides + +`EthereumWalletMockAbstract.addNewAccount` + +*** + +### connectToDapp() + +```ts +connectToDapp(wallet?): Promise +``` + +Connects wallet to the dapp. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `wallet`? | `WalletMock` | The wallet to connect to the dapp. | + +#### Returns + +`Promise`\<`void`\> + +A promise that resolves when the wallet is connected to the dapp. + +#### Overrides + +`EthereumWalletMockAbstract.connectToDapp` + +*** + +### getAccountAddress() + +```ts +getAccountAddress(): Promise +``` + +Retrieves the current account address. + +#### Returns + +`Promise`\<`undefined` \| \`0x$\{string\}\`\> + +A promise that resolves to the current account address. + +#### Overrides + +`EthereumWalletMockAbstract.getAccountAddress` + +*** + +### getAllAccounts() + +```ts +getAllAccounts(): Promise +``` + +Retrieves all account addresses. + +#### Returns + +`Promise`\<`undefined` \| \`0x$\{string\}\`[]\> + +A promise that resolves to an array of account addresses. + +#### Overrides + +`EthereumWalletMockAbstract.getAllAccounts` + +*** + +### importWallet() + +```ts +importWallet(seedPhrase): Promise +``` + +Imports a wallet using the given seed phrase. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `seedPhrase` | `string` | The seed phrase to import. | + +#### Returns + +`Promise`\<`void`\> + +A promise that resolves when the wallet is imported. + +#### Overrides + +`EthereumWalletMockAbstract.importWallet` + +*** + +### importWalletFromPrivateKey() + +```ts +importWalletFromPrivateKey(privateKey): Promise +``` + +Imports a wallet using the given private key. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `privateKey` | \`0x$\{string\}\` | The private key to import. | + +#### Returns + +`Promise`\<`void`\> + +A promise that resolves when the wallet is imported. + +#### Overrides + +`EthereumWalletMockAbstract.importWalletFromPrivateKey` + +*** + +### switchAccount() + +```ts +switchAccount(accountAddress): Promise +``` + +Switches to the account with the given address. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `accountAddress` | `string` | The address of the account to switch to. | + +#### Returns + +`Promise`\<`void`\> + +A promise that resolves when the account switch is complete. + +#### Overrides + +`EthereumWalletMockAbstract.switchAccount` + +*** + +### switchNetwork() + +```ts +switchNetwork(networkName): Promise +``` + +Switches to the network with the given name. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `networkName` | `string` | The name of the network to switch to. | + +#### Returns + +`Promise`\<`void`\> + +A promise that resolves when the network switch is complete. + +#### Overrides + +`EthereumWalletMockAbstract.switchNetwork` diff --git a/docs/api/playwright/classes/MetaMask.md b/docs/api/playwright/classes/MetaMask.md new file mode 100644 index 000000000..5c706026e --- /dev/null +++ b/docs/api/playwright/classes/MetaMask.md @@ -0,0 +1,855 @@ +# Class: MetaMask + +MetaMask class for interacting with the MetaMask extension in Playwright tests. + +This class provides methods to perform various operations on the MetaMask extension, +such as importing wallets, switching networks, confirming transactions, and more. + +## Extends + +- `MetaMaskAbstract` + +## Constructors + +### new MetaMask() + +```ts +new MetaMask( + context, + page, + password, + extensionId?): MetaMask +``` + +Creates an instance of MetaMask. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `context` | `BrowserContext` | The Playwright BrowserContext in which the MetaMask extension is running. | +| `page` | `Page` | The Playwright Page object representing the MetaMask extension's main page. | +| `password` | `string` | The password for the MetaMask wallet. | +| `extensionId`? | `string` | The ID of the MetaMask extension. Optional if no interaction with dapps is required. | + +#### Returns + +[`MetaMask`](MetaMask.md) + +#### Overrides + +`MetaMaskAbstract.constructor` + +## Properties + +| Property | Modifier | Type | Description | Overrides | +| :------ | :------ | :------ | :------ | :------ | +| `context` | `readonly` | `BrowserContext` | - | - | +| `crashPage` | `readonly` | `CrashPage` | This property can be used to access selectors for the crash page. | - | +| `extensionId?` | `readonly` | `string` | - | `MetaMaskAbstract.extensionId` | +| `homePage` | `readonly` | `HomePage` | This property can be used to access selectors for the home page. | - | +| `lockPage` | `readonly` | `LockPage` | This property can be used to access selectors for the lock page. | - | +| `notificationPage` | `readonly` | `NotificationPage` | This property can be used to access selectors for the notification page. | - | +| `onboardingPage` | `readonly` | `OnboardingPage` | This property can be used to access selectors for the onboarding page. | - | +| `page` | `readonly` | `Page` | - | - | +| `password` | `readonly` | `string` | - | `MetaMaskAbstract.password` | +| `settingsPage` | `readonly` | `SettingsPage` | This property can be used to access selectors for the settings page. | - | + +## Methods + +### addNetwork() + +```ts +addNetwork(network): Promise +``` + +Adds a new network to MetaMask. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `network` | `object` | The network configuration to add. | +| `network.blockExplorerUrl`? | `string` | - | +| `network.chainId` | `number` | - | +| `network.name` | `string` | - | +| `network.rpcUrl` | `string` | - | +| `network.symbol` | `string` | - | + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.addNetwork` + +*** + +### addNewAccount() + +```ts +addNewAccount(accountName): Promise +``` + +Adds a new account with the given name. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `accountName` | `string` | The name for the new account. | + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.addNewAccount` + +*** + +### addNewToken() + +```ts +addNewToken(): Promise +``` + +Adds a new token. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.addNewToken` + +#### Throws + +If extensionId is not set. + +*** + +### approveNewNetwork() + +```ts +approveNewNetwork(): Promise +``` + +Approves adding a new network. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.approveNewNetwork` + +#### Throws + +If extensionId is not set. + +*** + +### approveSwitchNetwork() + +```ts +approveSwitchNetwork(): Promise +``` + +Approves switching to a new network. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.approveSwitchNetwork` + +#### Throws + +If extensionId is not set. + +*** + +### approveTokenPermission() + +```ts +approveTokenPermission(options?): Promise +``` + +Approves a token permission request. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `options`? | `object` | Optional settings for the approval. | +| `options.gasSetting`? | \| `"low"` \| `"market"` \| `"aggressive"` \| `"site"` \| \{ `"gasLimit"`: `number`; `"maxBaseFee"`: `number`; `"priorityFee"`: `number`; \} | - | +| `options.spendLimit`? | `number` \| `"max"` | - | + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.approveTokenPermission` + +#### Throws + +If extensionId is not set. + +*** + +### closeTransactionDetails() + +```ts +closeTransactionDetails(): Promise +``` + +Closes the transaction details view. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.closeTransactionDetails` + +*** + +### confirmSignature() + +```ts +confirmSignature(): Promise +``` + +Confirms a signature request. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.confirmSignature` + +#### Throws + +If extensionId is not set. + +*** + +### confirmSignatureWithRisk() + +```ts +confirmSignatureWithRisk(): Promise +``` + +Confirms a signature request with risk. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.confirmSignatureWithRisk` + +#### Throws + +If extensionId is not set. + +*** + +### confirmTransaction() + +```ts +confirmTransaction(options?): Promise +``` + +Confirms a transaction. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `options`? | `object` | Optional gas settings for the transaction. | +| `options.gasSetting`? | \| `"low"` \| `"market"` \| `"aggressive"` \| `"site"` \| \{ `"gasLimit"`: `number`; `"maxBaseFee"`: `number`; `"priorityFee"`: `number`; \} | - | + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.confirmTransaction` + +#### Throws + +If extensionId is not set. + +*** + +### confirmTransactionAndWaitForMining() + +```ts +confirmTransactionAndWaitForMining(options?): Promise +``` + +Confirms a transaction and waits for it to be mined. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `options`? | `object` | Optional gas settings for the transaction. | +| `options.gasSetting`? | \| `"low"` \| `"market"` \| `"aggressive"` \| `"site"` \| \{ `"gasLimit"`: `number`; `"maxBaseFee"`: `number`; `"priorityFee"`: `number`; \} | - | + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.confirmTransactionAndWaitForMining` + +#### Throws + +If extensionId is not set. + +*** + +### connectToDapp() + +```ts +connectToDapp(accounts?): Promise +``` + +Connects MetaMask to a dapp. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `accounts`? | `string`[] | Optional array of account addresses to connect. | + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.connectToDapp` + +#### Throws + +If extensionId is not set. + +*** + +### decrypt() + +```ts +decrypt(): Promise +``` + +Decrypts a message. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.decrypt` + +#### Throws + +If extensionId is not set. + +*** + +### disableEthSign() + +```ts +disableEthSign(): Promise +``` + +Disables eth_sign. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.disableEthSign` + +*** + +### getAccountAddress() + +```ts +getAccountAddress(): Promise +``` + +Gets the address of the currently selected account. + +#### Returns + +`Promise`\<`string`\> + +The account address. + +#### Overrides + +`MetaMaskAbstract.getAccountAddress` + +*** + +### goBackToHomePage() + +```ts +goBackToHomePage(): Promise +``` + +Navigates back to the home page. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.goBackToHomePage` + +*** + +### importWallet() + +```ts +importWallet(seedPhrase): Promise +``` + +Imports a wallet using the given seed phrase. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `seedPhrase` | `string` | The seed phrase to import. | + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.importWallet` + +*** + +### importWalletFromPrivateKey() + +```ts +importWalletFromPrivateKey(privateKey): Promise +``` + +Imports a wallet using the given private key. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `privateKey` | `string` | The private key to import. | + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.importWalletFromPrivateKey` + +*** + +### lock() + +```ts +lock(): Promise +``` + +Locks the MetaMask wallet. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.lock` + +*** + +### openSettings() + +```ts +openSettings(): Promise +``` + +Opens the settings page. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.openSettings` + +*** + +### openSidebarMenu() + +```ts +openSidebarMenu(menu): Promise +``` + +Opens a specific sidebar menu in the settings. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `menu` | `SettingsSidebarMenus` | The menu to open. | + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.openSidebarMenu` + +*** + +### openTransactionDetails() + +```ts +openTransactionDetails(txIndex): Promise +``` + +Opens the details of a specific transaction. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `txIndex` | `number` | The index of the transaction to open. | + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.openTransactionDetails` + +*** + +### providePublicEncryptionKey() + +```ts +providePublicEncryptionKey(): Promise +``` + +Provides a public encryption key. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.providePublicEncryptionKey` + +#### Throws + +If extensionId is not set. + +*** + +### rejectNewNetwork() + +```ts +rejectNewNetwork(): Promise +``` + +Rejects adding a new network. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.rejectNewNetwork` + +#### Throws + +If extensionId is not set. + +*** + +### rejectSignature() + +```ts +rejectSignature(): Promise +``` + +Rejects a signature request. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.rejectSignature` + +#### Throws + +If extensionId is not set. + +*** + +### rejectSwitchNetwork() + +```ts +rejectSwitchNetwork(): Promise +``` + +Rejects switching to a new network. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.rejectSwitchNetwork` + +#### Throws + +If extensionId is not set. + +*** + +### rejectTokenPermission() + +```ts +rejectTokenPermission(): Promise +``` + +Rejects a token permission request. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.rejectTokenPermission` + +#### Throws + +If extensionId is not set. + +*** + +### rejectTransaction() + +```ts +rejectTransaction(): Promise +``` + +Rejects a transaction. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.rejectTransaction` + +#### Throws + +If extensionId is not set. + +*** + +### renameAccount() + +```ts +renameAccount(currentAccountName, newAccountName): Promise +``` + +Renames the currently selected account. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `currentAccountName` | `string` | The current account name. | +| `newAccountName` | `string` | The new name for the account. | + +#### Returns + +`Promise`\<`void`\> + +*** + +### resetAccount() + +```ts +resetAccount(): Promise +``` + +Resets the account. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.resetAccount` + +*** + +### switchAccount() + +```ts +switchAccount(accountName): Promise +``` + +Switches to the account with the given name. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `accountName` | `string` | The name of the account to switch to. | + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.switchAccount` + +*** + +### switchNetwork() + +```ts +switchNetwork(networkName, isTestnet?): Promise +``` + +Switches to the specified network. + +#### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `networkName` | `string` | The name of the network to switch to. | +| `isTestnet`? | `boolean` | Whether the network is a testnet. Default is false. | + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.switchNetwork` + +*** + +### toggleDismissSecretRecoveryPhraseReminder() + +```ts +toggleDismissSecretRecoveryPhraseReminder(): Promise +``` + +Toggles the dismissal of the secret recovery phrase reminder. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.toggleDismissSecretRecoveryPhraseReminder` + +*** + +### toggleShowTestNetworks() + +```ts +toggleShowTestNetworks(): Promise +``` + +Toggles the display of test networks. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.toggleShowTestNetworks` + +*** + +### unlock() + +```ts +unlock(): Promise +``` + +Unlocks the MetaMask wallet. + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.unlock` + +*** + +### unsafe\_enableEthSign() + +```ts +unsafe_enableEthSign(): Promise +``` + +Enables eth_sign (unsafe). + +#### Returns + +`Promise`\<`void`\> + +#### Overrides + +`MetaMaskAbstract.unsafe_enableEthSign` diff --git a/docs/api/playwright/functions/ethereumWalletMockFixtures.md b/docs/api/playwright/functions/ethereumWalletMockFixtures.md new file mode 100644 index 000000000..9d626db5e --- /dev/null +++ b/docs/api/playwright/functions/ethereumWalletMockFixtures.md @@ -0,0 +1,181 @@ +# Function: ethereumWalletMockFixtures() + +## ethereumWalletMockFixtures(title, body) + +```ts +function ethereumWalletMockFixtures(title, body): void +``` + +Declares a test. +- `test(title, body)` +- `test(title, details, body)` + +**Usage** + +```js +import { test, expect } from '@playwright/test'; + +test('basic test', async ({ page }) => { + await page.goto('https://playwright.dev/'); + // ... +}); +``` + +**Tags** + +You can tag tests by providing additional test details. Alternatively, you can include tags in the test title. Note +that each tag must start with `@` symbol. + +```js +import { test, expect } from '@playwright/test'; + +test('basic test', { + tag: '@smoke', +}, async ({ page }) => { + await page.goto('https://playwright.dev/'); + // ... +}); + +test('another test @smoke', async ({ page }) => { + await page.goto('https://playwright.dev/'); + // ... +}); +``` + +Test tags are displayed in the test report, and are available to a custom reporter via `TestCase.tags` property. + +You can also filter tests by their tags during test execution: +- in the [command line](https://playwright.dev/docs/test-cli#reference); +- in the config with [testConfig.grep](https://playwright.dev/docs/api/class-testconfig#test-config-grep) and + [testProject.grep](https://playwright.dev/docs/api/class-testproject#test-project-grep); + +Learn more about [tagging](https://playwright.dev/docs/test-annotations#tag-tests). + +**Annotations** + +You can annotate tests by providing additional test details. + +```js +import { test, expect } from '@playwright/test'; + +test('basic test', { + annotation: { + type: 'issue', + description: 'https://github.com/microsoft/playwright/issues/23180', + }, +}, async ({ page }) => { + await page.goto('https://playwright.dev/'); + // ... +}); +``` + +Test annotations are displayed in the test report, and are available to a custom reporter via +`TestCase.annotations` property. + +You can also add annotations during runtime by manipulating +[testInfo.annotations](https://playwright.dev/docs/api/class-testinfo#test-info-annotations). + +Learn more about [test annotations](https://playwright.dev/docs/test-annotations). + +### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `title` | `string` | Test title. | +| `body` | (`args`, `testInfo`) => `void` \| `Promise`\<`void`\> | Test body that takes one or two arguments: an object with fixtures and optional TestInfo. | + +### Returns + +`void` + +## ethereumWalletMockFixtures(title, details, body) + +```ts +function ethereumWalletMockFixtures( + title, + details, + body): void +``` + +Declares a test. +- `test(title, body)` +- `test(title, details, body)` + +**Usage** + +```js +import { test, expect } from '@playwright/test'; + +test('basic test', async ({ page }) => { + await page.goto('https://playwright.dev/'); + // ... +}); +``` + +**Tags** + +You can tag tests by providing additional test details. Alternatively, you can include tags in the test title. Note +that each tag must start with `@` symbol. + +```js +import { test, expect } from '@playwright/test'; + +test('basic test', { + tag: '@smoke', +}, async ({ page }) => { + await page.goto('https://playwright.dev/'); + // ... +}); + +test('another test @smoke', async ({ page }) => { + await page.goto('https://playwright.dev/'); + // ... +}); +``` + +Test tags are displayed in the test report, and are available to a custom reporter via `TestCase.tags` property. + +You can also filter tests by their tags during test execution: +- in the [command line](https://playwright.dev/docs/test-cli#reference); +- in the config with [testConfig.grep](https://playwright.dev/docs/api/class-testconfig#test-config-grep) and + [testProject.grep](https://playwright.dev/docs/api/class-testproject#test-project-grep); + +Learn more about [tagging](https://playwright.dev/docs/test-annotations#tag-tests). + +**Annotations** + +You can annotate tests by providing additional test details. + +```js +import { test, expect } from '@playwright/test'; + +test('basic test', { + annotation: { + type: 'issue', + description: 'https://github.com/microsoft/playwright/issues/23180', + }, +}, async ({ page }) => { + await page.goto('https://playwright.dev/'); + // ... +}); +``` + +Test annotations are displayed in the test report, and are available to a custom reporter via +`TestCase.annotations` property. + +You can also add annotations during runtime by manipulating +[testInfo.annotations](https://playwright.dev/docs/api/class-testinfo#test-info-annotations). + +Learn more about [test annotations](https://playwright.dev/docs/test-annotations). + +### Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `title` | `string` | Test title. | +| `details` | `TestDetails` | Additional test details. | +| `body` | (`args`, `testInfo`) => `void` \| `Promise`\<`void`\> | Test body that takes one or two arguments: an object with fixtures and optional TestInfo. | + +### Returns + +`void` diff --git a/docs/api/functions/getExtensionId.md b/docs/api/playwright/functions/getExtensionId.md similarity index 100% rename from docs/api/functions/getExtensionId.md rename to docs/api/playwright/functions/getExtensionId.md diff --git a/docs/api/functions/metaMaskFixtures.md b/docs/api/playwright/functions/metaMaskFixtures.md similarity index 100% rename from docs/api/functions/metaMaskFixtures.md rename to docs/api/playwright/functions/metaMaskFixtures.md diff --git a/docs/api/playwright/functions/mockEthereum.md b/docs/api/playwright/functions/mockEthereum.md new file mode 100644 index 000000000..174eabb21 --- /dev/null +++ b/docs/api/playwright/functions/mockEthereum.md @@ -0,0 +1,16 @@ +# Function: mockEthereum() + +```ts +function mockEthereum(wallet?, accounts?): void +``` + +## Parameters + +| Parameter | Type | +| :------ | :------ | +| `wallet`? | \| `"metamask"` \| `"coinbase"` \| `"phantom"` \| `"walletconnect"` \| `"walletlink"` | +| `accounts`? | \`0x$\{string\}\`[] | + +## Returns + +`void` diff --git a/docs/api/playwright/functions/unlockForFixture.md b/docs/api/playwright/functions/unlockForFixture.md new file mode 100644 index 000000000..42603d819 --- /dev/null +++ b/docs/api/playwright/functions/unlockForFixture.md @@ -0,0 +1,19 @@ +# Function: unlockForFixture() + +```ts +function unlockForFixture(page, password): Promise +``` + +A more advanced version of the `MetaMask.unlock()` function that incorporates various workarounds for MetaMask issues, among other things. + This function should be used instead of the `MetaMask.unlock()` when passing it to the `testWithSynpress` function. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `page` | `Page` | The MetaMask tab page. | +| `password` | `string` | The password of the MetaMask wallet. | + +## Returns + +`Promise`\<`void`\> diff --git a/docs/api/playwright/index.md b/docs/api/playwright/index.md new file mode 100644 index 000000000..c8394b8c7 --- /dev/null +++ b/docs/api/playwright/index.md @@ -0,0 +1,16 @@ +# playwright + +## Index + +| Member | Description | +| :------ | :------ | +| [EthereumWalletMock](classes/EthereumWalletMock.md) | Mock implementation of an Ethereum wallet for testing purposes. | +| [MetaMask](classes/MetaMask.md) | MetaMask class for interacting with the MetaMask extension in Playwright tests. | +| [DEFAULT\_NETWORK\_ID](variables/DEFAULT_NETWORK_ID.md) | The network ID (Optimism network by default). | +| [PRIVATE\_KEY](variables/PRIVATE_KEY.md) | The private key used for testing purposes. | +| [web3MockPath](variables/web3MockPath.md) | Relative path to the web3-mock bundle. | +| [ethereumWalletMockFixtures](functions/ethereumWalletMockFixtures.md) | Declares a test. | +| [getExtensionId](functions/getExtensionId.md) | Returns the extension ID for the given extension name. The ID is fetched from the `chrome://extensions` page. | +| [metaMaskFixtures](functions/metaMaskFixtures.md) | - | +| [mockEthereum](functions/mockEthereum.md) | - | +| [unlockForFixture](functions/unlockForFixture.md) | A more advanced version of the `MetaMask.unlock()` function that incorporates various workarounds for MetaMask issues, among other things. | diff --git a/docs/api/playwright/variables/DEFAULT_NETWORK_ID.md b/docs/api/playwright/variables/DEFAULT_NETWORK_ID.md new file mode 100644 index 000000000..0164405a6 --- /dev/null +++ b/docs/api/playwright/variables/DEFAULT_NETWORK_ID.md @@ -0,0 +1,9 @@ +# Variable: DEFAULT\_NETWORK\_ID + +```ts +const DEFAULT_NETWORK_ID: "0xa" = "0xa"; +``` + +The network ID (Optimism network by default). + +## Constant diff --git a/docs/api/playwright/variables/PRIVATE_KEY.md b/docs/api/playwright/variables/PRIVATE_KEY.md new file mode 100644 index 000000000..20d53ea63 --- /dev/null +++ b/docs/api/playwright/variables/PRIVATE_KEY.md @@ -0,0 +1,9 @@ +# Variable: PRIVATE\_KEY + +```ts +const PRIVATE_KEY: "ea084c575a01e2bbefcca3db101eaeab1d8af15554640a510c73692db24d0a6a" = "ea084c575a01e2bbefcca3db101eaeab1d8af15554640a510c73692db24d0a6a"; +``` + +The private key used for testing purposes. + +## Constant diff --git a/docs/api/playwright/variables/web3MockPath.md b/docs/api/playwright/variables/web3MockPath.md new file mode 100644 index 000000000..ac2e8b804 --- /dev/null +++ b/docs/api/playwright/variables/web3MockPath.md @@ -0,0 +1,9 @@ +# Variable: web3MockPath + +```ts +const web3MockPath: string; +``` + +Relative path to the web3-mock bundle. + +## Constant diff --git a/docs/api/typedoc-sidebar.json b/docs/api/typedoc-sidebar.json index df96f0b2b..30282d5dc 100644 --- a/docs/api/typedoc-sidebar.json +++ b/docs/api/typedoc-sidebar.json @@ -1,35 +1,97 @@ [ { - "text": "Classes", + "text": "cypress", + "link": "/api/cypress/", "collapsed": true, "items": [ { - "text": "EthereumWalletMock", - "link": "/api/classes/EthereumWalletMock.md" + "text": "Classes", + "collapsed": true, + "items": [{ "text": "MetaMask", "link": "/api/cypress/classes/MetaMask.md" }] }, - { "text": "MetaMask", "link": "/api/classes/MetaMask.md" } + { + "text": "Functions", + "collapsed": true, + "items": [ + { + "text": "configureSynpressForEthereumWalletMock", + "link": "/api/cypress/functions/configureSynpressForEthereumWalletMock.md" + }, + { "text": "configureSynpressForMetaMask", "link": "/api/cypress/functions/configureSynpressForMetaMask.md" }, + { "text": "initMetaMask", "link": "/api/cypress/functions/initMetaMask.md" } + ] + }, + { + "text": "support", + "link": "/api/cypress/support/", + "collapsed": true, + "items": [ + { + "text": "Functions", + "collapsed": true, + "items": [ + { "text": "mockEthereum", "link": "/api/cypress/support/functions/mockEthereum.md" }, + { + "text": "synpressCommandsForEthereumWalletMock", + "link": "/api/cypress/support/functions/synpressCommandsForEthereumWalletMock.md" + }, + { + "text": "synpressCommandsForMetaMask", + "link": "/api/cypress/support/functions/synpressCommandsForMetaMask.md" + } + ] + } + ] + } ] }, { - "text": "Functions", + "text": "index", + "link": "/api/index/", "collapsed": true, "items": [ { - "text": "defineWalletSetup", - "link": "/api/functions/defineWalletSetup.md" - }, + "text": "Functions", + "collapsed": true, + "items": [ + { "text": "defineWalletSetup", "link": "/api/index/functions/defineWalletSetup.md" }, + { "text": "testWithSynpress", "link": "/api/index/functions/testWithSynpress.md" } + ] + } + ] + }, + { + "text": "playwright", + "link": "/api/playwright/", + "collapsed": true, + "items": [ { - "text": "ethereumWalletMockFixtures", - "link": "/api/functions/ethereumWalletMockFixtures.md" + "text": "Classes", + "collapsed": true, + "items": [ + { "text": "EthereumWalletMock", "link": "/api/playwright/classes/EthereumWalletMock.md" }, + { "text": "MetaMask", "link": "/api/playwright/classes/MetaMask.md" } + ] }, - { "text": "getExtensionId", "link": "/api/functions/getExtensionId.md" }, { - "text": "metaMaskFixtures", - "link": "/api/functions/metaMaskFixtures.md" + "text": "Variables", + "collapsed": true, + "items": [ + { "text": "DEFAULT_NETWORK_ID", "link": "/api/playwright/variables/DEFAULT_NETWORK_ID.md" }, + { "text": "PRIVATE_KEY", "link": "/api/playwright/variables/PRIVATE_KEY.md" }, + { "text": "web3MockPath", "link": "/api/playwright/variables/web3MockPath.md" } + ] }, { - "text": "testWithSynpress", - "link": "/api/functions/testWithSynpress.md" + "text": "Functions", + "collapsed": true, + "items": [ + { "text": "ethereumWalletMockFixtures", "link": "/api/playwright/functions/ethereumWalletMockFixtures.md" }, + { "text": "getExtensionId", "link": "/api/playwright/functions/getExtensionId.md" }, + { "text": "metaMaskFixtures", "link": "/api/playwright/functions/metaMaskFixtures.md" }, + { "text": "mockEthereum", "link": "/api/playwright/functions/mockEthereum.md" }, + { "text": "unlockForFixture", "link": "/api/playwright/functions/unlockForFixture.md" } + ] } ] } diff --git a/docs/docs/getting-started.md b/docs/docs/getting-started.md index c63d6f422..6f6c8968e 100644 --- a/docs/docs/getting-started.md +++ b/docs/docs/getting-started.md @@ -1,23 +1,19 @@ # Getting Started ::: warning -This documentation refers to the **alpha** release of Synpress v4. The API is subject to change. +This documentation refers to Synpress v4 and it is still in progress. For Synpress v3 documentation, please refer [here](https://github.com/Synthetixio/synpress). ::: ## Overview -::: info -Support for [Cypress](https://www.cypress.io/) is coming soon. -::: - -Synpress is an E2E (End-to-End) testing library for Web3 dapps. It can be used with ~~ -both~~ [Playwright](https://playwright.dev/) ~~and [Cypress](https://www.cypress.io/)~~. +Synpress is an E2E (End-to-End) testing library for Web3 dapps. It can be used with +both: [Playwright](https://playwright.dev/) and [Cypress](https://www.cypress.io/). Synpress is built with developer experience, stability, and performance in mind: -- **Developer Experience**: Type safety, simple API, comprehensive documentation, support for ~~both~~ Playwright ~~and - Cypress~~ and all of ~~their~~ its features. +- **Developer Experience**: Type safety, simple API, comprehensive documentation, support for both Playwright and + Cypress and all of their its features. - **Stability**: Complete test coverage, bullet-proof wallet integration API. - **Performance**: Optimized for speed, parallelization, and fast feedback loops. @@ -28,15 +24,15 @@ Check out the [Why Synpress](./introduction) section to learn more about the pro ::: code-group ```bash [pnpm] -pnpm add @synthetixio/synpress@alpha +pnpm add @synthetixio/synpress@latest ``` ```bash [npm] -npm i @synthetixio/synpress@alpha +npm i @synthetixio/synpress@latest ``` ```bash [yarn] -yarn add @synthetixio/synpress@alpha +yarn add @synthetixio/synpress@latest ``` ::: @@ -46,42 +42,10 @@ Synpress is now an ESM-only package. Don't use `require()` to import it, and mak contains `"type": "module"`. ::: -## Setup - -1. Import `testWithSynpress` from `@synthetixio/synpress` in your test files to get started. - -```javascript -import { testWithSynpress } from "@synthetixio/synpress"; -``` - -2. Inject the wallet fixtures you want to use (EthereumWalletMock or MetaMask available at the moment). - -```javascript -import { ethereumWalletMockFixtures } from "@synthetixio/synpress"; - -const test = testWithSynpress(ethereumWalletMockFixtures); - -const { expect } = test; -``` - -or - -```javascript -import { metaMaskFixtures } from "@synthetixio/synpress"; - -import basicSetup from "../wallet-setup/basic.setup"; - -const test = testWithSynpress(metaMaskFixtures(basicSetup)); - -const { expect } = test; -``` - -3a. In case you use MetaMask, you also have to setup the `wallet-cache` feature to generate cache. Check out -the [Wallet Cache](./guides/wallet-cache.md) guide for more information. - ## Next Steps For more information on what to do next, check out the following topics: - [**TypeScript**](./typescript) - Learn how to set up TypeScript with Synpress. -- [**Wallet Cache**](./guides/wallet-cache) - Learn what's a wallet cache and how to use it. +- [**Playwright**](./setupPlaywright) - Learn how to set up Playwright with Synpress. +- [**Cypress**](./setupCypress) - Learn how to set up Cypress with Synpress. diff --git a/docs/docs/guides/playwright.md b/docs/docs/guides/playwright.md index 10d2040c4..2042ae9f1 100644 --- a/docs/docs/guides/playwright.md +++ b/docs/docs/guides/playwright.md @@ -66,7 +66,7 @@ test('should connect wallet to the MetaMask Test Dapp', async ({ context, page, You can notice the unusual `extensionId` fixture used here. This fixture is amongst a few others that are provided by Synpress. You can learn more about them in the [Built-in Fixtures](./fixtures) section. -To access the MetaMask API, you must create an instance of the `MetaMask` class as shown above. To learn more about the constructor and all the methods this class provides, see [its API reference](/api/classes/MetaMask). +To access the MetaMask API, you must create an instance of the `MetaMask` class as shown above. To learn more about the constructor and all the methods this class provides, see [its API reference](/api/playwright/classes/MetaMask.md). ::: tip diff --git a/docs/docs/introduction.md b/docs/docs/introduction.md index c329539e4..097856e13 100644 --- a/docs/docs/introduction.md +++ b/docs/docs/introduction.md @@ -34,7 +34,7 @@ Synpress provides a simple yet powerful and fully typed API that is easy to use. Our documentation is comprehensive, and we've made sure it covers everything you need to know about Synpress. -Synpress can be used with ~~two~~ leading E2E testing frameworks out there, i.e., ~~both~~ [Playwright](https://playwright.dev/) ~~and [Cypress](https://www.cypress.io/)~~, with support for all of ~~their~~ its features. +Synpress can be used with ~~two~~ leading E2E testing frameworks out there, i.e., both [Playwright](https://playwright.dev/) and [Cypress](https://www.cypress.io/), with support for all of their its features. ## Stability diff --git a/docs/docs/migration-guide.md b/docs/docs/migration-guide.md index 9d00d0c25..ef6efaf13 100644 --- a/docs/docs/migration-guide.md +++ b/docs/docs/migration-guide.md @@ -1,7 +1,240 @@ -# Migration Guide +# Migration Guide: Synpress v3 to v4 -If you're coming from earlier versions of Synpress, you're both in and out of luck. Synpress v4 is a complete rewrite of the library, so it's not backward compatible with previous versions. However, the API is much more straightforward and intuitive, so you should be able to migrate your tests easily. +Synpress v4 introduces significant improvements in functionality, performance, and API design. This guide will help you seamlessly transition your tests from v3 to v4. -::: info -Once the API of the alpha release is stable, we'll publish a migration guide that should help you migrate your tests from v3 to v4. + +::: warning +This migration guide is particularly for Cypress users. If you're using Playwright with Synpress, please refer to the [Playwright-specific documentation](/docs/setupPlaywright). ::: + + + +## Key Changes Overview + +1. **Installation**: Unchanged +2. **Configuration**: New MetaMask-specific setup +3. **Support Files**: More granular command imports +4. **TypeScript Configuration**: Written in TypeScript to improve compatibility and readability +5. **Test Structure**: Simplified with automatic page visits +6. **MetaMask Interactions**: Renamed and enhanced commands +7. **Test Execution**: Standardized Cypress command +8. **Configuration Options**: Expanded for greater flexibility + +## Key Changes + +1. **Installation**: + + ```bash + npm install @synthetixio/synpress@latest + ``` + + The installation process remains the same in v4. + +2. **Configuration**: + + - Update your `cypress.config.ts`: + + ```typescript + import { configureSynpressForMetaMask } from "@synthetixio/synpress/cypress"; + import { defineConfig } from "cypress"; + + export default defineConfig({ + chromeWebSecurity: false, + e2e: { + baseUrl: "http://localhost:9999", + specPattern: "test/cypress/**/*.cy.{js,jsx,ts,tsx}", + supportFile: "src/cypress/support/e2e.{js,jsx,ts,tsx}", + testIsolation: false, + async setupNodeEvents(on, config) { + return configureSynpressForMetaMask(on, config); + }, + }, + }); + ``` + + The v4 configuration uses `configureSynpressForMetaMask` instead of the previous `cypressGrepPlugin`. This new function handles MetaMask-specific setup automatically. + +3. **Support Files**: + + - Create or update `src/cypress/support/e2e.ts`: + + ```typescript + import { synpressCommandsForMetaMask } from "@synthetixio/synpress/cypress/support"; + + Cypress.on("uncaught:exception", () => { + // failing the test + return false; + }); + + synpressCommandsForMetaMask(); + + before(() => { + cy.visit("/"); + }); + ``` + + In v4, you import `synpressCommandsForMetaMask` instead of the previous global import. This allows for more granular control over which commands are available in your tests. + +4. **TypeScript Configuration**: + + - Update your `tsconfig.json`: + + ```json + { + "compilerOptions": { + "types": ["cypress"], + "esModuleInterop": true + }, + "include": ["cypress.config.ts", "test", "src"], + "files": ["environment.d.ts"] + } + ``` + + The v4 TypeScript configuration is more streamlined, focusing on Cypress types and ensuring compatibility with ES modules. + +5. **Test Structure**: + + - v4 no longer requires explicit `cy.visit()` calls in tests or `before()` hooks + - The initial page visit is now handled by the configuration step + + This change simplifies test structure and further improves performance by eliminating redundant page loads. + + Example: + + ```typescript + describe("My Test Suite", () => { + it("Test 1", () => { + // Test logic here + }); + + it("Test 2", () => { + // Test logic here + }); + }); + ``` + + This approach is correct and aligns with Cypress best practices for optimizing test performance. + +6. **MetaMask Interactions**: + + - Many MetaMask-specific commands have been renamed or modified for clarity and ease of use + - Examples of API changes: + ```typescript + // v3 // v4 + cy.acceptMetamaskAccess() -> cy.connectToDapp() + cy.confirmMetamaskTransaction() -> cy.confirmTransaction() + cy.rejectMetamaskTransaction() -> cy.rejectTransaction() + cy.switchMetamaskNetwork() -> cy.switchNetwork() + cy.addMetamaskNetwork() -> cy.addNetwork() + cy.importMetamaskAccount() -> cy.importWallet() + cy.createMetamaskAccount() -> // No direct equivalent in v4 + cy.getMetamaskWalletAddress() -> cy.getAccount() + cy.switchMetamaskAccount() -> cy.switchAccount() + cy.getMetamaskBalance() -> // No direct equivalent in v4 + ``` + + Note: This list may not be exhaustive. It's recommended to check the latest Synpress v4 documentation for a complete list of API changes and new commands that may have been introduced. + +7. **Test Execution**: + + - v3: Multiple commands to run tests + - v4: Simplified to use standard Cypress command: + ``` + npx cypress run --browser chrome --headed + ``` + +8. **Configuration**: + - v4: May introduce new configuration options for Synpress and MetaMask setup + +## Detailed API Changes + +Here's a more detailed breakdown of the API changes between Synpress v3 and v4: + +1. **Connecting to dApps**: + - v3: `cy.acceptMetamaskAccess()` + - v4: `cy.connectToDapp()` + + This change simplifies the command name while maintaining its core functionality. + +2. **Transaction Handling**: + - v3: + - `cy.confirmMetamaskTransaction()` + - `cy.rejectMetamaskTransaction()` + - v4: + - `cy.confirmTransaction()` + - `cy.rejectTransaction()` + + The new commands are more concise and remove the "Metamask" prefix for clarity. + +3. **Network Management**: + - v3: + - `cy.switchMetamaskNetwork()` + - `cy.addMetamaskNetwork()` + - v4: + - `cy.switchNetwork()` + - `cy.addNetwork()` + + These changes streamline network-related commands by removing the "Metamask" prefix. + +4. **Wallet Management**: + - v3: + - `cy.importMetamaskAccount()` + - `cy.createMetamaskAccount()` + - `cy.switchMetamaskAccount()` + - v4: + - `cy.importWallet()` + - No direct equivalent for `createMetamaskAccount()` + - `cy.switchAccount()` + + The v4 API simplifies wallet management commands and removes the ability to create new accounts directly. + +5. **Account Information**: + - v3: + - `cy.getMetamaskWalletAddress()` + - `cy.getMetamaskBalance()` + - v4: + - `cy.getAccount()` + - No direct equivalent for `getMetamaskBalance()` + + The v4 API simplifies getting account information but removes the direct balance checking capability. + +6. **New Commands in v4**: + - `cy.emptyAnvilNode()`: Empties the Anvil node + - `cy.addNetwork()`: Adds a new network to MetaMask + - `cy.approveNewNetwork()`: Approves a new network in MetaMask + - `cy.approveSwitchNetwork()`: Approves switching to a different network in MetaMask + - `cy.rejectNewNetwork()`: Rejects a new network in MetaMask + - `cy.rejectSwitchNetwork()`: Rejects switching to a different network in MetaMask + - `cy.deployToken()`: Deploys a new token contract + - `cy.addNewToken()`: Adds a new token to MetaMask + - `cy.approveTokenPermission()`: Approves token spending permission in MetaMask + - `cy.rejectTokenPermission()`: Rejects token spending permission in MetaMask + - `cy.toggleShowTestNetworks()`: Toggles the display of test networks in MetaMask + - `cy.toggleDismissSecretRecoveryPhraseReminder()`: Toggles the dismissal of the secret recovery phrase reminder + - `cy.providePublicEncryptionKey()`: Provides a public encryption key + - `cy.decrypt()`: Decrypts encrypted data + - `cy.confirmSignature()`: Confirms a signature request in MetaMask + - `cy.rejectSignature()`: Rejects a signature request in MetaMask + - `cy.confirmTransactionAndWaitForMining()`: Confirms a transaction and waits for it to be mined + - `cy.openTransactionDetails()`: Opens transaction details in MetaMask + - `cy.closeTransactionDetails()`: Closes transaction details in MetaMask + - `cy.goBackToHomePage()`: Returns to the MetaMask home page + - `cy.openSettings()`: Opens MetaMask settings + - `cy.openSidebarMenu()`: Opens a specific sidebar menu in MetaMask settings + +Note: The `setupMetamask()` function is not present in the provided file. Some commands like `connectToDapp()`, `disconnectFromDapp()`, `switchNetwork()`, `lock()`, `unlock()`, `confirmTransaction()`, and `rejectTransaction()` were present in Synpress v3 and have been retained or slightly modified in v4. This list focuses on the new or significantly changed commands in v4. + +7. **Advanced Transaction Handling in v4**: + - `cy.confirmTransaction()` now supports advanced options: + ```typescript + cy.confirmTransaction({ + gasSetting: 'low' | 'medium' | 'high' | { + maxBaseFee: number, + priorityFee: number, + gasLimit?: number + } + }) + ``` + This allows for more granular control over gas settings during transaction confirmation. + +When migrating from v3 to v4, carefully review your existing tests and update the commands according to these changes. Also, consult the latest Synpress v4 documentation for any additional new features or commands that may have been introduced. diff --git a/docs/docs/setupCypress.md b/docs/docs/setupCypress.md new file mode 100644 index 000000000..55866be59 --- /dev/null +++ b/docs/docs/setupCypress.md @@ -0,0 +1,122 @@ +# Quick Setup: Cypress with Synpress + +This guide provides a streamlined setup process for integrating Cypress with Synpress to automate tests for Web3 dapps. While this covers the basic configuration, Synpress offers a wide range of advanced features for comprehensive testing. + +## Prerequisites + +- Node.js v18+ +- Basic knowledge of Cypress and TypeScript + +## Installation + +Install Cypress and Synpress in your project: + +```bash +npm install --save-dev cypress @synthetixio/synpress@latest +``` + +## Setup + +1. Create a Cypress configuration file (`cypress.config.ts`) in your project root: + + ```typescript + import { configureSynpressForMetaMask } from "@synthetixio/synpress/cypress"; + import { defineConfig } from "cypress"; + + export default defineConfig({ + chromeWebSecurity: false, + e2e: { + baseUrl: "http://localhost:9999", + specPattern: "test/cypress/**/*.cy.{js,jsx,ts,tsx}", + supportFile: "src/cypress/support/e2e.{js,jsx,ts,tsx}", + testIsolation: false, + async setupNodeEvents(on, config) { + return configureSynpressForMetaMask(on, config); + }, + }, + }); + ``` + +2. Create a support file (`src/cypress/support/e2e.ts`) and import Synpress commands: + + ```typescript + import { synpressCommandsForMetaMask } from "@synthetixio/synpress/cypress/support"; + + Cypress.on("uncaught:exception", () => { + // failing the test + return false; + }); + + synpressCommandsForMetaMask(); + + before(() => { + cy.visit("/"); + }); + ``` + +3. Update your `tsconfig.json` to include Cypress types: + + ```json + { + "compilerOptions": { + "types": ["cypress"], + "esModuleInterop": true + }, + "include": ["cypress.config.ts", "test", "src"], + "files": ["environment.d.ts"] + } + ``` + +## Writing Tests + +Here's an optimized example of how to write tests using Cypress with Synpress integration: + +1. Create a new test file (e.g., `test/cypress/e2e/metamask.cy.ts`): + + ```typescript + describe('MetaMask', () => { + it('should connect wallet and display account information', () => { + // Click the connect button to initiate wallet connection + cy.get('#connectButton').click() + + // Use Synpress command to connect MetaMask to the dApp + cy.connectToDapp() + + // Verify that the connected account address is displayed correctly + cy.get('#accounts').should( + 'have.text', + '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266' + ) + + // Additional test steps can be added here, such as: + // - Sending transactions + // - Interacting with smart contracts + // - Testing dapp-specific functionality + }) + ``` + +## Running Tests + +To run your Cypress tests with Synpress: + +1. Ensure your local development server is running (if testing against a local app). + +2. Run the tests using the following command: + + ```bash + npx cypress run --browser chrome --headed + ``` + +This will execute your tests using Cypress with Synpress integration in headless mode. + +## Next Steps + +- Dive deeper into Synpress capabilities: + + - Study the [Synpress API documentation](/api/) for comprehensive command and utility details. + - Explore advanced features like custom network management, gas fee optimization, and event listeners. + +- Enhance your test suite: + - Implement complex scenarios such as token transfers, smart contract interactions, and multi-step dApp workflows. + - Simulate various network conditions to ensure robust dApp performance. + - Utilize Synpress's built-in commands for MetaMask interactions and blockchain operations. diff --git a/docs/docs/setupPlaywright.md b/docs/docs/setupPlaywright.md new file mode 100644 index 000000000..0bf7f6cf4 --- /dev/null +++ b/docs/docs/setupPlaywright.md @@ -0,0 +1,138 @@ +# Quick Setup: Playwright with Synpress + +This guide provides a quick setup process for Playwright with Synpress to automate tests for Web3 dapps. Note that this is a basic configuration, and Synpress offers many more advanced functions and features for comprehensive testing. + +## Prerequisites + +- Node.js v18+ +- Playwright and TypeScript knowledge + +## Installation + +1. Install Playwright and its dependencies: + + ```bash + npm init playwright@latest + ``` + + Follow the prompts to complete the installation. + +2. Install Synpress as a dev dependency: + + ```bash + npm install --save-dev @synthetixio/synpress + ``` + +## Setup + +1. Create or update your Playwright configuration file (e.g., `playwright.config.ts`): + + ```typescript + // Import necessary Playwright and Synpress modules + import { defineConfig, devices } from '@playwright/test'; + import { synpressFixtures } from '@synthetixio/synpress/synpress'; + + // Define Playwright configuration + export default defineConfig({ + testDir: './tests', + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : undefined, + reporter: 'html', + use: { + // Set base URL for tests + baseURL: 'http://localhost:3000', + trace: 'on-first-retry', + }, + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + ], + // Additional Synpress-specific configuration can be added here + }); + ``` + +2. Create a `BasicSetup` file (e.g., `wallet-setup/basic.setup.ts`): + + ```typescript + import { defineWalletSetup } from '@synthetixio/synpress-cache' + import { MetaMask } from '@synthetixio/synpress' + + // Define a test seed phrase and password + export const SEED_PHRASE = 'test test test test test test test test test test test junk' + export const PASSWORD = 'Tester@1234' + + // Define the basic wallet setup + export default defineWalletSetup(PASSWORD, async (context, walletPage) => { + // Create a new MetaMask instance + const metamask = new MetaMask(context, walletPage, PASSWORD) + + // Import the wallet using the seed phrase + await metamask.importWallet(SEED_PHRASE) + + // Additional setup steps can be added here, such as: + // - Adding custom networks + // - Importing tokens + // - Setting up specific account states + }) + ``` + +3. Create a simple test file (e.g., `tests/example.spec.ts`): + + ```typescript + // Import necessary Synpress modules and setup + import { testWithSynpress, MetaMask, unlockForFixture } from '@synthetixio/synpress' + import BasicSetup from '../wallet-setup/basic.setup' + + // Create a test instance with Synpress and BasicSetup + const test = testWithSynpress(BasicSetup, unlockForFixture) + + // Extract expect function from test + const { expect } = test + + // Define a basic test case + test('should connect wallet to the MetaMask Test Dapp', async ({ context, page, extensionId }) => { + // Create a new MetaMask instance + const metamask = new MetaMask(context, page, BasicSetup.walletPassword, extensionId) + + // Navigate to the homepage + await page.goto('/') + + // Click the connect button + await page.locator('#connectButton').click() + + // Connect MetaMask to the dapp + await metamask.connectToDapp() + + // Verify the connected account address + await expect(page.locator('#accounts')).toHaveText('0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266') + + // Additional test steps can be added here, such as: + // - Sending transactions + // - Interacting with smart contracts + // - Testing dapp-specific functionality + }) + ``` + +## Running Tests + +To run your Playwright tests with Synpress: + +1. Start your local development server (if testing against a local app). + +2. Run the tests: + + ```bash + npx playwright test + ``` + +This will execute your tests using Playwright with Synpress integration. + +## Next Steps + +- Check the [API documentation](/api/) for detailed Synpress functionalities. +- Explore example projects in the [Synpress GitHub repository](https://github.com/Synthetixio/synpress/tree/new-dawn/examples). +- Join our [Discord community](https://discord.gg/XhZKSRGtWc) for support and best practices. diff --git a/docs/docs/typescript.md b/docs/docs/typescript.md index 5e716ccc9..560ad000e 100644 --- a/docs/docs/typescript.md +++ b/docs/docs/typescript.md @@ -1,20 +1,14 @@ -# TypeScript +# TypeScript Support in Synpress -## Requirements +## Requirements and Considerations -Synpress has full TypeScript support. It is written in TypeScript and ships with its type definitions. There are a few things to keep in mind: +Synpress offers comprehensive TypeScript support, being built with TypeScript and providing its own type definitions. Here are some key points to consider: -- Types require TypeScript >= 5.0.4. -- While in alpha, the types might change between releases. Locking the `@synthetixio/synpress` to a specific version is recommended. +- **TypeScript Version**: Synpress requires TypeScript version 5.0.4 or higher. +- **Version Stability**: Synpress is now a stable release, with consistent type definitions across versions. However, it's still recommended to specify the version of `@synthetixio/synpress` in your project for better control over updates. -To ensure everything works as expected, make sure to enable the [`strict`](https://www.typescriptlang.org/tsconfig#strict) compiler option in your `tsconfig.json`: +## Configuration + +To ensure optimal functionality and type checking, configure your TypeScript compiler with the `strict` option enabled. Update your `tsconfig.json` as follows: ::: code-group -```json [tsconfig.json] -{ - "compilerOptions": { - "strict": true - } -} -``` -::: diff --git a/docs/tsconfig.json b/docs/tsconfig.json index bb0ba38bc..451ae0894 100644 --- a/docs/tsconfig.json +++ b/docs/tsconfig.json @@ -3,5 +3,11 @@ "compilerOptions": { "rootDir": "." }, - "include": [".vitepress/**/*.ts", "node_modules/@synthetixio/synpress/src/index.ts"] + "include": [ + ".vitepress/**/*.ts", + "node_modules/@synthetixio/synpress/src/index.ts", + "node_modules/@synthetixio/synpress/src/cypress/index.ts", + "node_modules/@synthetixio/synpress/src/cypress/support/index.ts", + "node_modules/@synthetixio/synpress/src/playwright/index.ts" + ] } diff --git a/docs/typedoc.json b/docs/typedoc.json index fdf4d00b9..4bed65f0e 100644 --- a/docs/typedoc.json +++ b/docs/typedoc.json @@ -1,7 +1,12 @@ { "$schema": "https://typedoc.org/schema.json", "out": "./api", - "entryPoints": ["node_modules/@synthetixio/synpress/src/index.ts"], + "entryPoints": [ + "node_modules/@synthetixio/synpress/src/index.ts", + "node_modules/@synthetixio/synpress/src/cypress/index.ts", + "node_modules/@synthetixio/synpress/src/cypress/support/index.ts", + "node_modules/@synthetixio/synpress/src/playwright/index.ts" + ], "plugin": ["typedoc-plugin-markdown", "typedoc-vitepress-theme"], "readme": "none", "hideGenerator": true, diff --git a/examples/ethereum-wallet-mock/tsconfig.json b/examples/ethereum-wallet-mock/tsconfig.json index 4a1fbc3e5..b986ba020 100644 --- a/examples/ethereum-wallet-mock/tsconfig.json +++ b/examples/ethereum-wallet-mock/tsconfig.json @@ -1,13 +1,13 @@ { "compilerOptions": { - "rootDir": "test", + "rootDir": ".", "target": "ES2022", "module": "ES2022", "moduleResolution": "bundler", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, - "skipLibCheck": true, + "skipLibCheck": true, "types": ["cypress"] }, "include": ["cypress.config.ts", "test", "src"], diff --git a/packages/core/src/testWithSynpress.ts b/packages/core/src/testWithSynpress.ts index 498a8a58e..930fb41f3 100644 --- a/packages/core/src/testWithSynpress.ts +++ b/packages/core/src/testWithSynpress.ts @@ -1,8 +1,29 @@ import type { Fixtures, TestType } from '@playwright/test' import { mergeTests, test as base } from '@playwright/test' +/** + * Creates a test environment with Synpress integration. + * + * This function merges the base Playwright test with custom fixtures, allowing for + * seamless integration of Synpress capabilities in Playwright tests. + * + * Synpress is a wrapper around Cypress that adds support for testing + * Web3 and blockchain applications, particularly those involving + * MetaMask interactions. + * + * @param customFixtures - Custom fixtures to be merged with the base test. + * @returns A merged test object that includes both Playwright and Synpress capabilities. + * + * @example + * ```typescript + * const test = testWithSynpress(myCustomFixtures); + * test('My Web3 test', async ({ page, synpress }) => { + * // Test implementation using Playwright and Synpress + * }); + * ``` + */ export default function testWithSynpress( customFixtures: TestType -) { +): TestType { return mergeTests(base, customFixtures) } diff --git a/release/src/cypress/index.ts b/release/src/cypress/index.ts index 82b03a60b..93cf88871 100644 --- a/release/src/cypress/index.ts +++ b/release/src/cypress/index.ts @@ -1,2 +1,6 @@ export { configureSynpress as configureSynpressForEthereumWalletMock } from '@synthetixio/ethereum-wallet-mock/cypress' -export { configureSynpress as configureSynpressForMetaMask } from '@synthetixio/synpress-metamask/cypress' +export { + configureSynpress as configureSynpressForMetaMask, + initMetaMask, + MetaMask +} from '@synthetixio/synpress-metamask/cypress' diff --git a/wallets/ethereum-wallet-mock/src/cypress/support/mockEthereum.ts b/wallets/ethereum-wallet-mock/src/cypress/support/mockEthereum.ts index a396f567b..142fa17c6 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/support/mockEthereum.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/support/mockEthereum.ts @@ -1,4 +1,31 @@ -export default function mockEthereum() { +/** + * Mock Ethereum Environment for Cypress Tests + * + * This module provides a function to set up a mocked Ethereum environment + * for Cypress tests. It utilizes the Web3Mock library to simulate Ethereum + * blockchain interactions and MetaMask wallet behavior. + * + * @remarks + * Key features: + * - Mocks the Ethereum blockchain environment + * - Simulates MetaMask wallet functionality + * - Automatically applied before each test suite + * + * This function is typically called in the Cypress support file or test + * setup to ensure all tests run in a controlled, mocked Ethereum environment. + * It allows for consistent and predictable testing of Ethereum-based + * applications without the need for a real blockchain or wallet. + * + * @example + * ```typescript + * // In your Cypress support file + * import { mockEthereum } from '@synthetixio/synpress'; + * + * mockEthereum(); + * ``` + */ + +export default function mockEthereum(): void { before(() => { cy.visit('/', { onBeforeLoad: (window) => { diff --git a/wallets/ethereum-wallet-mock/src/cypress/support/synpressCommands.ts b/wallets/ethereum-wallet-mock/src/cypress/support/synpressCommands.ts index 4d03cc4b9..f74cc06d7 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/support/synpressCommands.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/support/synpressCommands.ts @@ -53,49 +53,117 @@ declare global { } } -export default function synpressCommands() { - Cypress.Commands.add('importWallet', (seedPhrase) => { +/** + * Synpress Commands for Ethereum Wallet Mock + * + * This module extends Cypress with custom commands for interacting with a mocked Ethereum wallet. + * It provides functionalities for wallet management, account operations, and network interactions. + * + * Key features include: + * - Wallet: Import wallet from seed phrase or private key + * - Account: Add new accounts, get all accounts, switch between accounts + * - Network: Add new networks, switch between networks + * - dApp Interaction: Connect to dApps + * + * These commands enhance the testing capabilities for Ethereum-based applications, + * allowing for comprehensive end-to-end testing of dApps using a mocked Ethereum wallet. + * This approach provides a controlled environment for testing without the need for a real wallet, + * making tests more reliable and easier to set up. + * + * @module SynpressCommandsForEthereumWalletMock + */ + +/** + * Initializes Synpress commands for the Ethereum Wallet Mock. + * + * This function adds custom Cypress commands for interacting with a mocked Ethereum wallet. + * These commands include wallet import, account management, network operations, and dApp connections. + * + * @example + * ```typescript + * import { synpressCommandsForEthereumWalletMock } from '@synthetixio/synpress'; + * + * synpressCommandsForEthereumWalletMock(); + * ``` + */ +export default function synpressCommandsForEthereumWalletMock(): void { + /** + * Imports a wallet using a seed phrase. + * @param seedPhrase - The seed phrase to import the wallet. + */ + Cypress.Commands.add('importWallet', (seedPhrase: string) => { const ethereumWalletMock = getEthereumWalletMock() ethereumWalletMock.importWallet(seedPhrase) }) - Cypress.Commands.add('importWalletFromPrivateKey', (privateKey) => { + /** + * Imports a wallet using a private key. + * @param privateKey - The private key to import the wallet. + */ + Cypress.Commands.add('importWalletFromPrivateKey', (privateKey: `0x${string}`) => { const ethereumWalletMock = getEthereumWalletMock() ethereumWalletMock.importWalletFromPrivateKey(privateKey) }) + /** + * Adds a new account to the wallet. + * @returns A promise that resolves when the account is added. + */ Cypress.Commands.add('addNewAccount', () => { const ethereumWalletMock = getEthereumWalletMock() return ethereumWalletMock.addNewAccount() }) + /** + * Retrieves all accounts in the wallet. + * @returns A promise that resolves with an array of account addresses. + */ Cypress.Commands.add('getAllAccounts', () => { const ethereumWalletMock = getEthereumWalletMock() - return ethereumWalletMock.getAllAccounts() }) + /** + * Gets the current account address. + * @returns A promise that resolves with the current account address. + */ Cypress.Commands.add('getAccountAddress', () => { const ethereumWalletMock = getEthereumWalletMock() return ethereumWalletMock.getAccountAddress() }) - Cypress.Commands.add('switchAccount', (accountAddress) => { + /** + * Switches to a different account. + * @param accountAddress - The address of the account to switch to. + */ + Cypress.Commands.add('switchAccount', (accountAddress: string) => { const ethereumWalletMock = getEthereumWalletMock() ethereumWalletMock.switchAccount(accountAddress) }) - Cypress.Commands.add('addNetwork', (network) => { + /** + * Adds a new network to the wallet. + * @param network - The network configuration to add. + */ + Cypress.Commands.add('addNetwork', (network: Network) => { const ethereumWalletMock = getEthereumWalletMock() ethereumWalletMock.addNetwork(network) }) - Cypress.Commands.add('switchNetwork', (networkName) => { + /** + * Switches to a different network. + * @param networkName - The name of the network to switch to. + */ + Cypress.Commands.add('switchNetwork', (networkName: string) => { const ethereumWalletMock = getEthereumWalletMock() ethereumWalletMock.switchNetwork(networkName) }) - Cypress.Commands.add('connectToDapp', (wallet) => { + /** + * Connects the wallet to a dApp. + * @param wallet - Optional wallet configuration to use for the connection. + */ + Cypress.Commands.add('connectToDapp', (wallet?: WalletMock) => { const ethereumWalletMock = getEthereumWalletMock() ethereumWalletMock.connectToDapp(wallet) }) diff --git a/wallets/ethereum-wallet-mock/src/cypress/utils/configureSynpress.ts b/wallets/ethereum-wallet-mock/src/cypress/utils/configureSynpress.ts index 1a473c0d1..d8ac1a3cb 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/utils/configureSynpress.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/utils/configureSynpress.ts @@ -4,6 +4,24 @@ import { initEthereumWalletMock } from './initEthereumWalletMock' let port: number +/** + * Configures Synpress for use with the Ethereum Wallet Mock. + * + * This function sets up the necessary configurations and hooks for running + * Cypress tests with the Ethereum Wallet Mock. It performs the following tasks: + * + * 1. Filters the available browsers to ensure only Chrome is used. + * 2. Sets up a 'before:browser:launch' hook to enable debug mode and establish + * a Playwright connection. + * 3. Sets up a 'before:spec' hook to initialize the Ethereum Wallet Mock before + * each test spec runs. + * + * @param on - Cypress plugin event handler + * @param config - Cypress plugin configuration options + * @returns Modified Cypress configuration + * @throws Error If no Chrome browser is found in the configuration + */ + export default function configureSynpress(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) { const browsers = config.browsers.filter((b) => b.name === 'chrome') if (browsers.length === 0) { diff --git a/wallets/ethereum-wallet-mock/src/playwright/EthereumWalletMock.ts b/wallets/ethereum-wallet-mock/src/playwright/EthereumWalletMock.ts index d0bb3b047..8f058b42e 100644 --- a/wallets/ethereum-wallet-mock/src/playwright/EthereumWalletMock.ts +++ b/wallets/ethereum-wallet-mock/src/playwright/EthereumWalletMock.ts @@ -4,11 +4,25 @@ import { ACCOUNT_MOCK, BLOCKCHAIN } from '../constants' import { EthereumWalletMockAbstract } from '../type/EthereumWalletMockAbstract' import type { Network } from '../type/Network' import type { WalletMock } from '../type/WalletMock' -import { OPTIMISM_NETWORK_ID } from './utils' - +import { DEFAULT_NETWORK_ID } from './utils' + +/** + * Mock implementation of an Ethereum wallet for testing purposes. + * Simulates wallet behavior in a controlled environment, allowing for consistent + * and reproducible tests without relying on actual blockchain interactions. + * + * @class + * @extends {EthereumWalletMockAbstract} + */ export default class EthereumWalletMock extends EthereumWalletMockAbstract { + /** The Playwright Page object to interact with. */ page: Page + /** + * Creates an instance of EthereumWalletMock. + * @param page - The Playwright Page object to interact with. + * @param wallet - The type of wallet to mock. + */ constructor(page: Page, wallet: WalletMock = 'metamask') { super(wallet) this.page = page @@ -17,10 +31,10 @@ export default class EthereumWalletMock extends EthereumWalletMockAbstract { /** * Imports a wallet using the given seed phrase. - * * @param seedPhrase - The seed phrase to import. + * @returns A promise that resolves when the wallet is imported. */ - importWallet(seedPhrase: string) { + importWallet(seedPhrase: string): Promise { this.seedPhrase = seedPhrase return this.page.evaluate( @@ -47,7 +61,8 @@ export default class EthereumWalletMock extends EthereumWalletMockAbstract { } /** - * Retrieves the current account address. + * Retrieves all account addresses. + * @returns A promise that resolves to an array of account addresses. */ async getAllAccounts(): Promise<`0x${string}`[] | undefined> { return this.page.evaluate(() => { @@ -56,9 +71,10 @@ export default class EthereumWalletMock extends EthereumWalletMockAbstract { } /** - * Adds a new account. This account is based on the initially imported seed phrase. + * Adds a new account based on the initially imported seed phrase. + * @returns A promise that resolves when the new account is added. */ - async addNewAccount() { + async addNewAccount(): Promise { const accounts = await this.getAllAccounts() const newAccount = mnemonicToAccount(this.seedPhrase || '', { @@ -81,10 +97,10 @@ export default class EthereumWalletMock extends EthereumWalletMockAbstract { /** * Imports a wallet using the given private key. - * * @param privateKey - The private key to import. + * @returns A promise that resolves when the wallet is imported. */ - async importWalletFromPrivateKey(privateKey: `0x${string}`) { + async importWalletFromPrivateKey(privateKey: `0x${string}`): Promise { const newAccount = privateKeyToAccount(privateKey) return this.page.evaluate( @@ -102,11 +118,11 @@ export default class EthereumWalletMock extends EthereumWalletMockAbstract { } /** - * Switches to the account with the given name. - * - * @param accountAddress - The name of the account to switch to. + * Switches to the account with the given address. + * @param accountAddress - The address of the account to switch to. + * @returns A promise that resolves when the account switch is complete. */ - async switchAccount(accountAddress: string) { + async switchAccount(accountAddress: string): Promise { return this.page.evaluate( ([blockchain, wallet, accountAddress]) => { return Web3Mock.mock({ @@ -123,10 +139,10 @@ export default class EthereumWalletMock extends EthereumWalletMockAbstract { /** * Adds a new network. - * * @param network - The network object to use for adding the new network. + * @returns A promise that resolves when the network is added. */ - async addNetwork(network: Network) { + async addNetwork(network: Network): Promise { const networkInfo = { chainId: network.chainId, chainName: network.name, @@ -151,6 +167,7 @@ export default class EthereumWalletMock extends EthereumWalletMockAbstract { /** * Retrieves the current account address. + * @returns A promise that resolves to the current account address. */ async getAccountAddress(): Promise<`0x${string}` | undefined> { return (await this.getAllAccounts())?.[0] @@ -158,10 +175,10 @@ export default class EthereumWalletMock extends EthereumWalletMockAbstract { /** * Switches to the network with the given name. - * * @param networkName - The name of the network to switch to. + * @returns A promise that resolves when the network switch is complete. */ - async switchNetwork(networkName: string) { + async switchNetwork(networkName: string): Promise { return this.page.evaluate( ([blockchain, wallet, networkName, chainId]) => { Web3Mock.mock({ @@ -178,16 +195,16 @@ export default class EthereumWalletMock extends EthereumWalletMockAbstract { params: [{ chainId }] }) }, - [BLOCKCHAIN, this.wallet, networkName, OPTIMISM_NETWORK_ID] + [BLOCKCHAIN, this.wallet, networkName, DEFAULT_NETWORK_ID] ) } /** * Connects wallet to the dapp. - * * @param wallet - The wallet to connect to the dapp. + * @returns A promise that resolves when the wallet is connected to the dapp. */ - connectToDapp(wallet: WalletMock = 'metamask') { + connectToDapp(wallet: WalletMock = 'metamask'): Promise { this.wallet = wallet return this.page.evaluate( diff --git a/wallets/ethereum-wallet-mock/src/playwright/constants.ts b/wallets/ethereum-wallet-mock/src/playwright/constants.ts index cefae7d5d..efd91d8f8 100644 --- a/wallets/ethereum-wallet-mock/src/playwright/constants.ts +++ b/wallets/ethereum-wallet-mock/src/playwright/constants.ts @@ -1,9 +1,18 @@ import { createRequire } from 'node:module' const require = createRequire(import.meta.url) +/** + * The private key used for testing purposes. + * @constant + * @type {string} + */ export const PRIVATE_KEY = 'ea084c575a01e2bbefcca3db101eaeab1d8af15554640a510c73692db24d0a6a' -export const OPTIMISM_NETWORK_ID = '0xa' +export const DEFAULT_NETWORK_ID = '0xa' -// Relative path to the web3-mock bundle +/** + * Relative path to the web3-mock bundle. + * @constant + * @type {string} + */ export const web3MockPath = require.resolve('@depay/web3-mock/dist/umd/index.bundle.js') diff --git a/wallets/metamask/src/cypress/MetaMask.ts b/wallets/metamask/src/cypress/MetaMask.ts index 54f4412fd..a4b33942d 100644 --- a/wallets/metamask/src/cypress/MetaMask.ts +++ b/wallets/metamask/src/cypress/MetaMask.ts @@ -1,5 +1,5 @@ import { type BrowserContext, type Page, expect } from '@playwright/test' -import { type CreateAnvilOptions, type Pool, createPool } from '@viem/anvil' +import { type Anvil, type CreateAnvilOptions, type Pool, createPool } from '@viem/anvil' import { MetaMask as MetaMaskPlaywright } from '../playwright/MetaMask' import { waitFor } from '../playwright/utils/waitFor' import HomePageSelectors from '../selectors/pages/HomePage' @@ -12,100 +12,155 @@ import getPlaywrightMetamask from './getPlaywrightMetamask' let pool: Pool +/** + * MetaMask class for interacting with the MetaMask extension in Cypress tests. + */ export default class MetaMask { + /** The MetaMask instance for Playwright */ readonly metamaskPlaywright: MetaMaskPlaywright + /** The MetaMask extension page */ readonly metamaskExtensionPage: Page + /** + * Creates an instance of MetaMask. + * @param context - The browser context + * @param metamaskExtensionPage - The MetaMask extension page + * @param metamaskExtensionId - The MetaMask extension ID + */ constructor(context: BrowserContext, metamaskExtensionPage: Page, metamaskExtensionId: string) { this.metamaskPlaywright = getPlaywrightMetamask(context, metamaskExtensionPage, metamaskExtensionId) this.metamaskExtensionPage = metamaskExtensionPage } - async getAccount() { + /** + * Gets the current account name. + * @returns The current account name + */ + async getAccount(): Promise { return await this.metamaskExtensionPage .locator(this.metamaskPlaywright.homePage.selectors.accountMenu.accountButton) .innerText() } - async getAccountAddress() { + /** + * Gets the current account address. + * @returns The current account address + */ + async getAccountAddress(): Promise { return await this.metamaskPlaywright.getAccountAddress() } - async getNetwork() { + /** + * Gets the current network name. + * @returns The current network name + */ + async getNetwork(): Promise { return await this.metamaskExtensionPage .locator(this.metamaskPlaywright.homePage.selectors.currentNetwork) .innerText() } - async connectToDapp(accounts?: string[]) { + /** + * Connects MetaMask to a dApp. + * @param accounts - Optional array of account addresses to connect + * @returns True if the connection was successful + */ + async connectToDapp(accounts?: string[]): Promise { await this.metamaskPlaywright.connectToDapp(accounts) - return true } - async importWallet(seedPhrase: string) { + /** + * Imports a wallet using a seed phrase. + * @param seedPhrase - The seed phrase to import + * @returns True if the import was successful + */ + async importWallet(seedPhrase: string): Promise { await this.metamaskPlaywright.importWallet(seedPhrase) - return true } - async importWalletFromPrivateKey(privateKey: string) { + /** + * Imports a wallet using a private key. + * @param privateKey - The private key to import + * @returns True if the import was successful + */ + async importWalletFromPrivateKey(privateKey: string): Promise { await this.metamaskPlaywright.importWalletFromPrivateKey(privateKey) - return true } - async addNewAccount(accountName: string) { + /** + * Adds a new account with the given name. + * @param accountName - The name for the new account + * @returns True if the account was added successfully + */ + async addNewAccount(accountName: string): Promise { await this.metamaskPlaywright.addNewAccount(accountName) - await expect( this.metamaskExtensionPage.locator(this.metamaskPlaywright.homePage.selectors.accountMenu.accountButton) ).toHaveText(accountName) - return true } - async switchAccount(accountName: string) { + /** + * Switches to the account with the given name. + * @param accountName - The name of the account to switch to + * @returns True if the switch was successful + */ + async switchAccount(accountName: string): Promise { await this.metamaskPlaywright.switchAccount(accountName) - await expect( this.metamaskExtensionPage.locator(this.metamaskPlaywright.homePage.selectors.accountMenu.accountButton) ).toHaveText(accountName) - return true } + /** + * Renames an account. + * @param options - Object containing the current and new account names + * @param options.currentAccountName - The current name of the account + * @param options.newAccountName - The new name for the account + * @returns True if the rename was successful + */ async renameAccount({ currentAccountName, newAccountName }: { currentAccountName: string newAccountName: string - }) { + }): Promise { await this.metamaskPlaywright.renameAccount(currentAccountName, newAccountName) - await this.metamaskExtensionPage.locator(HomePageSelectors.threeDotsMenu.accountDetailsCloseButton).click() - await expect( this.metamaskExtensionPage.locator(this.metamaskPlaywright.homePage.selectors.accountMenu.accountButton) ).toHaveText(newAccountName) - return true } - async resetAccount() { + /** + * Resets the current account. + * @returns True if the reset was successful + */ + async resetAccount(): Promise { await this.metamaskPlaywright.resetAccount() - return true } + /** + * Switches to the specified network. + * @param options - Object containing the network name and testnet flag + * @param options.networkName - The name of the network to switch to + * @param options.isTestnet - Whether the network is a testnet (default: false) + * @returns True if the switch was successful, false otherwise + */ async switchNetwork({ networkName, isTestnet = false }: { networkName: string isTestnet?: boolean - }) { + }): Promise { return await this.metamaskPlaywright .switchNetwork(networkName, isTestnet) .then(() => { @@ -116,32 +171,44 @@ export default class MetaMask { }) } - async createAnvilNode(options?: CreateAnvilOptions) { + /** + * Creates an Anvil node for testing. + * @param options - Optional Anvil node creation options + * @returns Object containing the Anvil instance, RPC URL, and chain ID + */ + async createAnvilNode(options?: CreateAnvilOptions): Promise<{ anvil: Anvil; rpcUrl: string; chainId: number }> { pool = createPool() - const nodeId = Array.from(pool.instances()).length const anvil = await pool.start(nodeId, options) - const rpcUrl = `http://${anvil.host}:${anvil.port}` - const DEFAULT_ANVIL_CHAIN_ID = 31337 const chainId = options?.chainId ?? DEFAULT_ANVIL_CHAIN_ID - return { anvil, rpcUrl, chainId } } - async emptyAnvilNode() { + /** + * Empties the Anvil node pool. + * @returns True if the operation was successful + */ + async emptyAnvilNode(): Promise { await pool.empty() return true } + /** + * Connects to an Anvil node. + * @param options - Object containing the RPC URL and chain ID + * @param options.rpcUrl - The RPC URL of the Anvil node + * @param options.chainId - The chain ID of the Anvil node + * @returns True if the connection was successful, false otherwise + */ async connectToAnvil({ rpcUrl, chainId }: { rpcUrl: string chainId: number - }) { + }): Promise { try { await this.metamaskPlaywright.addNetwork({ name: 'Anvil', @@ -150,7 +217,6 @@ export default class MetaMask { symbol: 'ETH', blockExplorerUrl: 'https://etherscan.io/' }) - await this.metamaskPlaywright.switchNetwork('Anvil') return true } catch (e) { @@ -159,47 +225,58 @@ export default class MetaMask { } } - async addNetwork(network: Network) { + /** + * Adds a new network to MetaMask. + * @param network - The network configuration to add + * @returns True if the network was added successfully + */ + async addNetwork(network: Network): Promise { await this.metamaskPlaywright.addNetwork(network) - await waitFor( () => this.metamaskExtensionPage.locator(HomePageSelectors.networkAddedPopover.switchToNetworkButton).isVisible(), 3_000, false ) - await this.metamaskExtensionPage.locator(HomePageSelectors.networkAddedPopover.switchToNetworkButton).click() - return true } - // Token - - async deployToken() { + /** + * Deploys a token. + * @returns True if the token was deployed successfully + */ + async deployToken(): Promise { await waitFor( () => this.metamaskExtensionPage.locator(TransactionPage.nftApproveAllConfirmationPopup.approveButton).isVisible(), 3_000, false ) - await this.metamaskPlaywright.confirmTransaction() - return true } - async addNewToken() { + /** + * Adds a new token to MetaMask. + * @returns True if the token was added successfully + */ + async addNewToken(): Promise { await this.metamaskPlaywright.addNewToken() - await expect(this.metamaskExtensionPage.locator(Selectors.portfolio.singleToken).nth(1)).toContainText('TST') - return true } + /** + * Approves token permission. + * @param options - Optional settings for token approval + * @param options.spendLimit - The spend limit for the token (number or 'max') + * @param options.gasSetting - Gas settings for the transaction + * @returns True if the permission was approved, false otherwise + */ async approveTokenPermission(options?: { spendLimit?: number | 'max' gasSetting?: GasSettings - }) { + }): Promise { return await this.metamaskPlaywright .approveTokenPermission(options) .then(() => { @@ -210,59 +287,78 @@ export default class MetaMask { }) } - async rejectTokenPermission() { + /** + * Rejects token permission. + * @returns True if the permission was rejected successfully + */ + async rejectTokenPermission(): Promise { await this.metamaskPlaywright.rejectTokenPermission() - return true } - // Network - - async approveNewNetwork() { + /** + * Approves adding a new network. + * @returns True if the new network was approved successfully + */ + async approveNewNetwork(): Promise { await this.metamaskPlaywright.approveNewNetwork() - return true } - async approveSwitchNetwork() { + /** + * Approves switching to a new network. + * @returns True if the network switch was approved successfully + */ + async approveSwitchNetwork(): Promise { await this.metamaskPlaywright.approveSwitchNetwork() - return true } - async rejectNewNetwork() { + /** + * Rejects adding a new network. + * @returns True if the new network was rejected successfully + */ + async rejectNewNetwork(): Promise { await this.metamaskPlaywright.rejectNewNetwork() - return true } - async rejectSwitchNetwork() { + /** + * Rejects switching to a new network. + * @returns True if the network switch was rejected successfully + */ + async rejectSwitchNetwork(): Promise { await this.metamaskPlaywright.rejectSwitchNetwork() - return true } - // Lock/Unlock - - async lock() { + /** + * Locks the MetaMask wallet. + * @returns True if the wallet was locked successfully + */ + async lock(): Promise { await this.metamaskPlaywright.lock() await expect( this.metamaskExtensionPage.locator(this.metamaskPlaywright.lockPage.selectors.submitButton) ).toBeVisible() - return true } - async unlock() { + /** + * Unlocks the MetaMask wallet. + * @returns True if the wallet was unlocked successfully + */ + async unlock(): Promise { await this.metamaskPlaywright.unlock() await expect(this.metamaskExtensionPage.locator(this.metamaskPlaywright.homePage.selectors.logo)).toBeVisible() - return true } - // Others - - async providePublicEncryptionKey() { + /** + * Provides a public encryption key. + * @returns True if the key was provided successfully, false otherwise + */ + async providePublicEncryptionKey(): Promise { return await this.metamaskPlaywright .providePublicEncryptionKey() .then(() => { @@ -273,7 +369,11 @@ export default class MetaMask { }) } - async decrypt() { + /** + * Decrypts a message. + * @returns True if the message was decrypted successfully, false otherwise + */ + async decrypt(): Promise { return await this.metamaskPlaywright .decrypt() .then(() => { @@ -284,7 +384,11 @@ export default class MetaMask { }) } - async confirmSignature() { + /** + * Confirms a signature request. + * @returns True if the signature was confirmed successfully, false otherwise + */ + async confirmSignature(): Promise { return await this.metamaskPlaywright .confirmSignature() .then(() => { @@ -295,39 +399,53 @@ export default class MetaMask { }) } - async rejectSignature() { + /** + * Rejects a signature request. + * @returns True if the signature was rejected successfully + */ + async rejectSignature(): Promise { await this.metamaskPlaywright.rejectSignature() - return true } - async confirmTransaction(options?: { gasSetting?: GasSettings }) { + /** + * Confirms a transaction. + * @param options - Optional gas settings for the transaction + * @returns True if the transaction was confirmed successfully + */ + async confirmTransaction(options?: { + gasSetting?: GasSettings + }): Promise { await waitFor( () => this.metamaskExtensionPage.locator(TransactionPage.nftApproveAllConfirmationPopup.approveButton).isVisible(), 5_000, false ) - await this.metamaskPlaywright.confirmTransaction(options) - return true } - async rejectTransaction() { + /** + * Rejects a transaction. + * @returns True if the transaction was rejected successfully + */ + async rejectTransaction(): Promise { await this.metamaskPlaywright.rejectTransaction() - return true } - async confirmTransactionAndWaitForMining() { + /** + * Confirms a transaction and waits for it to be mined. + * @returns True if the transaction was confirmed and mined successfully, false otherwise + */ + async confirmTransactionAndWaitForMining(): Promise { await waitFor( () => this.metamaskExtensionPage.locator(TransactionPage.nftApproveAllConfirmationPopup.approveButton).isVisible(), 5_000, false ) - return this.metamaskPlaywright .confirmTransactionAndWaitForMining() .then(() => { @@ -338,7 +456,12 @@ export default class MetaMask { }) } - async openTransactionDetails(txIndex: number) { + /** + * Opens the details of a specific transaction. + * @param txIndex - The index of the transaction to open + * @returns True if the transaction details were opened successfully, false otherwise + */ + async openTransactionDetails(txIndex: number): Promise { return this.metamaskPlaywright .openTransactionDetails(txIndex) .then(() => { @@ -349,7 +472,11 @@ export default class MetaMask { }) } - async closeTransactionDetails() { + /** + * Closes the transaction details view. + * @returns True if the transaction details were closed successfully, false otherwise + */ + async closeTransactionDetails(): Promise { return this.metamaskPlaywright .closeTransactionDetails() .then(() => { @@ -360,40 +487,53 @@ export default class MetaMask { }) } - async toggleShowTestNetworks() { + /** + * Toggles the display of test networks. + * @returns True if the toggle was successful + */ + async toggleShowTestNetworks(): Promise { await this.metamaskPlaywright.toggleShowTestNetworks() - return true } - async toggleDismissSecretRecoveryPhraseReminder() { + /** + * Toggles the dismissal of the secret recovery phrase reminder. + * @returns True if the toggle was successful + */ + async toggleDismissSecretRecoveryPhraseReminder(): Promise { await this.metamaskPlaywright.toggleDismissSecretRecoveryPhraseReminder() - return true } - async goBackToHomePage() { + /** + * Navigates back to the home page. + * @returns True if the navigation was successful + */ + async goBackToHomePage(): Promise { 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() - return true } - async openSettings() { + /** + * Opens the settings page. + * @returns True if the settings page was opened successfully + */ + async openSettings(): Promise { await this.metamaskPlaywright.openSettings() - return true } - async openSidebarMenu(menu: SettingsSidebarMenus) { + /** + * Opens a specific sidebar menu in the settings. + * @param menu - The menu to open + * @returns True if the menu was opened successfully + */ + async openSidebarMenu(menu: SettingsSidebarMenus): Promise { await this.metamaskPlaywright.openSidebarMenu(menu) await expect(this.metamaskExtensionPage.locator(HomePageSelectors.settings.sidebarMenu(menu))).toBeVisible() - return true } } diff --git a/wallets/metamask/src/cypress/configureSynpress.ts b/wallets/metamask/src/cypress/configureSynpress.ts index fbced67ca..8960e76de 100644 --- a/wallets/metamask/src/cypress/configureSynpress.ts +++ b/wallets/metamask/src/cypress/configureSynpress.ts @@ -20,6 +20,38 @@ let metamaskExtensionPage: Page // TODO: Implement if needed to change the focus between pages // let cypressPage: Page +/** + * Configures Synpress for use with MetaMask. + * + * This function sets up the necessary configurations and hooks for running + * Cypress tests with MetaMask. + * + * @param on - Cypress plugin event handler + * @param config - Cypress plugin configuration options + * @param importDefaultWallet - Whether to import the default wallet + * @returns Modified Cypress configuration + * @throws Error If no Chrome browser is found in the configuration + * + * @remarks + * This function performs the following tasks: + * + * 1. Filters the available browsers to ensure only Chrome is used. + * 2. Sets up a 'before:browser:launch' hook to enable debug mode, establish + * a Playwright connection, and initialize MetaMask. + * 3. Sets up a 'before:spec' hook to import the MetaMask wallet before + * each test spec runs. + * 4. Provides task handlers for various MetaMask-related operations. + * + * @example + * ```typescript + * import { configureSynpress } from './configureSynpress'; + * + * export default (on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) => { + * return configureSynpress(on, config); + * }; + * ``` + */ + export default function configureSynpress( on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions, diff --git a/wallets/metamask/src/cypress/support/initMetaMask.ts b/wallets/metamask/src/cypress/support/initMetaMask.ts index 5266fb93b..ec7b13eef 100644 --- a/wallets/metamask/src/cypress/support/initMetaMask.ts +++ b/wallets/metamask/src/cypress/support/initMetaMask.ts @@ -1,10 +1,19 @@ import { prepareExtension } from '../../prepareExtension' -export async function initMetaMask() { +/** + * Initializes MetaMask for Cypress tests. + * + * This function prepares the MetaMask extension for use in Cypress tests. + * It sets up the necessary browser arguments and extension paths. + * + * @async + * @returns {Promise<{extensions: string[], browserArgs: string[]}>} An object containing the extension path and browser arguments. + */ +export async function initMetaMask(): Promise<{ extensions: string[]; browserArgs: string[] }> { const metamaskPath = await prepareExtension(false) const extensions = [metamaskPath] - const browserArgs = [] + const browserArgs: string[] = [] if (process.env.HEADLESS) { browserArgs.push('--headless=new') diff --git a/wallets/metamask/src/cypress/support/synpressCommands.ts b/wallets/metamask/src/cypress/support/synpressCommands.ts index e46a8a78f..3a4342e93 100644 --- a/wallets/metamask/src/cypress/support/synpressCommands.ts +++ b/wallets/metamask/src/cypress/support/synpressCommands.ts @@ -76,53 +76,135 @@ declare global { } } -export default function synpressCommands() { +/** + * Synpress Commands for MetaMask + * + * This module extends Cypress with custom commands for interacting with MetaMask and Ethereum networks. + * It provides a wide range of functionalities including wallet management, account operations, + * network interactions, token handling, transaction management, and MetaMask UI interactions. + * + * @module SynpressCommandsForMetaMask + * + * Key features: + * - Wallet: Import wallet, connect to dApps + * - Account: Add, switch, rename, reset accounts + * - Network: Switch networks, create and manage Anvil nodes, add custom networks + * - Tokens: Deploy tokens, add new tokens, approve token permissions + * - Transactions: Confirm, reject, and view transaction details + * - MetaMask UI: Lock/unlock, toggle settings, navigate UI + * + * These commands enhance the testing capabilities for Ethereum-based applications, + * allowing for comprehensive end-to-end testing of dApps integrated with MetaMask. + */ + +/** + * Initializes Synpress commands for MetaMask + */ +export default function synpressCommandsForMetaMask(): void { // Wallet + /** + * Imports a wallet using a seed phrase + * @param seedPhrase - The seed phrase to import + */ Cypress.Commands.add('importWallet', (seedPhrase: string) => { return cy.task('importWallet', seedPhrase) }) + /** + * Imports a wallet using a private key + * @param privateKey - The private key to import + */ Cypress.Commands.add('importWalletFromPrivateKey', (privateKey: string) => { return cy.task('importWalletFromPrivateKey', privateKey) }) + /** + * Connects to a dApp + */ Cypress.Commands.add('connectToDapp', () => { return cy.task('connectToDapp') }) // Account + /** + * Gets the current account + */ Cypress.Commands.add('getAccount', () => { return cy.task('getAccount') }) + + /** + * Adds a new account + * @param accountName - The name of the new account + */ Cypress.Commands.add('addNewAccount', (accountName: string) => { return cy.task('addNewAccount', accountName) }) + + /** + * Switches to a different account + * @param accountName - The name of the account to switch to + */ Cypress.Commands.add('switchAccount', (accountName: string) => { return cy.task('switchAccount', accountName) }) + + /** + * Renames an account + * @param currentAccountName - The current name of the account + * @param newAccountName - The new name for the account + */ Cypress.Commands.add('renameAccount', (currentAccountName: string, newAccountName: string) => { return cy.task('renameAccount', { currentAccountName, newAccountName }) }) + + /** + * Gets the address of the current account + * @returns The account address + */ Cypress.Commands.add('getAccountAddress', () => { return cy.task('getAccountAddress') }) + + /** + * Resets the current account + */ Cypress.Commands.add('resetAccount', () => { return cy.task('resetAccount') }) // Network + /** + * Gets the current network + */ Cypress.Commands.add('getNetwork', () => { return cy.task('getNetwork') }) + + /** + * Switches to a different network + * @param networkName - The name of the network to switch to + * @param isTestnet - Whether the network is a testnet + */ Cypress.Commands.add('switchNetwork', (networkName: string, isTestnet = false) => { return cy.task('switchNetwork', { networkName, isTestnet }) }) + + /** + * Creates an Anvil node + * @param options - Options for creating the Anvil node + * @returns An object containing the Anvil instance, RPC URL, and chain ID + */ Cypress.Commands.add('createAnvilNode', (options?: CreateAnvilOptions) => { return cy.task('createAnvilNode', options) }) + + /** + * Connects to an Anvil node + */ Cypress.Commands.add('connectToAnvil', () => { return cy.task('createAnvilNode').then((anvilNetwork) => { const anvilNetworkDetails = anvilNetwork as { @@ -142,33 +224,72 @@ export default function synpressCommands() { return cy.task('addNetwork', network) }) }) + + /** + * Empties the Anvil node + */ Cypress.Commands.add('emptyAnvilNode', () => { return cy.task('emptyAnvilNode') }) + + /** + * Adds a new network + * @param network - The network to add + */ Cypress.Commands.add('addNetwork', (network: Network) => { return cy.task('addNetwork', network) }) + + /** + * Approves adding a new network + */ Cypress.Commands.add('approveNewNetwork', () => { return cy.task('approveNewNetwork') }) + + /** + * Approves switching to a new network + */ Cypress.Commands.add('approveSwitchNetwork', () => { return cy.task('approveSwitchNetwork') }) + + /** + * Rejects adding a new network + */ Cypress.Commands.add('rejectNewNetwork', () => { return cy.task('rejectNewNetwork') }) + + /** + * Rejects switching to a new network + */ Cypress.Commands.add('rejectSwitchNetwork', () => { return cy.task('rejectSwitchNetwork') }) // Token + /** + * Deploys a token + */ Cypress.Commands.add('deployToken', () => { return cy.task('deployToken') }) + + /** + * Adds a new token + */ Cypress.Commands.add('addNewToken', () => { return cy.task('addNewToken') }) + + /** + * Approves token permission + * @param options - Options for approving token permission + * @param options.spendLimit - The spend limit for the token + * @param options.gasSetting - Gas settings for the transaction + */ Cypress.Commands.add( 'approveTokenPermission', (options?: { @@ -178,63 +299,132 @@ export default function synpressCommands() { return cy.task('approveTokenPermission', options) } ) + + /** + * Rejects token permission + */ Cypress.Commands.add('rejectTokenPermission', () => { return cy.task('rejectTokenPermission') }) // Lock/Unlock + /** + * Locks MetaMask + */ Cypress.Commands.add('lock', () => { return cy.task('lock') }) + + /** + * Unlocks MetaMask + */ Cypress.Commands.add('unlock', () => { return cy.task('unlock') }) // Toggles + /** + * Toggles showing test networks + */ Cypress.Commands.add('toggleShowTestNetworks', () => { return cy.task('toggleShowTestNetworks') }) + + /** + * Toggles dismissing the secret recovery phrase reminder + */ Cypress.Commands.add('toggleDismissSecretRecoveryPhraseReminder', () => { return cy.task('toggleDismissSecretRecoveryPhraseReminder') }) // Others + /** + * Provides a public encryption key + */ Cypress.Commands.add('providePublicEncryptionKey', () => { return cy.task('providePublicEncryptionKey') }) + + /** + * Decrypts a message + */ Cypress.Commands.add('decrypt', () => { return cy.task('decrypt') }) + + /** + * Confirms a signature + */ Cypress.Commands.add('confirmSignature', () => { return cy.task('confirmSignature') }) + + /** + * Rejects a signature + */ Cypress.Commands.add('rejectSignature', () => { return cy.task('rejectSignature') }) + + /** + * Confirms a transaction + * @param options - Options for confirming the transaction + * @param options.gasSetting - Gas settings for the transaction + */ Cypress.Commands.add('confirmTransaction', (options?: { gasSetting?: GasSettings }) => { return cy.task('confirmTransaction', options) }) + + /** + * Rejects a transaction + */ Cypress.Commands.add('rejectTransaction', () => { return cy.task('rejectTransaction') }) + + /** + * Confirms a transaction and waits for mining + */ Cypress.Commands.add('confirmTransactionAndWaitForMining', () => { return cy.task('confirmTransactionAndWaitForMining') }) + + /** + * Opens transaction details + * @param txIndex - The index of the transaction to open + */ Cypress.Commands.add('openTransactionDetails', (txIndex = 0) => { return cy.task('openTransactionDetails', txIndex) }) + + /** + * Closes transaction details + */ Cypress.Commands.add('closeTransactionDetails', () => { return cy.task('closeTransactionDetails') }) + + /** + * Goes back to the home page + */ Cypress.Commands.add('goBackToHomePage', () => { return cy.task('goBackToHomePage') }) + + /** + * Opens settings + */ Cypress.Commands.add('openSettings', () => { return cy.task('openSettings') }) + + /** + * Opens a sidebar menu + * @param menu - The menu to open + */ Cypress.Commands.add('openSidebarMenu', (menu: SettingsSidebarMenus) => { return cy.task('openSidebarMenu', menu) }) diff --git a/wallets/metamask/src/playwright/MetaMask.ts b/wallets/metamask/src/playwright/MetaMask.ts index 19f56f57e..b3120c7de 100644 --- a/wallets/metamask/src/playwright/MetaMask.ts +++ b/wallets/metamask/src/playwright/MetaMask.ts @@ -8,61 +8,81 @@ import { SettingsPage } from './pages/SettingsPage/page' const NO_EXTENSION_ID_ERROR = new Error('MetaMask extensionId is not set') +/** + * MetaMask class for interacting with the MetaMask extension in Playwright tests. + * + * This class provides methods to perform various operations on the MetaMask extension, + * such as importing wallets, switching networks, confirming transactions, and more. + * + * @class + * @extends MetaMaskAbstract + */ export class MetaMask extends MetaMaskAbstract { /** - * This property can be used to access selectors for a given page. + * This property can be used to access selectors for the crash page. * - * @group Selectors + * @public + * @readonly */ readonly crashPage: CrashPage + /** - * This property can be used to access selectors for a given page. + * This property can be used to access selectors for the onboarding page. * - * @group Selectors + * @public + * @readonly */ readonly onboardingPage: OnboardingPage + /** - * This property can be used to access selectors for a given page. + * This property can be used to access selectors for the lock page. * - * @group Selectors + * @public + * @readonly */ readonly lockPage: LockPage + /** - * This property can be used to access selectors for a given page. + * This property can be used to access selectors for the home page. * - * @group Selectors + * @public + * @readonly */ readonly homePage: HomePage + /** - * This property can be used to access selectors for a given page. + * This property can be used to access selectors for the notification page. * - * @group Selectors + * @public + * @readonly */ readonly notificationPage: NotificationPage + + /** + * This property can be used to access selectors for the settings page. + * + * @public + * @readonly + */ readonly settingsPage: SettingsPage + /** + * Creates an instance of MetaMask. + * + * @param context - The Playwright BrowserContext in which the MetaMask extension is running. + * @param page - The Playwright Page object representing the MetaMask extension's main page. + * @param password - The password for the MetaMask wallet. + * @param extensionId - The ID of the MetaMask extension. Optional if no interaction with dapps is required. + */ constructor( - /** - * The browser context. - */ readonly context: BrowserContext, - /** - * The MetaMask tab page. - */ readonly page: Page, - /** - * The password of the MetaMask wallet. - */ override readonly password: string, - /** - * The extension ID of the MetaMask extension. Optional if no interaction with the dapp is required. - */ override readonly extensionId?: string ) { super(password, extensionId) this.crashPage = new CrashPage() - this.onboardingPage = new OnboardingPage(page) this.lockPage = new LockPage(page) this.homePage = new HomePage(page) @@ -70,11 +90,21 @@ export class MetaMask extends MetaMaskAbstract { this.settingsPage = new SettingsPage(page) } - async importWallet(seedPhrase: string) { + /** + * Imports a wallet using the given seed phrase. + * + * @param seedPhrase - The seed phrase to import. + */ + async importWallet(seedPhrase: string): Promise { await this.onboardingPage.importWallet(seedPhrase, this.password) } - async addNewAccount(accountName: string) { + /** + * Adds a new account with the given name. + * + * @param accountName - The name for the new account. + */ + async addNewAccount(accountName: string): Promise { await this.homePage.addNewAccount(accountName) } @@ -84,7 +114,7 @@ export class MetaMask extends MetaMaskAbstract { * @param currentAccountName - The current account name. * @param newAccountName - The new name for the account. */ - async renameAccount(currentAccountName: string, newAccountName: string) { + async renameAccount(currentAccountName: string, newAccountName: string): Promise { await this.homePage.renameAccount(currentAccountName, newAccountName) } @@ -93,28 +123,54 @@ export class MetaMask extends MetaMaskAbstract { * * @param privateKey - The private key to import. */ - - async importWalletFromPrivateKey(privateKey: string) { + async importWalletFromPrivateKey(privateKey: string): Promise { await this.homePage.importWalletFromPrivateKey(privateKey) } - async switchAccount(accountName: string) { + /** + * Switches to the account with the given name. + * + * @param accountName - The name of the account to switch to. + */ + async switchAccount(accountName: string): Promise { await this.homePage.switchAccount(accountName) } - async addNetwork(network: Network) { + /** + * Adds a new network to MetaMask. + * + * @param network - The network configuration to add. + */ + async addNetwork(network: Network): Promise { await this.homePage.addNetwork(network) } - async getAccountAddress() { + /** + * Gets the address of the currently selected account. + * + * @returns The account address. + */ + async getAccountAddress(): Promise { return await this.homePage.getAccountAddress() } - async switchNetwork(networkName: string, isTestnet = false) { + /** + * Switches to the specified network. + * + * @param networkName - The name of the network to switch to. + * @param isTestnet - Whether the network is a testnet. Default is false. + */ + async switchNetwork(networkName: string, isTestnet = false): Promise { await this.homePage.switchNetwork(networkName, isTestnet) } - async connectToDapp(accounts?: string[]) { + /** + * Connects MetaMask to a dapp. + * + * @param accounts - Optional array of account addresses to connect. + * @throws {Error} If extensionId is not set. + */ + async connectToDapp(accounts?: string[]): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -122,15 +178,26 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.connectToDapp(this.extensionId, accounts) } - async lock() { + /** + * Locks the MetaMask wallet. + */ + async lock(): Promise { await this.homePage.lock() } - async unlock() { + /** + * Unlocks the MetaMask wallet. + */ + async unlock(): Promise { await this.lockPage.unlock(this.password) } - async confirmSignature() { + /** + * Confirms a signature request. + * + * @throws {Error} If extensionId is not set. + */ + async confirmSignature(): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -138,7 +205,12 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.signMessage(this.extensionId) } - async confirmSignatureWithRisk() { + /** + * Confirms a signature request with risk. + * + * @throws {Error} If extensionId is not set. + */ + async confirmSignatureWithRisk(): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -146,7 +218,12 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.signMessageWithRisk(this.extensionId) } - async rejectSignature() { + /** + * Rejects a signature request. + * + * @throws {Error} If extensionId is not set. + */ + async rejectSignature(): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -154,7 +231,12 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.rejectMessage(this.extensionId) } - async approveNewNetwork() { + /** + * Approves adding a new network. + * + * @throws {Error} If extensionId is not set. + */ + async approveNewNetwork(): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -162,7 +244,12 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.approveNewNetwork(this.extensionId) } - async rejectNewNetwork() { + /** + * Rejects adding a new network. + * + * @throws {Error} If extensionId is not set. + */ + async rejectNewNetwork(): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -170,7 +257,12 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.rejectNewNetwork(this.extensionId) } - async approveSwitchNetwork() { + /** + * Approves switching to a new network. + * + * @throws {Error} If extensionId is not set. + */ + async approveSwitchNetwork(): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -178,7 +270,12 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.approveSwitchNetwork(this.extensionId) } - async rejectSwitchNetwork() { + /** + * Rejects switching to a new network. + * + * @throws {Error} If extensionId is not set. + */ + async rejectSwitchNetwork(): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -186,7 +283,13 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.rejectSwitchNetwork(this.extensionId) } - async confirmTransaction(options?: { gasSetting?: GasSettings }) { + /** + * Confirms a transaction. + * + * @param options - Optional gas settings for the transaction. + * @throws {Error} If extensionId is not set. + */ + async confirmTransaction(options?: { gasSetting?: GasSettings }): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -194,7 +297,12 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.confirmTransaction(this.extensionId, options) } - async rejectTransaction() { + /** + * Rejects a transaction. + * + * @throws {Error} If extensionId is not set. + */ + async rejectTransaction(): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -202,10 +310,16 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.rejectTransaction(this.extensionId) } + /** + * Approves a token permission request. + * + * @param options - Optional settings for the approval. + * @throws {Error} If extensionId is not set. + */ async approveTokenPermission(options?: { spendLimit?: 'max' | number gasSetting?: GasSettings - }) { + }): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -213,7 +327,12 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.approveTokenPermission(this.extensionId, options) } - async rejectTokenPermission() { + /** + * Rejects a token permission request. + * + * @throws {Error} If extensionId is not set. + */ + async rejectTokenPermission(): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -221,41 +340,72 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.rejectTokenPermission(this.extensionId) } - async goBackToHomePage() { + /** + * Navigates back to the home page. + */ + async goBackToHomePage(): Promise { await this.homePage.goBackToHomePage() } - async openSettings() { + /** + * Opens the settings page. + */ + async openSettings(): Promise { await this.homePage.openSettings() } - async openSidebarMenu(menu: SettingsSidebarMenus) { + /** + * Opens a specific sidebar menu in the settings. + * + * @param menu - The menu to open. + */ + async openSidebarMenu(menu: SettingsSidebarMenus): Promise { await this.homePage.openSidebarMenu(menu) } - async toggleShowTestNetworks() { + /** + * Toggles the display of test networks. + */ + async toggleShowTestNetworks(): Promise { await this.homePage.toggleShowTestNetworks() } - async toggleDismissSecretRecoveryPhraseReminder() { + /** + * Toggles the dismissal of the secret recovery phrase reminder. + */ + async toggleDismissSecretRecoveryPhraseReminder(): Promise { await this.homePage.toggleDismissSecretRecoveryPhraseReminder() } - async resetAccount() { + /** + * Resets the account. + */ + async resetAccount(): Promise { await this.homePage.resetAccount() } - async unsafe_enableEthSign() { + /** + * Enables eth_sign (unsafe). + */ + async unsafe_enableEthSign(): Promise { await this.homePage.openSettings() await this.settingsPage.enableEthSign() } - async disableEthSign() { + /** + * Disables eth_sign. + */ + async disableEthSign(): Promise { await this.homePage.openSettings() await this.settingsPage.disableEthSign() } - async addNewToken() { + /** + * Adds a new token. + * + * @throws {Error} If extensionId is not set. + */ + async addNewToken(): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -263,7 +413,12 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.addNewToken(this.extensionId) } - async providePublicEncryptionKey() { + /** + * Provides a public encryption key. + * + * @throws {Error} If extensionId is not set. + */ + async providePublicEncryptionKey(): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -271,7 +426,12 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.providePublicEncryptionKey(this.extensionId) } - async decrypt() { + /** + * Decrypts a message. + * + * @throws {Error} If extensionId is not set. + */ + async decrypt(): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -279,9 +439,15 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.decryptMessage(this.extensionId) } + /** + * Confirms a transaction and waits for it to be mined. + * + * @param options - Optional gas settings for the transaction. + * @throws {Error} If extensionId is not set. + */ async confirmTransactionAndWaitForMining(options?: { gasSetting?: GasSettings - }) { + }): Promise { if (!this.extensionId) { throw NO_EXTENSION_ID_ERROR } @@ -289,11 +455,19 @@ export class MetaMask extends MetaMaskAbstract { await this.notificationPage.confirmTransactionAndWaitForMining(this.extensionId, options) } - async openTransactionDetails(txIndex: number) { + /** + * Opens the details of a specific transaction. + * + * @param txIndex - The index of the transaction to open. + */ + async openTransactionDetails(txIndex: number): Promise { await this.homePage.openTransactionDetails(txIndex) } - async closeTransactionDetails() { + /** + * Closes the transaction details view. + */ + async closeTransactionDetails(): Promise { await this.homePage.closeTransactionDetails() } }