Skip to content

Commit

Permalink
refactor: walletd e2e tests
Browse files Browse the repository at this point in the history
  • Loading branch information
alexfreska committed Jun 12, 2024
1 parent 6ae66f3 commit 4e6d0df
Show file tree
Hide file tree
Showing 13 changed files with 230 additions and 414 deletions.
19 changes: 11 additions & 8 deletions apps/walletd-e2e/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,24 @@ export default defineConfig({
reuseExistingServer: !process.env.CI,
cwd: workspaceRoot,
},
// Run the tests serially as they may mutate the state of the same application.
workers: 1,
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},

{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
// Disable firefox and webkit to save time since tests are running serially.
// {
// name: 'firefox',
// use: { ...devices['Desktop Firefox'] },
// },

{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
// {
// name: 'webkit',
// use: { ...devices['Desktop Safari'] },
// },

// Uncomment for mobile browsers support
/* {
Expand Down
54 changes: 0 additions & 54 deletions apps/walletd-e2e/src/fixtures/createWallet.ts

This file was deleted.

15 changes: 5 additions & 10 deletions apps/walletd-e2e/src/fixtures/navigateToWallet.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import { Page } from '@playwright/test'
import { Wallet } from '@siafoundation/walletd-types'
import { Page, expect } from '@playwright/test'
import { openWallet } from './wallet'

export async function navigateToWallet({
page,
wallet,
}: {
page: Page
wallet: Wallet
}) {
export async function navigateToWallet(page: Page, name: string) {
await page.getByLabel('Dashboard').click()
await page.getByText(wallet.name).click()
await openWallet(page, name)
await expect(page.getByTestId('navbar').getByText(name)).toBeVisible()
}
6 changes: 5 additions & 1 deletion apps/walletd-e2e/src/fixtures/textInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ import { Page, expect } from '@playwright/test'
export async function fillTextInputByName(
page: Page,
name: string,
value: string
value: string,
tabAfterFill = false
) {
await page.locator(`input[name="${name}"]`).click()
await page.locator(`input[name="${name}"]`).fill(value)
if (tabAfterFill) {
await page.locator(`input[name="${name}"]`).press('Tab')
}
}

export async function expectTextInputByName(
Expand Down
38 changes: 38 additions & 0 deletions apps/walletd-e2e/src/fixtures/textarea.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Page, expect } from '@playwright/test'

export async function clickTextareaByName(page: Page, name: string) {
await page.locator(`textarea[name="${name}"]`).click()
}

export async function fillTextareaByName(
page: Page,
name: string,
value: string,
tabAfterFill = false
) {
await page.locator(`textarea[name="${name}"]`).click()
await page.locator(`textarea[name="${name}"]`).fill(value)
if (tabAfterFill) {
await page.locator(`textarea[name="${name}"]`).press('Tab')
}
}

export async function expectTextareaByName(
page: Page,
name: string,
value: string
) {
await expect(page.locator(`textarea[name="${name}"]`)).toHaveValue(value)
}

export async function expectTextareaNotVisible(page: Page, name: string) {
await expect(page.locator(`textarea[name="${name}"]`)).toBeHidden()
}

export async function expectTextareaByNameAttribute(
page: Page,
name: string,
value: string
) {
await expect(page.locator(`textarea[name="${name}"]`)).toHaveAttribute(value)
}
86 changes: 86 additions & 0 deletions apps/walletd-e2e/src/fixtures/wallet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { BrowserContext, expect, Page } from '@playwright/test'
import { fillTextInputByName } from './textInput'
import { clickTextareaByName, fillTextareaByName } from './textarea'

export async function createNewWallet(
page: Page,
context: BrowserContext,
name: string
) {
await context.grantPermissions(['clipboard-read', 'clipboard-write'])
await expect(page.getByRole('button', { name: 'Add wallet' })).toBeVisible()
await page.getByRole('button', { name: 'Add wallet' }).click()
await page.getByRole('button', { name: 'Create a wallet' }).click()
await fillTextInputByName(page, 'name', name, true)
await fillTextareaByName(page, 'description', name, true)
await clickTextareaByName(page, 'mnemonic')
const cb = await page.evaluateHandle(() => navigator.clipboard.readText())
const mnemonic = await cb.jsonValue()
await page.getByRole('button', { name: 'Add wallet' }).click()
await expect(page.getByText(`Wallet ${name.slice(0, 5)}`)).toBeVisible()
await fillTextInputByName(page, 'mnemonic', mnemonic)
await page.getByRole('button', { name: 'Generate addresses' }).click()
}

export async function recoverWallet(
page: Page,
context: BrowserContext,
name: string,
mnemonic: string
) {
await context.grantPermissions(['clipboard-read', 'clipboard-write'])
await expect(page.getByRole('button', { name: 'Add wallet' })).toBeVisible()
await page.getByRole('button', { name: 'Add wallet' }).click()
await page.getByRole('button', { name: 'Recover a wallet' }).click()
await fillTextInputByName(page, 'name', name, true)
await fillTextareaByName(page, 'description', name, true)
await fillTextareaByName(page, 'mnemonic', mnemonic, true)
await page.getByRole('button', { name: 'Add wallet' }).click()
await expect(page.getByText(`Wallet ${name.slice(0, 5)}`)).toBeVisible()
await fillTextInputByName(page, 'mnemonic', mnemonic)
await page.getByRole('button', { name: 'Generate addresses' }).click()
}

export async function deleteWallet(page: Page, name: string) {
await openWalletContextMenu(page, name)
await page.getByRole('menuitem', { name: 'Delete wallet' }).click()
await fillTextInputByName(page, 'name', name)
await page.locator('input[name=name]').press('Enter')
await expect(page.getByRole('dialog')).toBeHidden()
await walletNotInList(page, name)
}

export async function unlockWallet(page: Page, name: string, mnemonic: string) {
await openWalletContextMenu(page, name)
await page.getByRole('menuitem', { name: 'Unlock wallet' }).click()
await fillTextInputByName(page, 'mnemonic', mnemonic)
await page.locator('input[name=mnemonic]').press('Enter')
await expect(page.getByRole('dialog')).toBeHidden()
}

export async function deleteWalletIfExists(page: Page, name: string) {
const doesWalletExist = await page
.getByRole('table')
.getByText(name)
.first()
.isVisible()
if (doesWalletExist) {
await deleteWallet(page, name)
}
}

export async function openWallet(page: Page, name: string) {
await page.getByRole('table').getByText(name).first().click()
}

export async function openWalletContextMenu(page: Page, name: string) {
await page.getByRole('row', { name }).getByRole('button').first().click()
}

export async function walletInList(page: Page, name: string) {
await expect(page.getByRole('table').getByText(name).first()).toBeVisible()
}

export async function walletNotInList(page: Page, name: string) {
await expect(page.getByRole('table').getByText(name).first()).toBeHidden()
}
4 changes: 1 addition & 3 deletions apps/walletd-e2e/src/specs/login.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { test, expect } from '@playwright/test'
import { mockApiDefaults } from '@siafoundation/walletd-mock'
import { login } from '../fixtures/login'

test('login', async ({ page }) => {
await mockApiDefaults({ page })
await login({ page })
await expect(page.getByRole('button', { name: 'Add wallet' })).toBeVisible()
await expect(page.getByTestId('navbar').getByText('Wallets')).toBeVisible()
})
81 changes: 26 additions & 55 deletions apps/walletd-e2e/src/specs/seedGenerateAddresses.spec.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,22 @@
import { test, expect } from '@playwright/test'
import { login } from '../fixtures/login'
import { createWallet } from '../fixtures/createWallet'
import { deleteWalletIfExists, recoverWallet } from '../fixtures/wallet'
import { navigateToWallet } from '../fixtures/navigateToWallet'
import {
getMockScenarioSeedWallet,
mockApiDefaults,
getMockRescanResponse,
} from '@siafoundation/walletd-mock'
import { WalletAddressesResponse } from '@siafoundation/walletd-types'
import { fillTextInputByName } from '../fixtures/textInput'

function getMockWalletAddressesResponse(): WalletAddressesResponse {
return []
}
test('generate new addresses', async ({ page, context }) => {
const name = 'my-existing-wallet'
const mnemonic =
'ridge business wish transfer home glove office salt wealth baby journey diary'

function getDefaultMockWalletResponses() {
return {
addresses: getMockWalletAddressesResponse(),
}
}

test('generate new addresses', async ({ page }) => {
const rescanResponse = getMockRescanResponse()
await mockApiDefaults({
page,
responses: {
rescan: rescanResponse,
},
})
await login({ page })
await deleteWalletIfExists(page, name)

const mocks = getMockScenarioSeedWallet()
const { newWallet, mnemonic } = mocks
await createWallet({
page,
newWallet,
mnemonic,
responses: getDefaultMockWalletResponses(),
})
await navigateToWallet({ page, wallet: newWallet })
await recoverWallet(page, context, name, mnemonic)
await navigateToWallet(page, name)
await page.getByLabel('view addresses').click()
await page.getByRole('button', { name: 'Add addresses' }).click()
await page.locator('input[name=count]').fill('5')
await fillTextInputByName(page, 'count', '5')
await page.getByRole('button', { name: 'Generate addresses' }).click()
await expect(
page.getByText('65b40f6a720352ad5b9546b9f5077209672914cc...')
Expand All @@ -59,33 +35,28 @@ test('generate new addresses', async ({ page }) => {
).toBeVisible()
})

test('generate new addresses and rescan', async ({ page }) => {
const rescanResponse = getMockRescanResponse()
await mockApiDefaults({
page,
responses: {
rescan: rescanResponse,
},
})
test('generate new addresses and rescan', async ({ page, context }) => {
const name = 'my-existing-wallet'
const mnemonic =
'ridge business wish transfer home glove office salt wealth baby journey diary'

await login({ page })
await deleteWalletIfExists(page, name)

const mocks = getMockScenarioSeedWallet()
const { newWallet, mnemonic } = mocks
await createWallet({
page,
newWallet,
mnemonic,
responses: getDefaultMockWalletResponses(),
})
await navigateToWallet({ page, wallet: newWallet })
await recoverWallet(page, context, name, mnemonic)
await navigateToWallet(page, name)
await page.getByLabel('view addresses').click()
await page.getByRole('button', { name: 'Add addresses' }).click()
await page.locator('input[name=count]').fill('5')
await fillTextInputByName(page, 'count', '5')
await page.getByLabel('shouldRescan').click()
await expect(page.locator('input[name=rescanStartHeight]')).toHaveValue(
'61,676'
const val = await page.locator('input[name=rescanStartHeight]').inputValue()
const defaultRescanStartHeight = Number(val.replace(/,/g, ''))
expect(defaultRescanStartHeight).toBeGreaterThan(60_000)
await fillTextInputByName(
page,
'rescanStartHeight',
String(defaultRescanStartHeight - 500)
)
rescanResponse.index.height = 30_000
await page
.getByRole('button', { name: 'Generate addresses and rescan' })
.click()
Expand Down
Loading

0 comments on commit 4e6d0df

Please sign in to comment.