Skip to content

Commit

Permalink
✅ test(metamask): Run tests in parallel
Browse files Browse the repository at this point in the history
  • Loading branch information
duckception committed Nov 6, 2023
1 parent c721a58 commit b8a62db
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 115 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ jobs:
- name: Build project
run: pnpm run build

- name: Build cache
run: |
xvfb-run pnpm run build:cache
- name: Run E2E tests (headful)
run: |
xvfb-run pnpm run test:e2e:headful
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"private": true,
"scripts": {
"build": "turbo build",
"build:cache": "turbo build:cache",
"format": "biome format . --write",
"format:check": "biome format . --error-on-warnings",
"preinstall": "npx only-allow pnpm",
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

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

4 changes: 2 additions & 2 deletions turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
"test": {
"dependsOn": ["build"]
},
"test:e2e:headless": {
"build:cache": {
"dependsOn": ["build"]
},
"test:e2e:headful": {
"dependsOn": ["build"]
"dependsOn": ["build", "build:cache"]
}
}
}
4 changes: 4 additions & 0 deletions wallets/metamask/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
],
"scripts": {
"build": "pnpm run clean && pnpm run build:dist && pnpm run build:types",
"build:cache": "core test/e2e/wallet-setup",
"build:cache:headless": "core test/e2e/wallet-setup --headless",
"build:cache:headless:force": "core test/e2e/wallet-setup --headless --force",
"build:dist": "tsup --tsconfig tsconfig.build.json",
"build:types": "tsc --emitDeclarationOnly --project tsconfig.build.json",
"clean": "rimraf dist types",
Expand All @@ -30,6 +33,7 @@
},
"dependencies": {
"core": "workspace:*",
"fixtures": "workspace:*",
"zod": "^3.22.4"
},
"devDependencies": {
Expand Down
3 changes: 1 addition & 2 deletions wallets/metamask/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ export default defineConfig({
testDir: './test/e2e',

// Run all tests in parallel.
// TODO: Enable later once we have more tests.
fullyParallel: false,
fullyParallel: true,

// Fail the build on CI if you accidentally left test.only in the source code.
forbidOnly: !!process.env.CI,
Expand Down
22 changes: 22 additions & 0 deletions wallets/metamask/test/e2e/connectToDapp.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { testWithSynpress } from 'fixtures'
import { connectToDapp, getExtensionId, unlockForFixture } from '../../src'

import basicSetup from './wallet-setup/basic.setup'

const test = testWithSynpress(basicSetup, unlockForFixture)

const { describe, expect } = test

describe('connectToDapp', () => {
test('should connect wallet to dapp', async ({ context, page }) => {
const extensionId = await getExtensionId(context, 'MetaMask')

await page.goto('https://metamask.github.io/test-dapp/')

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

await connectToDapp(context, extensionId)

await expect(page.locator('#accounts')).toHaveText('0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266')
})
})
15 changes: 15 additions & 0 deletions wallets/metamask/test/e2e/getExtensionId.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { testWithSynpress } from 'fixtures'
import { getExtensionId, unlockForFixture } from '../../src'

import basicSetup from './wallet-setup/basic.setup'

const test = testWithSynpress(basicSetup, unlockForFixture)

const { describe, expect } = test

describe('getExtensionId', () => {
test('should return the extension id', async ({ context }) => {
const extensionId = await getExtensionId(context, 'MetaMask')
expect(extensionId).toMatch(/^[a-z]{32}$/)
})
})
62 changes: 62 additions & 0 deletions wallets/metamask/test/e2e/importWallet.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { type BrowserContext, type Page, chromium, test as base } from '@playwright/test'
import { OnboardingPage, prepareExtension } from '../../src'

const SEED_PHRASE = 'test test test test test test test test test test test junk'
const PASSWORD = 'Tester@1234'

let sharedContext: BrowserContext | undefined

const test = base.extend<{
metamaskPage: Page
}>({
context: async ({ context: _ }, use) => {
if (sharedContext) {
await use(sharedContext)

return
}

const metamaskPath = await prepareExtension()

// biome-ignore format: the array should not be formatted
const browserArgs = [
`--disable-extensions-except=${metamaskPath}`,
`--load-extension=${metamaskPath}`
]

if (process.env.HEADLESS) {
browserArgs.push('--headless=new')
}

const context = await chromium.launchPersistentContext('', {
headless: false,
args: browserArgs
})

try {
await context.waitForEvent('page', { timeout: 5000 })
} catch {
throw new Error('[FIXTURE] MetaMask extension did not load in time')
}

sharedContext = context
await use(context)
},
metamaskPage: async ({ context }, use) => {
const metamaskOnboardingPage = context.pages()[1] as Page
await use(metamaskOnboardingPage)
}
})

const { describe, expect } = test

describe('importWallet', () => {
test('should go through the onboarding flow and import wallet from seed phrase', async ({ metamaskPage }) => {
const onboardingPage = new OnboardingPage(metamaskPage)

await onboardingPage.importWallet(SEED_PHRASE, PASSWORD)

await expect(metamaskPage.getByText('Account 1')).toBeVisible()
await expect(metamaskPage.getByText('0xf39...2266')).toBeVisible()
})
})
16 changes: 16 additions & 0 deletions wallets/metamask/test/e2e/lock.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { testWithSynpress } from 'fixtures'
import { UnlockPageSelectors, lock, unlockForFixture } from '../../src'

import basicSetup from './wallet-setup/basic.setup'

const test = testWithSynpress(basicSetup, unlockForFixture)

const { describe, expect } = test

describe('lock', () => {
test('should lock the wallet', async ({ metamaskPage }) => {
await lock(metamaskPage)

await expect(metamaskPage.locator(UnlockPageSelectors.submitButton)).toBeVisible()
})
})
111 changes: 0 additions & 111 deletions wallets/metamask/test/e2e/metamask.spec.ts

This file was deleted.

18 changes: 18 additions & 0 deletions wallets/metamask/test/e2e/unlock.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { testWithSynpress } from 'fixtures'
import { HomePageSelectors, lock, unlock, unlockForFixture } from '../../src'

import basicSetup from './wallet-setup/basic.setup'

const test = testWithSynpress(basicSetup, unlockForFixture)

const { describe, expect } = test

describe('unlock', () => {
test('should unlock the wallet', async ({ metamaskPage }) => {
await lock(metamaskPage)

await unlock(metamaskPage, basicSetup.walletPassword)

await expect(metamaskPage.locator(HomePageSelectors.logo)).toBeVisible()
})
})
10 changes: 10 additions & 0 deletions wallets/metamask/test/e2e/wallet-setup/basic.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineWalletSetup } from 'core'
import { importWallet } from './utils/importWallet'

const SEED_PHRASE = 'test test test test test test test test test test test junk'

const PASSWORD = 'Tester@1234'

export default defineWalletSetup(PASSWORD, async (_, walletPage) => {
await importWallet(walletPage, SEED_PHRASE, PASSWORD)
})
8 changes: 8 additions & 0 deletions wallets/metamask/test/e2e/wallet-setup/utils/importWallet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { Page } from '@playwright/test'
import { OnboardingPage } from '../../../../src'

export async function importWallet(walletPage: Page, seedPhrase: string, password: string) {
const onboardingPage = new OnboardingPage(walletPage)

await onboardingPage.importWallet(seedPhrase, password)
}

0 comments on commit b8a62db

Please sign in to comment.