Skip to content

Commit

Permalink
feat(ui-test): connect flow
Browse files Browse the repository at this point in the history
  • Loading branch information
arein committed Dec 19, 2023
1 parent 15b8719 commit 4b9d092
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 2 deletions.
14 changes: 14 additions & 0 deletions apps/laboratory/tests/connect.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { DEFAULT_SESSION_PARAMS } from './shared/constants'
import { testMW } from './shared/fixtures/w3m-wallet-fixture'

// Initialize the connection
testMW.beforeEach(async ({ modalPage, walletPage }) => {
await modalPage.getWalletConnectV2Uri() // Copies to clopboard

Check failure on line 6 in apps/laboratory/tests/connect.spec.ts

View workflow job for this annotation

GitHub Actions / code_style (lint)

Expected comment to be above code

Check failure on line 6 in apps/laboratory/tests/connect.spec.ts

View workflow job for this annotation

GitHub Actions / code_style (lint)

Unexpected comment inline with code
await walletPage.connect()
await walletPage.handleSessionProposal(DEFAULT_SESSION_PARAMS)
})

testMW('Should connect', async ({ modalValidator, walletValidator }) => {
await modalValidator.expectConnected()
await walletValidator.expectConnected()
})
8 changes: 8 additions & 0 deletions apps/laboratory/tests/shared/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
import type { SessionParams } from '../types'

// Allow localhost
export const LOCAL_LABS_URL = 'http://localhost:3000/library/wagmi/'
export const WALLET_URL = 'https://react-wallet.walletconnect.com/'
export const DEFAULT_SESSION_PARAMS: SessionParams = {
reqAccounts: ['1', '2'],
optAccounts: ['1', '2'],
accept: true
}
6 changes: 6 additions & 0 deletions apps/laboratory/tests/shared/fixtures/w3m-fixture.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { test as base } from '@playwright/test'
import { ModalPage } from '../pages/ModalPage'
import { ModalValidator } from '../validators/ModalValidator'

// Declare the types of fixtures to use
interface ModalFixture {
modalPage: ModalPage
modalValidator: ModalValidator
}

// M -> test Modal
Expand All @@ -12,6 +14,10 @@ export const testM = base.extend<ModalFixture>({
const modalPage = new ModalPage(page)
await modalPage.load()
await use(modalPage)
},
modalValidator: async ({ modalPage }, use) => {
const modalValidator = new ModalValidator(modalPage.page)
await use(modalValidator)
}
})
export { expect } from '@playwright/test'
29 changes: 29 additions & 0 deletions apps/laboratory/tests/shared/fixtures/w3m-wallet-fixture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { testM as base } from './w3m-fixture'
import { WalletPage } from '../pages/WalletPage'
import { WalletValidator } from '../validators/WalletValidator'

// Declare the types of fixtures to use
interface ModalWalletFixture {
walletPage: WalletPage
walletValidator: WalletValidator
}

// MW -> test Modal + Wallet
export const testMW = base.extend<ModalWalletFixture>({
walletPage: async ({ context, browserName }, use) => {
// WalletPage needs clipboard permissions with chromium to paste URI
if (browserName === 'chromium') {
await context.grantPermissions(['clipboard-read', 'clipboard-write'])
}

// Use a new page, to open alongside the modal
const walletPage = new WalletPage(await context.newPage())
await walletPage.load()
await use(walletPage)
},
walletValidator: async ({ walletPage }, use) => {
const walletValidator = new WalletValidator(walletPage.page)
await use(walletValidator)
}
})
export { expect } from '@playwright/test'
15 changes: 13 additions & 2 deletions apps/laboratory/tests/shared/pages/ModalPage.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import type { Page } from '@playwright/test'
import type { Locator, Page } from '@playwright/test'
import { LOCAL_LABS_URL } from '../constants'

export class ModalPage {
private readonly baseURL = LOCAL_LABS_URL

constructor(public readonly page: Page) {}
private readonly connectButton: Locator

constructor(public readonly page: Page) {
this.connectButton = this.page.getByText('Connect Wallet')
}

async load() {
await this.page.goto(this.baseURL)
}

async getWalletConnectV2Uri() {
await this.page.goto(this.baseURL)
await this.connectButton.click()
await this.page.getByText('WalletConnect').click()
await this.page.getByText('Copy link').click()
}
}
67 changes: 67 additions & 0 deletions apps/laboratory/tests/shared/pages/WalletPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* eslint-disable no-await-in-loop */
import type { Locator, Page } from '@playwright/test'
import { WALLET_URL } from '../constants'
import type { SessionParams } from '../types'

