Skip to content

Commit

Permalink
✨ feat: Add createAnvilNode fixture
Browse files Browse the repository at this point in the history
  • Loading branch information
duckception committed Nov 27, 2023
1 parent 66811d2 commit a4b78bb
Show file tree
Hide file tree
Showing 15 changed files with 183 additions and 126 deletions.
1 change: 1 addition & 0 deletions packages/fixtures/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"types:check": "tsc --noEmit"
},
"dependencies": {
"@viem/anvil": "^0.0.6",
"core": "workspace:*",
"fs-extra": "^11.1.1",
"zod": "^3.22.4"
Expand Down
22 changes: 22 additions & 0 deletions packages/fixtures/src/fixtures/testWithSynpress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
PlaywrightWorkerOptions
} from '@playwright/test'
import { chromium, test as base } from '@playwright/test'
import { type Anvil, type CreateAnvilOptions, createPool } from '@viem/anvil'
import { defineWalletSetup } from 'core'
import { createTempContextDir, removeTempContextDir } from 'core'
import { CACHE_DIR_NAME, prepareExtension } from 'core'
Expand All @@ -27,6 +28,7 @@ type PrivateSynpressFixtures = {
type PublicSynpressFixtures = {
extensionId: string
metamaskPage: Page
createAnvilNode: (options?: CreateAnvilOptions) => Promise<{ anvil: Anvil; rpcUrl: string; chainId: number }>
}

type SynpressFixtures = TestFixtures & PrivateSynpressFixtures & PublicSynpressFixtures
Expand Down Expand Up @@ -101,6 +103,26 @@ const synpressFixtures = (
},
metamaskPage: async ({ context: _ }, use) => {
await use(_metamaskPage)
},
// TODO: We should be able to use this in a wallet setup. This will be possible when we add a store.
// TODO: ^ Thanks to this we won't have to rely on MetaMask RPC for initial connection, which will increase the speed of the tests.
createAnvilNode: async ({ context: _ }, use) => {
const pool = createPool()

await use(async (options?: CreateAnvilOptions) => {
const nodeId = Array.from(pool.instances()).length
// const anvil = await pool.start(nodeId, options)
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 }
})

await pool.empty()
}
})

