Skip to content

Commit

Permalink
chore: serialize email tests and use wc uri instead of deeplink (#2590)
Browse files Browse the repository at this point in the history
Co-authored-by: Segun Adebayo <joseshegs@gmail.com>
Co-authored-by: Enes <enesozturk.d@gmail.com>
Co-authored-by: Chris Smith <chris@walletconnect.com>
  • Loading branch information
4 people authored Jul 29, 2024
1 parent f3b124f commit 02f227a
Show file tree
Hide file tree
Showing 28 changed files with 11,556 additions and 14,850 deletions.
28 changes: 16 additions & 12 deletions .github/workflows/ui_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,16 @@ jobs:
name: 'Playwright Tests'
runs-on:
group: ubuntu-runners
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4]
shardTotal: [4]
timeout-minutes: 20
steps:
- name: Tune GitHub-hosted runner network
uses: smorimoto/tune-github-hosted-runner-network@v1

- name: checkout
uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -83,7 +91,7 @@ jobs:
~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}-${{ hashFiles('apps/laboratory/tests/shared/constants/devices.ts') }}

- name: install
- name: Install dependencies
run: pnpm install

- name: build packages and lab
Expand Down Expand Up @@ -114,25 +122,21 @@ jobs:
SOCIAL_TEST_PASSWORD: ${{ secrets.TESTS_SOCIAL_PASSWORD }}
CI: true
working-directory: ./apps/laboratory/
run: pnpm ${{ inputs.command }}
run: pnpm ${{ inputs.command }} --shard=${{ matrix.shard }}/${{ matrix.shardTotal }}

- name: Run canary with minimal environment config
env:
NEXT_PUBLIC_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_PROJECT_ID }}
NEXTAUTH_SECRET: ${{ secrets.TESTS_NEXTAUTH_SECRET }}
MAILSAC_API_KEY: ${{ secrets.TESTS_MAILSEC_API_KEY }}
NEXT_PUBLIC_SECURE_SITE_SDK_URL: ${{ inputs.secure-site-url }}
CI: true
working-directory: ./apps/laboratory/
run: pnpm playwright:test:canary

- uses: actions/upload-artifact@v3
if: always()
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
name: playwright-report-${{ matrix.shard }}
path: ./apps/laboratory/playwright-report/
retention-days: 7