export class WalletPage {
private readonly baseURL = WALLET_URL

private readonly gotoAccounts: Locator

private readonly gotoSessions: Locator

private readonly gotoHome: Locator

private readonly gotoPairings: Locator

private readonly gotoSettings: Locator

constructor(public readonly page: Page) {
this.gotoAccounts = this.page.getByTestId('accounts')
this.gotoSessions = this.page.getByTestId('sessions')
this.gotoHome = this.page.getByTestId('wc-connect')
this.gotoPairings = this.page.getByTestId('pairings')
this.gotoSettings = this.page.getByTestId('settings')
}

async load() {
await this.page.goto(this.baseURL)
}

async connect() {
await this.gotoHome.click()

await this.page.getByTestId('uri-input').click()

// Paste clipboard
const isMac = process.platform === 'darwin'
const modifier = isMac ? 'Meta' : 'Control'
await this.page.keyboard.press(`${modifier}+KeyV`)

await this.page.getByTestId('uri-connect-button').click()
}

async disconnect() {
await this.gotoSessions.click()
const sessionCard = this.page.getByTestId('session-card').first()
await sessionCard.getByTestId('session-icon').click()
await this.page.getByTestId('session-delete-button').click()
}

/**
* Handle a session proposal event in the wallet
* @param reqAccounts - required account numbers to select ex/ ['1', '2']
* @param optAccounts - optional account numbers to select ex/ ['1', '2']
* @param accept - accept or reject the session
*/
async handleSessionProposal(opts: SessionParams) {
const meh = opts.accept ? `approve` : `reject`
await this.page.getByTestId(`session-${meh}-button`).focus()
await this.page.keyboard.press('Space')
}

async handleRequest({ accept }: { accept: boolean }) {
const meh = accept ? `approve` : `reject`
await this.page.getByTestId(`request-button-${meh}`).click()
}
}
5 changes: 5 additions & 0 deletions apps/laboratory/tests/shared/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface SessionParams {
reqAccounts: string[]
optAccounts: string[]
accept: boolean
}
10 changes: 10 additions & 0 deletions apps/laboratory/tests/shared/validators/ModalValidator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { expect } from '@playwright/test'
import type { Page } from '@playwright/test'

export class ModalValidator {
constructor(public readonly page: Page) {}

async expectConnected() {
await expect(this.page.getByText('Sign Message')).toBeVisible()
}
}
47 changes: 47 additions & 0 deletions apps/laboratory/tests/shared/validators/WalletValidator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { expect } from '@playwright/test'
import type { Locator, Page } from '@playwright/test'
import { WALLET_URL } from '../constants'

export class WalletValidator {
private readonly baseURL = WALLET_URL

private readonly gotoAccounts: Locator

private readonly gotoSessions: Locator

private readonly gotoHome: Locator

private readonly gotoPairings: Locator

private readonly gotoSettings: Locator

constructor(public readonly page: Page) {
this.gotoAccounts = this.page.getByTestId('accounts')
this.gotoSessions = this.page.getByTestId('sessions')
this.gotoHome = this.page.getByTestId('wc-connect')
this.gotoPairings = this.page.getByTestId('pairings')
this.gotoSettings = this.page.getByTestId('settings')
}

async expectConnected() {
await this.page.reload()
await this.gotoSessions.click()
await expect(this.page.getByTestId('session-card')).toBeVisible()
}

async expectDisconnected() {
await this.page.reload()
await this.gotoSessions.click()
await expect(this.page.getByTestId('session-card')).not.toBeVisible()
}

async expectRecievedSign({ chainName = 'Ethereum' }) {
await expect(this.page.getByText('Sign Message')).toBeVisible()
await expect(this.page.getByTestId('request-details-chain')).toHaveText(chainName)
}

async expectRecievedSignTyped({ chainName = 'Ethereum' }) {
await expect(this.page.getByText('Sign Typed Data')).toBeVisible()
await expect(this.page.getByTestId('request-details-chain')).toHaveText(chainName)
}
}

0 comments on commit 4b9d092

Please sign in to comment.