Expand Down
48 changes: 40 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions wallets/metamask/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ export default defineConfig({
// Look for test files in the "test/e2e" directory, relative to this configuration file.
testDir: './test/e2e',

// We're increasing the timeout to 60 seconds to allow all traces to be recorded.
// Sometimes it threw an error saying that traces were not recorded in the 30 seconds timeout limit.
timeout: 60_000,

// Run all tests in parallel.
fullyParallel: true,

Expand Down
1 change: 1 addition & 0 deletions wallets/metamask/src/fixture-actions/unlockForFixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export async function unlockForFixture(page: Page, password: string) {

await metamask.unlock()

// TODO: If this function times out -> page.reload() and try again.
await waitForSpinnerToVanish(page)

await retryIfMetaMaskCrashAfterUnlock(page)
Expand Down
35 changes: 26 additions & 9 deletions wallets/metamask/test/e2e/metamask/addNetwork.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,53 @@ const test = testWithSynpress(basicSetup, unlockForFixture)

const { expect } = test

const network = {
const optimismMainnet = {
name: 'OP Mainnet',
rpcUrl: 'https://mainnet.optimism.io',
chainId: 10,
symbol: 'ETH',
blockExplorerUrl: 'https://optimistic.etherscan.io'
}

test('should add network and close network added popup', async ({ context, metamaskPage }) => {
test('should add network and close network added popup', async ({ context, metamaskPage, createAnvilNode }) => {
const metamask = new MetaMask(context, metamaskPage, basicSetup.walletPassword)

const { rpcUrl, chainId } = await createAnvilNode()

const network = {
name: 'Anvil',
rpcUrl,
chainId,
symbol: 'ETH',
blockExplorerUrl: 'https://etherscan.io/'
}

await metamask.addNetwork(network)

const isNetworkAddedPopupVisible = await waitFor(
() => metamaskPage.locator(metamask.homePage.selectors.networkAddedPopover.switchToNetworkButton).isVisible(),
1_000,
3_000,
false
)
expect(isNetworkAddedPopupVisible).toBe(false)

await expect(metamaskPage.locator(metamask.homePage.selectors.currentNetwork)).toHaveText(network.name)
})

test('should add network without block explorer', async ({ context, metamaskPage }) => {
test('should add network without block explorer', async ({ context, metamaskPage, createAnvilNode }) => {
const metamask = new MetaMask(context, metamaskPage, basicSetup.walletPassword)

await metamask.addNetwork({
...network,
const { rpcUrl, chainId } = await createAnvilNode()

const network = {
name: 'Anvil',
rpcUrl,
chainId,
symbol: 'ETH',
blockExplorerUrl: undefined
})
}

await metamask.addNetwork(network)

await expect(metamaskPage.locator(metamask.homePage.selectors.currentNetwork)).toHaveText(network.name)
})
Expand All @@ -54,7 +71,7 @@ test('should throw if there is an issue with rpc url', async ({ context, metamas
const metamask = new MetaMask(context, metamaskPage, basicSetup.walletPassword)

const promise = metamask.addNetwork({
...network,
...optimismMainnet,
rpcUrl: 'hps://mainnet.optimism.io' // Incorrect.
})

Expand All @@ -67,7 +84,7 @@ test('should throw if there is an issue with chain id', async ({ context, metama
const metamask = new MetaMask(context, metamaskPage, basicSetup.walletPassword)

const promise = metamask.addNetwork({
...network,
...optimismMainnet,
chainId: 0x42069 // Incorrect.
})

Expand Down
7 changes: 6 additions & 1 deletion wallets/metamask/test/e2e/metamask/approveNewNetwork.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ const test = testWithMetaMask

const { expect } = test

test('should add a new network', async ({ page, metamask }) => {
test('should add a new network', async ({ page, metamask, createAnvilNode }) => {
await createAnvilNode({
chainId: 1338,
port: 8546
})

await page.locator('#addEthereumChain').click()

await metamask.approveNewNetwork()
Expand Down
28 changes: 9 additions & 19 deletions wallets/metamask/test/e2e/metamask/approvePermission.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { testWithMetaMask } from '../testWithMetaMask'

const test = testWithMetaMask.extend<{
switchChainAndDeployToken: () => Promise<void>
deployToken: () => Promise<void>
}>({
switchChainAndDeployToken: async ({ page, metamask }, use) => {
deployToken: async ({ page, metamask, connectToAnvil }, use) => {
await use(async () => {
await page.locator('#addEthereumChain').click()

await metamask.approveNewNetwork()
await metamask.approveSwitchNetwork()
await connectToAnvil()

await expect(page.locator('#tokenAddresses')).toBeEmpty()
await page.locator('#createToken').click()
Expand All @@ -20,31 +17,24 @@ const test = testWithMetaMask.extend<{

const { expect } = test

// These tests rely on the same account, which means they must be run in serial.
test.describe.configure({ mode: 'serial' })

test('should approve tokens with the default limit by default', async ({
page,
metamask,
switchChainAndDeployToken
}) => {
await switchChainAndDeployToken()
test('should approve tokens with the default limit by default', async ({ page, metamask, deployToken }) => {
await deployToken()

await page.locator('#approveTokens').click()

await metamask.approvePermission()
})

test('should approve tokens with the max limit', async ({ page, metamask, switchChainAndDeployToken }) => {
await switchChainAndDeployToken()
test('should approve tokens with the max limit', async ({ page, metamask, deployToken }) => {
await deployToken()

await page.locator('#approveTokens').click()

await metamask.approvePermission('max')
})

test('should approve tokens with the custom limit', async ({ page, metamask, switchChainAndDeployToken }) => {
await switchChainAndDeployToken()
test('should approve tokens with the custom limit', async ({ page, metamask, deployToken }) => {
await deployToken()

await page.locator('#approveTokens').click()

Expand Down
Loading

0 comments on commit a4b78bb

Please sign in to comment.