- uses: actions/upload-artifact@v3
if: always()
with:
name: screenshots
path: ./apps/laboratory/test-results/
retention-days: 7
24 changes: 12 additions & 12 deletions apps/laboratory/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"playwright:install": "playwright install --with-deps",
"playwright:test": "playwright test",
"playwright:test:basic": "playwright test --grep 'basic-tests.spec.ts'",
"playwright:test:wallet": "playwright test --grep 'connect-qr.spec.ts|wallet.spec.ts'",
"playwright:test:wallet": "playwright test --grep 'wallet.spec.ts'",
"playwright:test:email": "playwright test --grep 'email.spec.ts'",
"playwright:test:social": "playwright test --grep 'social.spec.ts'",
"playwright:test:siwe": "playwright test --grep siwe.spec.ts",
Expand All @@ -20,17 +20,17 @@
"playwright:test:sa": "playwright test --grep smart-account.spec.ts",
"playwright:test:canary": "playwright test --retries=0 --grep canary.spec.ts --project='Desktop Chrome/wagmi'",
"playwright:test:wallet-features": "playwright test --grep wallet-features.spec.ts",
"playwright:debug": "pnpm playwright:test -- --debug",
"playwright:debug:basic": "pnpm playwright:test:basic -- --debug",
"playwright:debug:wallet": "pnpm playwright:test:wallet -- --debug",
"playwright:debug:email": "pnpm playwright:test:email -- --debug",
"playwright:debug:social": "pnpm playwright:test:social -- --debug",
"playwright:debug:siwe": "pnpm playwright:test:siwe -- --debug",
"playwright:debug:siwe-email": "pnpm playwright:test:siwe-email -- --debug",
"playwright:debug:siwe-sa": "pnpm playwright:test:siwe-sa -- --debug",
"playwright:debug:sa": "pnpm playwright:test:sa -- --debug",
"playwright:debug:canary": "pnpm playwright:test:canary -- --debug",
"playwright:debug:wallet-features": "pnpm playwright:test:wallet-features -- --debug"
"playwright:debug": "pnpm playwright:test --debug",
"playwright:debug:basic": "pnpm playwright:test:basic --debug",
"playwright:debug:wallet": "pnpm playwright:test:wallet --debug",
"playwright:debug:email": "pnpm playwright:test:email --debug",
"playwright:debug:social": "pnpm playwright:test:social --debug",
"playwright:debug:siwe": "pnpm playwright:test:siwe --debug",
"playwright:debug:siwe-email": "pnpm playwright:test:siwe-email --debug",
"playwright:debug:siwe-sa": "pnpm playwright:test:siwe-sa --debug",
"playwright:debug:sa": "pnpm playwright:test:sa --debug",
"playwright:debug:canary": "pnpm playwright:test:canary --debug",
"playwright:debug:wallet-features": "pnpm playwright:test:wallet-features --debug"
},
"dependencies": {
"@chakra-ui/icons": "2.1.1",
Expand Down
4 changes: 3 additions & 1 deletion apps/laboratory/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ export default defineConfig<ModalFixture>({
retries: getValue(2, 1),
workers: getValue(8, 4),
reporter: getValue(
[['list'], ['html', { open: 'never' }]],
[['list'], ['html', { host: '0.0.0.0' }]],
[['list'], ['html', { host: '0.0.0.0' }]]
),
// Limits the number of failed tests in the whole test suite. Playwright Test will stop after reaching this number of failed tests and skip any tests that were not executed yet
maxFailures: getValue(10, undefined),
expect: {
timeout: getValue(60, 15) * 1000
},
Expand Down
4 changes: 3 additions & 1 deletion apps/laboratory/tests/basic-tests.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { testMExternal } from './shared/fixtures/w3m-external-fixture'
import { testM, expect } from './shared/fixtures/w3m-fixture'
import { ModalValidator } from './shared/validators/ModalValidator'

testM.describe('Modal only tests', () => {
testM('Should be able to open modal', async ({ modalPage }) => {
Expand All @@ -9,7 +10,8 @@ testM.describe('Modal only tests', () => {
})

testMExternal.describe('External connectors tests', () => {
testMExternal('Should show external connectors', async ({ modalPage, modalValidator }) => {
testMExternal('Should show external connectors', async ({ modalPage }) => {
const modalValidator = new ModalValidator(modalPage.page)
await modalPage.page.getByTestId('connect-button').click()
await modalValidator.expectExternalVisible()
})
Expand Down
93 changes: 48 additions & 45 deletions apps/laboratory/tests/canary.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import { testConnectedMW } from './shared/fixtures/w3m-wallet-fixture'
import { timeEnd, timeStart } from './shared/utils/logs'
import { uploadCanaryResultsToCloudWatch } from './shared/utils/metrics'
import { expectConnection } from './shared/utils/validation'
import { ModalValidator } from './shared/validators/ModalValidator'
import { WalletValidator } from './shared/validators/WalletValidator'

const ENV = process.env['ENVIRONMENT'] || 'dev'
const REGION = process.env['REGION'] || 'eu-central-1'

testConnectedMW.beforeEach(async ({ modalValidator, walletValidator }) => {
testConnectedMW.beforeEach(async ({ modalPage, walletPage }) => {
const modalValidator = new ModalValidator(modalPage.page)
const walletValidator = new WalletValidator(walletPage.page)
timeStart('beforeEach expectConnection')
await expectConnection(modalValidator, walletValidator)
timeEnd('beforeEach expectConnection')
Expand All @@ -35,47 +39,46 @@ testConnectedMW.afterEach(async ({ browserName, timingRecords }, testInfo) => {
}
})

testConnectedMW(
'it should sign',
async ({ modalPage, walletPage, modalValidator, walletValidator, timingRecords }) => {
timeStart('modalPage.sign()')
await modalPage.sign()
timeEnd('modalPage.sign()')
const signRequestedTime = new Date()
timeStart('walletValidator.expectReceivedSign')
await walletValidator.expectReceivedSign({})
timeEnd('walletValidator.expectReceivedSign')
const signReceivedTime = new Date()
timingRecords.push({
item: 'sign',
timeMs: signReceivedTime.getTime() - signRequestedTime.getTime()
})
timeStart('walletPage.handleRequest')
await walletPage.handleRequest({ accept: true })
timeEnd('walletPage.handleRequest')
timeStart('modalValidator.expectAcceptedSign')
await modalValidator.expectAcceptedSign()
timeEnd('modalValidator.expectAcceptedSign')
timeStart('modalPage.disconnect')
await modalPage.disconnect()
timeEnd('modalPage.disconnect')
const disconnectRequestedTime = new Date()
timeStart('walletValidator.expectDisconnected')
await walletValidator.expectDisconnected()
timeEnd('walletValidator.expectDisconnected')
// The wallet completes the disconnect first, so testing the disconnect time of the wallet before the disconnect time of the app
const disconnectWalletReceivedTime = new Date()
timingRecords.push({
item: 'disconnectWallet',
timeMs: disconnectWalletReceivedTime.getTime() - disconnectRequestedTime.getTime()
})
timeStart('modalValidator.expectDisconnected')
await modalValidator.expectDisconnected()
timeEnd('modalValidator.expectDisconnected')
const disconnectAppReceivedTime = new Date()
timingRecords.push({
item: 'disconnectApp',
timeMs: disconnectAppReceivedTime.getTime() - disconnectRequestedTime.getTime()
})
}
)
testConnectedMW('it should sign', async ({ modalPage, walletPage, timingRecords }) => {
const modalValidator = new ModalValidator(modalPage.page)
const walletValidator = new WalletValidator(walletPage.page)
timeStart('modalPage.sign()')
await modalPage.sign()
timeEnd('modalPage.sign()')
const signRequestedTime = new Date()
timeStart('walletValidator.expectReceivedSign')
await walletValidator.expectReceivedSign({})
timeEnd('walletValidator.expectReceivedSign')
const signReceivedTime = new Date()
timingRecords.push({
item: 'sign',
timeMs: signReceivedTime.getTime() - signRequestedTime.getTime()
})
timeStart('walletPage.handleRequest')
await walletPage.handleRequest({ accept: true })
timeEnd('walletPage.handleRequest')
timeStart('modalValidator.expectAcceptedSign')
await modalValidator.expectAcceptedSign()
timeEnd('modalValidator.expectAcceptedSign')
timeStart('modalPage.disconnect')
await modalPage.disconnect()
timeEnd('modalPage.disconnect')
const disconnectRequestedTime = new Date()
timeStart('walletValidator.expectDisconnected')
await walletValidator.expectDisconnected()
timeEnd('walletValidator.expectDisconnected')
// The wallet completes the disconnect first, so testing the disconnect time of the wallet before the disconnect time of the app
const disconnectWalletReceivedTime = new Date()
timingRecords.push({
item: 'disconnectWallet',
timeMs: disconnectWalletReceivedTime.getTime() - disconnectRequestedTime.getTime()
})
timeStart('modalValidator.expectDisconnected')
await modalValidator.expectDisconnected()
timeEnd('modalValidator.expectDisconnected')
const disconnectAppReceivedTime = new Date()
timingRecords.push({
item: 'disconnectApp',
timeMs: disconnectAppReceivedTime.getTime() - disconnectRequestedTime.getTime()
})
})
19 changes: 0 additions & 19 deletions apps/laboratory/tests/connect-qr.spec.ts

This file was deleted.

129 changes: 80 additions & 49 deletions apps/laboratory/tests/email.spec.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,94 @@
import { expect } from '@playwright/test'
import { testMEmail } from './shared/fixtures/w3m-email-fixture'
import { expect, test, type BrowserContext } from '@playwright/test'
import { ModalWalletPage } from './shared/pages/ModalWalletPage'
import { Email } from './shared/utils/email'
import { ModalWalletValidator } from './shared/validators/ModalWalletValidator'
import { SECURE_WEBSITE_URL } from './shared/constants'
import type { ModalWalletPage } from './shared/pages/ModalWalletPage'
import type { ModalWalletValidator } from './shared/validators/ModalWalletValidator'

testMEmail.beforeEach(async ({ modalValidator }) => {
await modalValidator.expectConnected()
/* eslint-disable init-declarations */
let page: ModalWalletPage
let validator: ModalWalletValidator
let context: BrowserContext
/* eslint-enable init-declarations */

// -- Setup --------------------------------------------------------------------
const emailTest = test.extend<{ library: string }>({
library: ['wagmi', { option: true }]
})

emailTest.describe.configure({ mode: 'serial' })

emailTest.beforeAll(async ({ browser, library }, testInfo) => {
context = await browser.newContext()
const browserPage = await context.newPage()

page = new ModalWalletPage(browserPage, library, 'email')
validator = new ModalWalletValidator(browserPage)

await page.load()

const mailsacApiKey = process.env['MAILSAC_API_KEY']
if (!mailsacApiKey) {
throw new Error('MAILSAC_API_KEY is not set')
}
const email = new Email(mailsacApiKey)
const tempEmail = email.getEmailAddressToUse(testInfo.parallelIndex)
await page.emailFlow(tempEmail, context, mailsacApiKey)

await validator.expectConnected()
})

emailTest.afterAll(async () => {
await page.page.close()
})

testMEmail('it should sign', async ({ modalPage, modalValidator }) => {
await modalPage.sign()
await modalPage.approveSign()
await modalValidator.expectAcceptedSign()
// -- Tests --------------------------------------------------------------------
emailTest('it should sign', async () => {
await page.sign()
await page.approveSign()
await validator.expectAcceptedSign()
})

testMEmail('it should upgrade wallet', async ({ modalPage, context }) => {
const page = await modalPage.clickWalletUpgradeCard(context)
expect(page.url()).toContain(SECURE_WEBSITE_URL)
await page.close()
emailTest('it should upgrade wallet', async () => {
const walletUpgradePage = await page.clickWalletUpgradeCard(context)
expect(walletUpgradePage.url()).toContain(SECURE_WEBSITE_URL)
await walletUpgradePage.close()
await page.closeModal()
})

testMEmail('it should reject sign', async ({ modalPage, modalValidator }) => {
await modalPage.sign()
await modalPage.rejectSign()
await modalValidator.expectRejectedSign()
emailTest('it should reject sign', async () => {
await page.sign()
await page.rejectSign()
await validator.expectRejectedSign()
})

testMEmail('it should switch network and sign', async ({ modalPage, modalValidator }) => {
emailTest('it should switch network and sign', async () => {
let targetChain = 'Polygon'
const walletModalPage = modalPage as ModalWalletPage
const walletModalValidator = modalValidator as ModalWalletValidator
await walletModalPage.openAccount()
await walletModalPage.openProfileView()
await walletModalPage.openSettings()
await walletModalPage.switchNetwork(targetChain)
await walletModalValidator.expectSwitchedNetwork(targetChain)
await walletModalPage.closeModal()
await walletModalPage.sign()
await walletModalPage.approveSign()
await walletModalValidator.expectAcceptedSign()
await page.openAccount()
await page.openProfileView()
await page.openSettings()
await page.switchNetwork(targetChain)
await validator.expectSwitchedNetwork(targetChain)
await page.closeModal()
await page.sign()
await page.approveSign()
await validator.expectAcceptedSign()

targetChain = 'Ethereum'
await walletModalPage.openAccount()
await walletModalPage.openProfileView()
await walletModalPage.openSettings()
await walletModalPage.switchNetwork(targetChain)
await walletModalValidator.expectSwitchedNetwork(targetChain)
await walletModalPage.closeModal()
await walletModalPage.sign()
await walletModalPage.approveSign()
await walletModalValidator.expectAcceptedSign()
})

testMEmail('it should disconnect correctly', async ({ modalPage, modalValidator }) => {
const walletModalPage = modalPage as ModalWalletPage
const walletModalValidator = modalValidator as ModalWalletValidator
await walletModalPage.openAccount()
await walletModalPage.openProfileView()
await walletModalPage.openSettings()
await walletModalPage.disconnect()
await walletModalValidator.expectDisconnected()
await page.openAccount()
await page.openProfileView()
await page.openSettings()
await page.switchNetwork(targetChain)
await validator.expectSwitchedNetwork(targetChain)
await page.closeModal()
await page.sign()
await page.approveSign()
await validator.expectAcceptedSign()
})

emailTest('it should disconnect correctly', async () => {
await page.openAccount()
await page.openProfileView()
await page.openSettings()
await page.disconnect()
await validator.expectDisconnected()
})
Loading

0 comments on commit 02f227a

Please sign in to comment.