diff --git a/apps/walletd-e2e/playwright.config.ts b/apps/walletd-e2e/playwright.config.ts index 6e8b330f8..6883242ca 100644 --- a/apps/walletd-e2e/playwright.config.ts +++ b/apps/walletd-e2e/playwright.config.ts @@ -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 /* { diff --git a/apps/walletd-e2e/src/fixtures/createWallet.ts b/apps/walletd-e2e/src/fixtures/createWallet.ts deleted file mode 100644 index 623ef908b..000000000 --- a/apps/walletd-e2e/src/fixtures/createWallet.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { expect, Page } from '@playwright/test' -import { mockApiWallet, mockApiWallets } from '@siafoundation/walletd-mock' -import { - Wallet, - WalletAddressesResponse, - WalletBalanceResponse, - WalletFundSiacoinResponse, - WalletOutputsSiacoinResponse, -} from '@siafoundation/walletd-types' - -export async function createWallet({ - page, - mnemonic, - newWallet, - responses = {}, - expects = {}, -}: { - page: Page - mnemonic: string - newWallet: Wallet - responses?: { - balance?: WalletBalanceResponse - outputsSiacoin?: WalletOutputsSiacoinResponse - fundSiacoin?: WalletFundSiacoinResponse - addresses?: WalletAddressesResponse - } - expects?: { - fundSiacoinPost?: (data: string | null) => void - } -}) { - const wallets = await mockApiWallets({ page, createWallet: newWallet }) - await mockApiWallet({ - page, - wallet: newWallet, - responses, - expects, - }) - - 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 Generate a' }).click() - await page.locator('input[name=name]').fill(newWallet.name) - await page.locator('input[name=name]').press('Tab') - await page.locator('textarea[name=description]').fill(newWallet.name) - await page.locator('textarea[name=description]').press('Tab') - await page.locator('textarea[name=mnemonic]').click() - wallets.push(newWallet) - await page.getByRole('button', { name: 'Add wallet' }).click() - await expect( - page.getByText(`Wallet ${newWallet.name.slice(0, 5)}`) - ).toBeVisible() - await page.locator('input[name=mnemonic]').fill(mnemonic) - await page.getByRole('button', { name: 'Generate addresses' }).click() -} diff --git a/apps/walletd-e2e/src/fixtures/navigateToWallet.ts b/apps/walletd-e2e/src/fixtures/navigateToWallet.ts index fb6a91bb7..cd790c7e6 100644 --- a/apps/walletd-e2e/src/fixtures/navigateToWallet.ts +++ b/apps/walletd-e2e/src/fixtures/navigateToWallet.ts @@ -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() } diff --git a/apps/walletd-e2e/src/fixtures/textInput.ts b/apps/walletd-e2e/src/fixtures/textInput.ts index 2e0fc736e..d6da3a220 100644 --- a/apps/walletd-e2e/src/fixtures/textInput.ts +++ b/apps/walletd-e2e/src/fixtures/textInput.ts @@ -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( diff --git a/apps/walletd-e2e/src/fixtures/textarea.ts b/apps/walletd-e2e/src/fixtures/textarea.ts new file mode 100644 index 000000000..24be686c8 --- /dev/null +++ b/apps/walletd-e2e/src/fixtures/textarea.ts @@ -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) +} diff --git a/apps/walletd-e2e/src/fixtures/wallet.ts b/apps/walletd-e2e/src/fixtures/wallet.ts new file mode 100644 index 000000000..e36ebb13d --- /dev/null +++ b/apps/walletd-e2e/src/fixtures/wallet.ts @@ -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() +} diff --git a/apps/walletd-e2e/src/specs/login.spec.ts b/apps/walletd-e2e/src/specs/login.spec.ts index 00ec0011e..d64ecccb9 100644 --- a/apps/walletd-e2e/src/specs/login.spec.ts +++ b/apps/walletd-e2e/src/specs/login.spec.ts @@ -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() }) diff --git a/apps/walletd-e2e/src/specs/seedGenerateAddresses.spec.ts b/apps/walletd-e2e/src/specs/seedGenerateAddresses.spec.ts index f427b0e0a..efabdc502 100644 --- a/apps/walletd-e2e/src/specs/seedGenerateAddresses.spec.ts +++ b/apps/walletd-e2e/src/specs/seedGenerateAddresses.spec.ts @@ -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...') @@ -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() diff --git a/apps/walletd-e2e/src/specs/seedSendSiacoin.spec.ts b/apps/walletd-e2e/src/specs/seedSendSiacoin.spec.ts index 385d42fb7..5c1d0b0ae 100644 --- a/apps/walletd-e2e/src/specs/seedSendSiacoin.spec.ts +++ b/apps/walletd-e2e/src/specs/seedSendSiacoin.spec.ts @@ -1,58 +1,26 @@ import { test, expect } from '@playwright/test' import { login } from '../fixtures/login' -import { createWallet } from '../fixtures/createWallet' +import { unlockWallet, walletInList } from '../fixtures/wallet' import { navigateToWallet } from '../fixtures/navigateToWallet' import { fillComposeTransactionSiacoin } from '../fixtures/sendSiacoinDialog' -import { - getMockScenarioSeedWallet, - mockApiDefaults, -} from '@siafoundation/walletd-mock' - -function getDefaultMockWalletResponses( - mocks: ReturnType -) { - return { - fund: mocks.walletFundResponse, - outputsSiacoin: mocks.walletOutputsSiacoinResponse, - addresses: mocks.walletAddressesResponse, - } -} test('send siacoin with a seed wallet', async ({ page }) => { - await mockApiDefaults({ page }) await login({ page }) - const mocks = getMockScenarioSeedWallet() - const { newWallet, mnemonic, receiveAddress, changeAddress } = mocks - await createWallet({ - page, - newWallet, - mnemonic, - responses: getDefaultMockWalletResponses(mocks), - expects: { - fundSiacoinPost: (data) => - expect(data).toEqual( - JSON.stringify({ - amount: '1003930000000000000000000', - changeAddress: mocks.changeAddress, - transaction: { - minerFees: ['3930000000000000000000'], - siacoinOutputs: [ - { - value: '1000000000000000000000000', - address: mocks.receiveAddress, - }, - ], - }, - }) - ), - }, - }) - await navigateToWallet({ page, wallet: newWallet }) + const name = 'test-send-siacoin-seed-wallet' + const receiveAddress = + '5739945c21e60afd70eaf97ccd33ea27836e0219212449f39e4b38acaa8b3119aa4150a9ef0f' + const changeAddress = + '170173c40ca0f39f9618da30af14c390c7ce70248a3662a7a5d3d5a8a31c9fbfa2071e9f6518' + const mnemonic = + 'march wait photo expire sweet hurry photo joy sail certain time beef' + await walletInList(page, name) + await unlockWallet(page, name, mnemonic) + await navigateToWallet(page, name) await page.getByLabel('send').click() await fillComposeTransactionSiacoin({ page, - receiveAddress: mocks.receiveAddress, - changeAddress: mocks.changeAddress, + receiveAddress, + changeAddress, amount: '1', }) await expect(page.getByText('The wallet is currently unlocked')).toBeVisible() @@ -70,222 +38,3 @@ test('send siacoin with a seed wallet', async ({ page }) => { await expect(page.getByText('Total')).toBeVisible() await expect(page.getByText('1.004 SC')).toBeVisible() }) - -test('errors if the input to sign is not found on the transaction', async ({ - page, -}) => { - await mockApiDefaults({ page }) - const mocks = getMockScenarioSeedWallet() - const { newWallet, mnemonic, receiveAddress, changeAddress } = mocks - const mockFundInvalid = mocks.walletFundResponse - mockFundInvalid.transaction.siacoinInputs[0].parentID = - 'scoid:bb3e781330c9b3991e0141807df1327fadf114ca6c37acb9e58004f942d91dfb' - await login({ page }) - await createWallet({ - page, - newWallet, - mnemonic, - responses: { - ...getDefaultMockWalletResponses(mocks), - fundSiacoin: mockFundInvalid, - }, - expects: { - fundSiacoinPost: (data) => - expect(data).toEqual( - JSON.stringify({ - amount: '1003930000000000000000000', - changeAddress: mocks.changeAddress, - transaction: { - minerFees: ['3930000000000000000000'], - siacoinOutputs: [ - { - value: '1000000000000000000000000', - address: mocks.receiveAddress, - }, - ], - }, - }) - ), - }, - }) - await navigateToWallet({ page, wallet: newWallet }) - await page.getByLabel('send').click() - await fillComposeTransactionSiacoin({ - page, - receiveAddress, - changeAddress, - amount: '1', - }) - await expect(page.getByText('The wallet is currently unlocked')).toBeVisible() - await expect(page.getByText('Total')).toBeVisible() - await expect(page.getByText('1.004 SC')).toBeVisible() - - await page - .getByRole('button', { name: 'Sign and broadcast transaction' }) - .click() - await expect(page.getByText('Missing input')).toBeVisible() -}) - -test('errors if the inputs matching utxo is not found', async ({ page }) => { - await mockApiDefaults({ page }) - const mocks = getMockScenarioSeedWallet() - const { newWallet, mnemonic, receiveAddress, changeAddress } = mocks - const mockOutputsInvalid = mocks.walletOutputsSiacoinResponse - mockOutputsInvalid.forEach((output) => { - output.id = 'not the matching id' - }) - await login({ page }) - await createWallet({ - page, - newWallet, - mnemonic: mnemonic, - responses: { - ...getDefaultMockWalletResponses(mocks), - outputsSiacoin: mockOutputsInvalid, - }, - expects: { - fundSiacoinPost: (data) => - expect(data).toEqual( - JSON.stringify({ - amount: '1003930000000000000000000', - changeAddress: mocks.changeAddress, - transaction: { - minerFees: ['3930000000000000000000'], - siacoinOutputs: [ - { - value: '1000000000000000000000000', - address: mocks.receiveAddress, - }, - ], - }, - }) - ), - }, - }) - await navigateToWallet({ page, wallet: newWallet }) - await page.getByLabel('send').click() - await fillComposeTransactionSiacoin({ - page, - receiveAddress, - changeAddress, - amount: '1', - }) - await expect(page.getByText('The wallet is currently unlocked')).toBeVisible() - await expect(page.getByText('Total')).toBeVisible() - await expect(page.getByText('1.004 SC')).toBeVisible() - - await page - .getByRole('button', { name: 'Sign and broadcast transaction' }) - .click() - await expect(page.getByText('Missing utxo')).toBeVisible() -}) - -test('errors if the address is missing its index', async ({ page }) => { - await mockApiDefaults({ page }) - await login({ page }) - - const mocks = getMockScenarioSeedWallet() - const { newWallet, mnemonic, receiveAddress, changeAddress } = mocks - const mockAddressesInvalid = mocks.walletAddressesResponse - mockAddressesInvalid.forEach((address) => { - address.metadata.index = undefined - }) - await createWallet({ - page, - newWallet, - mnemonic: mnemonic, - responses: { - ...getDefaultMockWalletResponses(mocks), - addresses: mockAddressesInvalid, - }, - expects: { - fundSiacoinPost: (data) => - expect(data).toEqual( - JSON.stringify({ - amount: '1003930000000000000000000', - changeAddress: mocks.changeAddress, - transaction: { - minerFees: ['3930000000000000000000'], - siacoinOutputs: [ - { - value: '1000000000000000000000000', - address: mocks.receiveAddress, - }, - ], - }, - }) - ), - }, - }) - await navigateToWallet({ page, wallet: newWallet }) - await page.getByLabel('send').click() - await fillComposeTransactionSiacoin({ - page, - receiveAddress, - changeAddress, - amount: '1', - }) - await expect(page.getByText('The wallet is currently unlocked')).toBeVisible() - await expect(page.getByText('Total')).toBeVisible() - await expect(page.getByText('1.004 SC')).toBeVisible() - - await page - .getByRole('button', { name: 'Sign and broadcast transaction' }) - .click() - await expect(page.getByText('Missing address index')).toBeVisible() -}) - -test('errors if the address is missing its public key', async ({ page }) => { - await mockApiDefaults({ page }) - await login({ page }) - - const mocks = getMockScenarioSeedWallet() - const { newWallet, mnemonic, receiveAddress, changeAddress } = mocks - const mockAddressesInvalid = mocks.walletAddressesResponse - mockAddressesInvalid.forEach((address) => { - address.metadata.unlockConditions.publicKeys[0] = undefined - }) - await createWallet({ - page, - newWallet, - mnemonic: mnemonic, - responses: { - ...getDefaultMockWalletResponses(mocks), - addresses: mockAddressesInvalid, - }, - expects: { - fundSiacoinPost: (data) => - expect(data).toEqual( - JSON.stringify({ - amount: '1003930000000000000000000', - changeAddress: mocks.changeAddress, - transaction: { - minerFees: ['3930000000000000000000'], - siacoinOutputs: [ - { - value: '1000000000000000000000000', - address: mocks.receiveAddress, - }, - ], - }, - }) - ), - }, - }) - await navigateToWallet({ page, wallet: newWallet }) - await page.getByLabel('send').click() - await fillComposeTransactionSiacoin({ - page, - receiveAddress, - changeAddress, - amount: '1', - }) - await expect(page.getByText('The wallet is currently unlocked')).toBeVisible() - await expect(page.getByText('Total')).toBeVisible() - await expect(page.getByText('1.004 SC')).toBeVisible() - - await page - .getByRole('button', { name: 'Sign and broadcast transaction' }) - .click() - await expect(page.getByText('Missing address public key')).toBeVisible() -}) diff --git a/apps/walletd-e2e/src/specs/wallet.spec.ts b/apps/walletd-e2e/src/specs/wallet.spec.ts new file mode 100644 index 000000000..1c7f1ebdf --- /dev/null +++ b/apps/walletd-e2e/src/specs/wallet.spec.ts @@ -0,0 +1,42 @@ +import { test, expect } from '@playwright/test' +import { login } from '../fixtures/login' +import { + createNewWallet, + deleteWalletIfExists, + recoverWallet, + walletInList, +} from '../fixtures/wallet' +import { navigateToWallet } from '../fixtures/navigateToWallet' + +test('create new seed wallet', async ({ page, context }) => { + const name = 'my-new-seed-wallet' + await login({ page }) + await deleteWalletIfExists(page, name) + await createNewWallet(page, context, name) + await expect(page.getByRole('table').getByText(name).first()).toBeVisible() + await page.getByRole('table').getByText(name).first().click() + await expect(page.getByText('The wallet has no')).toBeVisible() + await expect(page.getByRole('link', { name: 'Addresses' })).toBeVisible() +}) + +test('recover wallet and see existing transactions', async ({ + page, + context, +}) => { + const name = 'my-existing-wallet' + await login({ page }) + await deleteWalletIfExists(page, name) + const mnemonic = + 'kite best great glance better spy core rigid angle mind man net' + await recoverWallet(page, context, name, mnemonic) + await walletInList(page, name) + await navigateToWallet(page, name) + const row1 = page.getByRole('row', { name: '9e8d82a3e590' }) + await expect(row1.getByText('6/12/24')).toBeVisible() + await expect(row1.getByText('transaction')).toBeVisible() + await expect(row1.getByText('+110.000 SC')).toBeVisible() + const row2 = page.getByRole('row', { name: '4bbbfcce2f1f' }) + await expect(row2.getByText('transaction')).toBeVisible() + await expect(row2.getByText('6/11/24')).toBeVisible() + await expect(row2.getByText('+300.000 SC')).toBeVisible() +}) diff --git a/apps/walletd-e2e/src/specs/walletCreate.spec.ts b/apps/walletd-e2e/src/specs/walletCreate.spec.ts deleted file mode 100644 index 548132c2d..000000000 --- a/apps/walletd-e2e/src/specs/walletCreate.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { test, expect } from '@playwright/test' -import { login } from '../fixtures/login' -import { createWallet } from '../fixtures/createWallet' -import { - getMockScenarioSeedWallet, - mockApiDefaults, -} from '@siafoundation/walletd-mock' - -test('wallet create', async ({ page }) => { - const mocks = getMockScenarioSeedWallet() - const { newWallet, mnemonic } = mocks - await mockApiDefaults({ page }) - await login({ page }) - await createWallet({ page, newWallet, mnemonic }) - await expect(page.locator(`span:text('${newWallet.name}')`)).toBeVisible() - await page.locator(`span:text('${newWallet.name}')`).click() - await expect(page.getByText('The wallet has no')).toBeVisible() - await expect(page.getByRole('link', { name: 'Addresses' })).toBeVisible() -}) diff --git a/apps/walletd/components/WalletContextMenu.tsx b/apps/walletd/components/WalletContextMenu.tsx index d6a0d994f..788adeed7 100644 --- a/apps/walletd/components/WalletContextMenu.tsx +++ b/apps/walletd/components/WalletContextMenu.tsx @@ -29,6 +29,7 @@ export function WalletContextMenu({ {metadata.type === 'seed' ? ( state.status === 'unlocked' ? ( e.stopPropagation()} onSelect={() => actions.lock()} > diff --git a/apps/walletd/contexts/events/types.ts b/apps/walletd/contexts/events/types.ts index 1365426c8..a414f2ee5 100644 --- a/apps/walletd/contexts/events/types.ts +++ b/apps/walletd/contexts/events/types.ts @@ -22,6 +22,7 @@ export type EventData = { export type TableColumnId = // | 'actions' + | 'id' | 'transactionId' | 'type' | 'height' @@ -33,6 +34,7 @@ export type TableColumnId = export const columnsDefaultVisible: TableColumnId[] = [ // 'actions', + 'id', 'transactionId', 'type', 'height',