diff --git a/packages/suite-desktop-core/e2e/snapshots/web/wallet/send-doge.test.ts/send-doge-confirmed.png b/packages/suite-desktop-core/e2e/snapshots/web/wallet/send-doge.test.ts/send-doge-confirmed.png new file mode 100644 index 00000000000..214f8f77113 Binary files /dev/null and b/packages/suite-desktop-core/e2e/snapshots/web/wallet/send-doge.test.ts/send-doge-confirmed.png differ diff --git a/packages/suite-desktop-core/e2e/snapshots/web/wallet/send-doge.test.ts/send-doge.png b/packages/suite-desktop-core/e2e/snapshots/web/wallet/send-doge.test.ts/send-doge.png new file mode 100644 index 00000000000..33cdcee99bf Binary files /dev/null and b/packages/suite-desktop-core/e2e/snapshots/web/wallet/send-doge.test.ts/send-doge.png differ diff --git a/packages/suite-desktop-core/e2e/support/fixtures.ts b/packages/suite-desktop-core/e2e/support/fixtures.ts index dec643bf528..0c4e885d802 100644 --- a/packages/suite-desktop-core/e2e/support/fixtures.ts +++ b/packages/suite-desktop-core/e2e/support/fixtures.ts @@ -29,7 +29,8 @@ import { RecoveryActions } from './pageActions/recoveryActions'; import { TrezorInputActions } from './pageActions/trezorInputActions'; import { MarketActions } from './pageActions/marketActions'; import { AssetsActions } from './pageActions/assetsActions'; -import { MetadataProviderMocks } from './metadataProviderMocks'; +import { MetadataProviderMock } from './mocks/metadataProviderMock'; +import { BlockbookMock } from './mocks/blockBookMock'; import { MetadataActions } from './pageActions/metadataActions'; type StartEmuModelRequired = StartEmu & { model: Model }; @@ -57,7 +58,8 @@ type Fixtures = { trezorInput: TrezorInputActions; analytics: AnalyticsFixture; indexedDb: IndexedDbFixture; - metadataProviderMocks: MetadataProviderMocks; + metadataProviderMock: MetadataProviderMock; + blockbookMock: BlockbookMock; }; const test = base.extend({ @@ -204,9 +206,14 @@ const test = base.extend({ const indexedDb = new IndexedDbFixture(page); await use(indexedDb); }, - metadataProviderMocks: async ({ page }, use) => { - const metadataProviderMocks = new MetadataProviderMocks(page); - await use(metadataProviderMocks); + metadataProviderMock: async ({ page }, use) => { + const metadataProviderMock = new MetadataProviderMock(page); + await use(metadataProviderMock); + }, + /* eslint-disable-next-line no-empty-pattern */ + blockbookMock: async ({}, use) => { + const blockbookMock = new BlockbookMock(); + await use(blockbookMock); }, }); diff --git a/packages/suite-desktop-core/e2e/support/mocks/blockBookMock.ts b/packages/suite-desktop-core/e2e/support/mocks/blockBookMock.ts new file mode 100644 index 00000000000..39c26d3cf70 --- /dev/null +++ b/packages/suite-desktop-core/e2e/support/mocks/blockBookMock.ts @@ -0,0 +1,31 @@ +import { BackendWebsocketServerMock } from '@trezor/e2e-utils'; + +import { step } from '../common'; +import { fixtures as dogeFixtures } from './doge-endpoints'; +import { fixtures as ltcFixtures } from './ltc-mimble-wimble-endpoints'; + +export class BlockbookMock { + private mockServer: BackendWebsocketServerMock | undefined; + + get url() { + if (!this.mockServer) { + throw new Error('Blockbook mock not initialized'); + } + + return `ws://localhost:${this.mockServer.options.port}`; + } + + @step() + async start(type: 'ltc' | 'doge') { + this.mockServer = await BackendWebsocketServerMock.create('blockbook'); + const fixtures = type === 'ltc' ? ltcFixtures : dogeFixtures; + this.mockServer.setFixtures(fixtures); + } + + @step() + stop() { + if (this.mockServer) { + this.mockServer.stop(); + } + } +} diff --git a/packages/suite-desktop-core/e2e/support/mocks/doge-endpoints.ts b/packages/suite-desktop-core/e2e/support/mocks/doge-endpoints.ts new file mode 100644 index 00000000000..e17e33b8ac8 --- /dev/null +++ b/packages/suite-desktop-core/e2e/support/mocks/doge-endpoints.ts @@ -0,0 +1,225 @@ +const PREV_TX = { + txid: '3796497830e70bbf60fbdd8f9570ed53851df6e3d7a34fb1eff2119caf03616d', + version: 1, + vin: [ + { + txid: 'adf4a7fc64379932db9690c6f28a731e3322df9cc1311d09a742f407cf3396c6', + sequence: 4294967295, + n: 0, + addresses: ['DN1ZMYxicfqLqRWcgftsS2iTAUhmLzcDKK'], + isAddress: true, + value: '1000000000', + hex: '47304402207cecdcab4b1c631bbed8da9776c91d5fff3e1afde9e91bfa44e7decffbd8331c022036fec7707d5371a2346ebb52d0ce2805ce6409439b8d6338b05b2c1df485b10f012102960563167bea073f7979cfe5525ca3a24655d3560894f577ab452e19216eda87', + }, + ], + vout: [ + { + value: '11556856856844445555', + n: 0, + hex: '76a9148ae3fead7569f965e334788cc40176b3ecee571588ac', + addresses: ['DHoUv6AUXrxadt5GhqK2TLN6Lw4bgKZnjG'], + isAddress: true, + }, + ], + blockHash: 'deadfea6fa7eaee8568f5ef04c4ea0b1b2c47e08299ec6fd4c45fb4b89792088', + blockHeight: 4484551, + confirmations: 79, + blockTime: 1669212266, + value: '11556856856844445555', + valueIn: '1000000000', + fees: '19200', + hex: '0100000001c69633cf07f442a7091d31c19cdf22331e738af2c69096db32993764fca7f4ad000000006a47304402207cecdcab4b1c631bbed8da9776c91d5fff3e1afde9e91bfa44e7decffbd8331c022036fec7707d5371a2346ebb52d0ce2805ce6409439b8d6338b05b2c1df485b10f012102960563167bea073f7979cfe5525ca3a24655d3560894f577ab452e19216eda87ffffffff01007f9a3b000000001976a9148ae3fead7569f965e334788cc40176b3ecee571588ac00000000', +}; + +const DOGE_ACCOUNT = { + data: { + page: 1, + totalPages: 1, + itemsOnPage: 25, + address: + 'dgub8rE9bgXY9DuS9fvhBMshxu6auWGdAcD9P6weqZrqnLx13edD963SB3kjHBTWYWBWErhpLW9SkopNwx7zLdvDt1nySVb8qj8zR95iH4578JN', + balance: '11556856856844445555', + totalReceived: '11556856856844445555', + totalSent: '0', + unconfirmedBalance: '0', + unconfirmedTxs: 0, + txs: 1, + transactions: [ + { + txid: '3796497830e70bbf60fbdd8f9570ed53851df6e3d7a34fb1eff2119caf03616d', + version: 1, + vin: [ + { + txid: 'adf4a7fc64379932db9690c6f28a731e3322df9cc1311d09a742f407cf3396c6', + sequence: 4294967295, + n: 0, + addresses: ['DN1ZMYxicfqLqRWcgftsS2iTAUhmLzcDKK'], + isAddress: true, + value: '1000000000', + hex: '47304402207cecdcab4b1c631bbed8da9776c91d5fff3e1afde9e91bfa44e7decffbd8331c022036fec7707d5371a2346ebb52d0ce2805ce6409439b8d6338b05b2c1df485b10f012102960563167bea073f7979cfe5525ca3a24655d3560894f577ab452e19216eda87', + }, + ], + vout: [ + { + value: '11556856856844445555', + n: 0, + hex: '76a9148ae3fead7569f965e334788cc40176b3ecee571588ac', + addresses: ['DHoUv6AUXrxadt5GhqK2TLN6Lw4bgKZnjG'], + isAddress: true, + isOwn: true, + }, + ], + blockHash: 'deadfea6fa7eaee8568f5ef04c4ea0b1b2c47e08299ec6fd4c45fb4b89792088', + blockHeight: 4484551, + confirmations: 16, + blockTime: 1669212266, + value: '11556856856844445555', + valueIn: '1000000000', + fees: '19200', + hex: '0100000001c69633cf07f442a7091d31c19cdf22331e738af2c69096db32993764fca7f4ad000000006a47304402207cecdcab4b1c631bbed8da9776c91d5fff3e1afde9e91bfa44e7decffbd8331c022036fec7707d5371a2346ebb52d0ce2805ce6409439b8d6338b05b2c1df485b10f012102960563167bea073f7979cfe5525ca3a24655d3560894f577ab452e19216eda87ffffffff01007f9a3b000000001976a9148ae3fead7569f965e334788cc40176b3ecee571588ac00000000', + }, + ], + usedTokens: 1, + tokens: [ + { + type: 'XPUBAddress', + name: 'DHoUv6AUXrxadt5GhqK2TLN6Lw4bgKZnjG', + path: "m/44'/3'/0'/0/0", + transfers: 1, + decimals: 8, + balance: '11556856856844445555', + totalReceived: '11556856856844445555', + totalSent: '0', + }, + { + type: 'XPUBAddress', + name: 'DBNkNukxRcH6QTPSp69KhVHQWkUpVLotWs', + path: "m/44'/3'/0'/0/1", + transfers: 0, + decimals: 8, + }, + { + type: 'XPUBAddress', + name: 'DCsP6RCfFHvTKFRocJEoW1CjYEPMk9pk3i', + path: "m/44'/3'/0'/1/0", + transfers: 0, + decimals: 8, + }, + { + type: 'XPUBAddress', + name: 'DMRZ3D9ppogDQoY7AUCLy5EaRTTEv6xJ5f', + path: "m/44'/3'/0'/1/1", + transfers: 0, + decimals: 8, + }, + ], + }, +}; + +const isFirstAccount = (descriptor: string) => descriptor === DOGE_ACCOUNT.data.address; + +export const fixtures = [ + { + method: 'getInfo', + default: true, + response: { + data: { + name: 'DogecoinMock', + shortcut: 'DOGE', + decimals: 8, + version: '0.3.6', + bestHeight: 4484566, + bestHash: '38fbb073e7eb4bfac9ed485dd0b3212247fb2a3d8b509dc9738c01a86ede33b3', + block0Hash: '1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691', + network: 'DOGE', + testnet: false, + backend: { version: '1140600', subversion: '/Shibetoshi:1.14.6/' }, + }, + }, + }, + { + method: 'getAccountInfo', + default: true, + response: ({ params }: any) => { + if (isFirstAccount(params.descriptor)) { + return DOGE_ACCOUNT; + } + }, + }, + { + method: 'getAccountUtxo', + default: true, + response: { + data: [ + { + txid: PREV_TX.txid, + vout: 0, + value: '11556856856844445555', + height: 4484551, + confirmations: 16, + address: 'DHoUv6AUXrxadt5GhqK2TLN6Lw4bgKZnjG', + path: "m/44'/3'/0'/0/0", + }, + ], + }, + }, + { + method: 'getBalanceHistory', + default: true, + response: { + data: [ + { + time: 1669161600, + txs: 1, + received: '11556856856844445555', + sent: '0', + sentToSelf: '0', + rates: { usd: 0.078881 }, + }, + ], + }, + }, + { + method: 'estimateFee', + default: true, + response: { + data: [ + { feePerUnit: '-100000000' }, + { feePerUnit: '6418769' }, + { feePerUnit: '1003782' }, + { feePerUnit: '1003782' }, + { feePerUnit: '1003782' }, + { feePerUnit: '1003782' }, + { feePerUnit: '1003782' }, + { feePerUnit: '1003782' }, + { feePerUnit: '1003782' }, + { feePerUnit: '1003782' }, + ], + }, + }, + { + method: 'getFiatRatesForTimestamps', + default: true, + response: { + data: { + tickers: [ + { + ts: 1668608419, + rates: { + usd: 0.085339, + }, + }, + ], + }, + }, + }, + { + method: 'getTransaction', + default: true, + response: ({ params }: any) => { + if (params?.txid === PREV_TX.txid) { + return { data: PREV_TX }; + } + }, + }, +]; diff --git a/packages/suite-desktop-core/e2e/support/mocks/ltc-mimble-wimble-endpoints.ts b/packages/suite-desktop-core/e2e/support/mocks/ltc-mimble-wimble-endpoints.ts new file mode 100644 index 00000000000..cd7ac424061 --- /dev/null +++ b/packages/suite-desktop-core/e2e/support/mocks/ltc-mimble-wimble-endpoints.ts @@ -0,0 +1,159 @@ +const PREV_TX = { + txid: 'efe11e0d8d562e73b7795c2a3b7e44c6b6390f2c42c3ae90bb1005009c27a3f3', + version: 2, + vin: [ + { + txid: '5961c1187b435a42e144a1c609253bca80ac0c55caf576831b6459c77fb690f1', + sequence: 4294967295, + n: 0, + addresses: ['ltc1gp6wfe96yxq855dhjjg0eg24yl8y6se62hgcadmh6jdyxfdlljy6slgmvea'], + isAddress: false, + value: '458340830086', + }, + ], + vout: [ + { + value: '458330830086', + n: 0, + spent: true, + hex: '582066723521c495f90a5fbe3686c617c294d69ac71ed9e57b65032f83e45871fd83', + addresses: ['ltc1gveer2gwyjhus5ha7x6rvv97zjntf43c7m8jhkegr97p7gkr3lkpsj08e2q'], + isAddress: false, + }, + { + value: '9997490', + n: 1, + hex: '0014f4de962f4bb82d0057974201202acd78d56db7f2', + addresses: ['ltc1q7n0fvt6thqksq4uhggqjq2kd0r2kmdlje4dvjg'], + isAddress: true, + }, + ], + blockHash: '98cdd21f13d92ccd23478681d6698aea20a7132d7ca9bec1204e0d25e9355eba', + blockHeight: 2373435, + confirmations: 29, + blockTime: 1669107971, + value: '458340827576', + valueIn: '458340830086', + fees: '2510', + hex: '02000000000801f190b67fc759641b8376f5ca550cac80ca3b2509c6a144e1425a437b18c161590000000000ffffffff020675a5b66a00000022582066723521c495f90a5fbe3686c617c294d69ac71ed9e57b65032f83e45871fd83b28c980000000000160014f4de962f4bb82d0057974201202acd78d56db7f20000000000', +}; + +const LTC_ACCOUNT = { + page: 1, + totalPages: 1, + itemsOnPage: 25, + address: + 'zpub6rDfq4mDgVKjjFz9cqWizJQvJyHKss4NhBzuiSaoJ5k23cCFyU2WQFrZEJPorsZt4soMDJtZBHL3ZyH8HfqkYSo7qzebbHL4QhpSTXUNpAq', + balance: '9997490', + totalReceived: '9997490', + totalSent: '0', + unconfirmedBalance: '0', + unconfirmedTxs: 0, + txs: 1, + transactions: [PREV_TX], + usedTokens: 1, + tokens: [ + { + type: 'XPUBAddress', + name: 'ltc1q7n0fvt6thqksq4uhggqjq2kd0r2kmdlje4dvjg', + path: "m/84'/2'/0'/0/0", + transfers: 1, + decimals: 8, + balance: '9997490', + totalReceived: '9997490', + totalSent: '0', + }, + { + type: 'XPUBAddress', + name: 'ltc1qjwamf85d5ua429l256pugmkp89rhkezndh8t3t', + path: "m/84'/2'/0'/1/0", + transfers: 0, + decimals: 8, + }, + { + type: 'XPUBAddress', + name: 'ltc1q6fwte9tar4dftxuarz8lwyfnwdmmt9azxjatpl', + path: "m/84'/2'/0'/1/1", + transfers: 0, + decimals: 8, + }, + ], +}; + +const isFirstAccount = (descriptor: string) => descriptor === LTC_ACCOUNT.address; + +export const fixtures = [ + { + method: 'getInfo', + default: true, + response: { + data: { + name: 'LitecoinMock', + shortcut: 'LTC', + decimals: 8, + version: '0.3.6', + bestHeight: 2373436, + bestHash: '2c1bc2b99f8a4447a57dfc7b694b9c82bff1b3af7cce8ff151df01238dc07c8b', + block0Hash: '12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2', + network: 'LTC', + testnet: false, + backend: { version: '210201', subversion: '/LitecoinCore:0.21.2.1/' }, + }, + }, + }, + { + method: 'getAccountInfo', + default: true, + response: ({ params }: any) => { + if (isFirstAccount(params.descriptor)) { + return { data: LTC_ACCOUNT }; + } + }, + }, + { + method: 'getAccountUtxo', + default: true, + response: { + data: [ + { + txid: PREV_TX.txid, + vout: 1, + value: '9997490', + height: 2373435, + confirmations: 2, + address: 'ltc1q7n0fvt6thqksq4uhggqjq2kd0r2kmdlje4dvjg', + path: "m/84'/2'/0'/0/0", + }, + ], + }, + }, + { + method: 'estimateFee', + default: true, + response: { + data: [ + { feePerUnit: '999' }, + { feePerUnit: '999' }, + { feePerUnit: '999' }, + { feePerUnit: '999' }, + { feePerUnit: '999' }, + { feePerUnit: '999' }, + { feePerUnit: '999' }, + { feePerUnit: '999' }, + { feePerUnit: '999' }, + { feePerUnit: '999' }, + ], + }, + }, + { + method: 'getTransaction', + default: true, + response: ({ params }: any) => { + if (params?.txid === PREV_TX.txid) { + return { + data: PREV_TX, + }; + } + }, + }, +]; diff --git a/packages/suite-desktop-core/e2e/support/metadataProviderMocks.ts b/packages/suite-desktop-core/e2e/support/mocks/metadataProviderMock.ts similarity index 84% rename from packages/suite-desktop-core/e2e/support/metadataProviderMocks.ts rename to packages/suite-desktop-core/e2e/support/mocks/metadataProviderMock.ts index 93a4a038d74..05dfbd72a70 100644 --- a/packages/suite-desktop-core/e2e/support/metadataProviderMocks.ts +++ b/packages/suite-desktop-core/e2e/support/mocks/metadataProviderMock.ts @@ -1,15 +1,15 @@ import { Page } from '@playwright/test'; -import { DropboxMock } from '../../../e2e-utils/src/mocks/dropbox'; -import { GoogleMock } from '../../../e2e-utils/src/mocks/google'; -import { step } from './common'; +import { GoogleMock, DropboxMock } from '@trezor/e2e-utils'; + +import { step } from '../common'; export enum MetadataProvider { DROPBOX = 'dropbox', GOOGLE = 'google', } -export type MetadataProviderMock = DropboxMock | GoogleMock; +export type ProviderMocks = DropboxMock | GoogleMock; const stubOpen = ` // Override Math.random for deterministic behavior @@ -53,12 +53,12 @@ const rerouteFetch = ` }; `; -export class MetadataProviderMocks { - private providerMock: MetadataProviderMock | undefined; +export class MetadataProviderMock { + private providerMock: ProviderMocks | undefined; constructor(private readonly page: Page) {} @step() - async initializeProviderMocking(provider: MetadataProvider) { + async start(provider: MetadataProvider) { switch (provider) { case MetadataProvider.DROPBOX: this.providerMock = new DropboxMock(); @@ -77,7 +77,7 @@ export class MetadataProviderMocks { } @step() - stopProviderMocking() { + stop() { if (!this.providerMock) { throw new Error('Provider mock not initialized'); } diff --git a/packages/suite-desktop-core/e2e/support/pageActions/marketActions.ts b/packages/suite-desktop-core/e2e/support/pageActions/marketActions.ts index 5f871d32072..99f8db4e3ea 100644 --- a/packages/suite-desktop-core/e2e/support/pageActions/marketActions.ts +++ b/packages/suite-desktop-core/e2e/support/pageActions/marketActions.ts @@ -72,6 +72,10 @@ export class MarketActions { readonly tradeConfirmationProvider: Locator; readonly tradeConfirmationContinueButton: Locator; readonly exchangeFeeDetails: Locator; + readonly broadcastButton: Locator; + readonly sendAddressInput: Locator; + readonly sendAmountInput: Locator; + readonly sendButton: Locator; constructor(private page: Page) { this.offerSpinner = this.page.getByTestId('@coinmarket/offers/loading-spinner'); @@ -125,6 +129,10 @@ export class MarketActions { '@coinmarket/offer/continue-transaction-button', ); this.exchangeFeeDetails = this.page.getByTestId('@wallet/fee-details'); + this.broadcastButton = this.page.getByTestId('broadcast-button'); + this.sendAddressInput = this.page.getByTestId('outputs.0.address'); + this.sendAmountInput = this.page.getByTestId('outputs.0.amount'); + this.sendButton = this.page.getByTestId('@send/review-button'); } @step() diff --git a/packages/suite-desktop-core/e2e/support/pageActions/metadataActions.ts b/packages/suite-desktop-core/e2e/support/pageActions/metadataActions.ts index 167f49bd0e8..fdbcdda8d06 100644 --- a/packages/suite-desktop-core/e2e/support/pageActions/metadataActions.ts +++ b/packages/suite-desktop-core/e2e/support/pageActions/metadataActions.ts @@ -2,7 +2,7 @@ import { Locator, Page, expect } from '@playwright/test'; import { TrezorUserEnvLink } from '@trezor/trezor-user-env-link'; -import { MetadataProvider } from '../metadataProviderMocks'; +import { MetadataProvider } from '../mocks/metadataProviderMock'; import { DevicePromptActions } from './devicePromptActions'; import { step } from '../common'; diff --git a/packages/suite-desktop-core/e2e/support/pageActions/settings/coinActions.ts b/packages/suite-desktop-core/e2e/support/pageActions/settings/coinActions.ts index c2a913fe006..b1112f3d9dc 100644 --- a/packages/suite-desktop-core/e2e/support/pageActions/settings/coinActions.ts +++ b/packages/suite-desktop-core/e2e/support/pageActions/settings/coinActions.ts @@ -16,12 +16,14 @@ export class CoinsActions { readonly coinAddressInput: Locator; readonly coinAdvanceSettingSaveButton: Locator; readonly modal: Locator; + readonly activateCoinsButton: Locator; constructor(private readonly page: Page) { this.coinBackendSelector = this.page.getByTestId('@settings/advance/select-type/input'); this.coinAddressInput = this.page.getByTestId('@settings/advance/url'); this.coinAdvanceSettingSaveButton = this.page.getByTestId('@settings/advance/button/save'); this.modal = this.page.getByTestId('@modal'); + this.activateCoinsButton = this.page.getByRole('button', { name: 'Activate coins' }); } @step() diff --git a/packages/suite-desktop-core/e2e/tests/metadata/account-metadata.test.ts b/packages/suite-desktop-core/e2e/tests/metadata/account-metadata.test.ts index 3c185d649e7..5e5ec9e3c5e 100644 --- a/packages/suite-desktop-core/e2e/tests/metadata/account-metadata.test.ts +++ b/packages/suite-desktop-core/e2e/tests/metadata/account-metadata.test.ts @@ -1,13 +1,13 @@ import { test, expect } from '../../support/fixtures'; -import { MetadataProvider } from '../../support/metadataProviderMocks'; +import { MetadataProvider } from '../../support/mocks/metadataProviderMock'; import { AccountLabelId } from '../../support/enums/accountLabelId'; // Metadata is by default disabled, this means, that application does not try to generate master key and connect to cloud. // Hovering over fields that may be labeled shows "add label" button upon which is clicked, Suite initiates metadata flow test.describe('Account metadata', { tag: ['@group=metadata', '@webOnly'] }, () => { test.use({ emulatorSetupConf: { mnemonic: 'mnemonic_all' } }); - test.beforeEach(async ({ metadataProviderMocks }) => { - await metadataProviderMocks.initializeProviderMocking(MetadataProvider.DROPBOX); + test.beforeEach(async ({ metadataProviderMock }) => { + await metadataProviderMock.start(MetadataProvider.DROPBOX); }); test('dropbox provider', async ({ @@ -105,7 +105,7 @@ test.describe('Account metadata', { tag: ['@group=metadata', '@webOnly'] }, () = ); }); - test.afterEach(({ metadataProviderMocks }) => { - metadataProviderMocks.stopProviderMocking(); + test.afterEach(({ metadataProviderMock }) => { + metadataProviderMock.stop(); }); }); diff --git a/packages/suite-desktop-core/e2e/tests/metadata/address-metadata.test.ts b/packages/suite-desktop-core/e2e/tests/metadata/address-metadata.test.ts index 2d730ca4607..b7e3cc7fa36 100644 --- a/packages/suite-desktop-core/e2e/tests/metadata/address-metadata.test.ts +++ b/packages/suite-desktop-core/e2e/tests/metadata/address-metadata.test.ts @@ -1,12 +1,12 @@ import { test, expect } from '../../support/fixtures'; -import { MetadataProvider } from '../../support/metadataProviderMocks'; +import { MetadataProvider } from '../../support/mocks/metadataProviderMock'; const metadataEl = '@metadata/addressLabel/bc1q7e6qu5smalrpgqrx9k2gnf0hgjyref5p36ru2m'; test.describe('Metadata - address labeling', { tag: ['@group=metadata', '@webOnly'] }, () => { test.use({ emulatorSetupConf: { mnemonic: 'mnemonic_all' } }); - test.beforeEach(async ({ metadataProviderMocks }) => { - await metadataProviderMocks.initializeProviderMocking(MetadataProvider.GOOGLE); + test.beforeEach(async ({ metadataProviderMock }) => { + await metadataProviderMock.start(MetadataProvider.GOOGLE); }); test('google provider', async ({ page, onboardingPage, metadataPage, dashboardPage }) => { @@ -40,7 +40,7 @@ test.describe('Metadata - address labeling', { tag: ['@group=metadata', '@webOnl await expect(page.getByTestId(metadataEl)).toHaveText('meow meow'); }); - test.afterEach(({ metadataProviderMocks }) => { - metadataProviderMocks.stopProviderMocking(); + test.afterEach(({ metadataProviderMock }) => { + metadataProviderMock.stop(); }); }); diff --git a/packages/suite-desktop-core/e2e/tests/wallet/send-doge.test.ts b/packages/suite-desktop-core/e2e/tests/wallet/send-doge.test.ts new file mode 100644 index 00000000000..736447ccd52 --- /dev/null +++ b/packages/suite-desktop-core/e2e/tests/wallet/send-doge.test.ts @@ -0,0 +1,70 @@ +import { test, expect } from '../../support/fixtures'; + +test.describe('Doge Send', { tag: ['@group=wallet', '@snapshot'] }, () => { + test.use({ + emulatorSetupConf: { + mnemonic: + 'fantasy auto fancy access ring spring patrol expect common tape talent annual', + }, + }); + + const recipientAddress = 'DJk8vtoEuNGtT4YRNoqVxWyRh6kM3s8bzc'; + const sendAmount = '115568568500'; + const feeAmount = '0.01450643'; + const totalAmount = '115,568,568,500.01450643'; + + test.beforeEach(async ({ onboardingPage, settingsPage, dashboardPage, blockbookMock }) => { + await blockbookMock.start('doge'); + await onboardingPage.completeOnboarding(); + await settingsPage.navigateTo('coins'); + await settingsPage.coins.disableNetwork('btc'); + await settingsPage.coins.enableNetwork('doge'); + await settingsPage.coins.openNetworkAdvanceSettings('doge'); + await settingsPage.coins.changeBackend('blockbook', blockbookMock.url); + await settingsPage.coins.activateCoinsButton.click(); + await dashboardPage.discoveryShouldFinish(); + await dashboardPage.navigateTo(); + }); + + test.afterEach(({ blockbookMock }) => { + blockbookMock.stop(); + }); + + test('Cannot send amount exceeding MAX_SAFE_INTEGER', async ({ + page, + trezorUserEnvLink, + walletPage, + marketPage, + devicePrompt, + }) => { + await test.step('Open send form for Doge', async () => { + await walletPage.accountButton({ symbol: 'doge' }).click(); + await walletPage.sendButton.click(); + }); + + await test.step('Fill amount over MAX_SAFE_INTEGER and send', async () => { + await marketPage.broadcastButton.click(); + await marketPage.sendAddressInput.fill(recipientAddress); + await marketPage.sendAmountInput.fill(sendAmount); + await marketPage.sendButton.click(); + await devicePrompt.confirmOnDevicePromptIsShown(); + }); + + await test.step('Verify info on modals and confirm', async () => { + await expect(devicePrompt.modal).toHaveScreenshot('send-doge.png'); + await expect( + page.getByTestId('@modal/output-total').getByTestId('@modal/output-value'), + ).toContainText(`${totalAmount} DOGE`); + await expect( + page.getByTestId('@modal/output-fee').getByTestId('@modal/output-value'), + ).toContainText(`${feeAmount} DOGE`); + await trezorUserEnvLink.pressYes(); + await expect(devicePrompt.modal).toHaveScreenshot('send-doge-confirmed.png'); + await trezorUserEnvLink.pressYes(); + }); + + await expect(page.getByTestId('@toast/sign-tx-error')).toHaveText( + 'Transaction signing error: Invalid amount specified', + ); + }); +}); diff --git a/packages/suite-web/e2e/tests/wallet/send-form-doge.test.ts b/packages/suite-web/e2e/tests/wallet/send-form-doge.test.ts deleted file mode 100644 index 6eccc473cc6..00000000000 --- a/packages/suite-web/e2e/tests/wallet/send-form-doge.test.ts +++ /dev/null @@ -1,69 +0,0 @@ -// @group_wallet -// @retry=2 - -import { onNavBar } from '../../support/pageObjects/topBarObject'; - -describe('Doge send form with mocked blockbook', () => { - beforeEach(() => { - cy.task('startEmu', { wipe: true }); - cy.task('setupEmu', { - needs_backup: false, - mnemonic: - 'fantasy auto fancy access ring spring patrol expect common tape talent annual', - }); - cy.task('startBridge'); - - cy.viewport('macbook-13').resetDb(); - cy.prefixedVisit('/'); - cy.passThroughInitialRun(); - cy.discoveryShouldFinish(); - onNavBar.openSettings(); - cy.getTestElement('@settings/menu/wallet').click(); - }); - - afterEach(() => { - cy.task('stopEmu'); - cy.task('stopBlockbookMock'); - }); - - it('spend an output with amount over MAX_SAFE_INTEGER', () => { - // - // Test preparation - // - - cy.task('startBlockbookMock', { endpointsFile: 'send-form-doge' }).then(port => { - const customBlockbook = `ws://localhost:${port}`; - cy.log(customBlockbook); - - // - // Test execution - // - cy.getTestElement('@settings/wallet/network/btc').click(); - cy.getTestElement('@settings/wallet/network/doge', { timeout: 30000 }) - .should('exist') - .click(); - cy.getTestElement('@settings/wallet/network/doge').trigger('mouseover'); - cy.getTestElement('@settings/wallet/network/doge/advance').click(); - cy.getTestElement('@modal').should('exist'); - cy.getTestElement('@settings/advance/select-type/input').click(); - cy.getTestElement('@settings/advance/select-type/option/blockbook').click(); - cy.getTestElement('@settings/advance/url').type(customBlockbook); - cy.getTestElement('@settings/advance/button/save').click(); - - cy.wait(1000); - cy.prefixedVisit('/accounts/send#/doge/0'); - cy.discoveryShouldFinish(); - - cy.getTestElement('broadcast-button').click(); - - cy.getTestElement('outputs.0.address').type('DJk8vtoEuNGtT4YRNoqVxWyRh6kM3s8bzc'); - cy.getTestElement('outputs.0.amount').type('115568568500'); - cy.getTestElement('@send/review-button').click(); - cy.getTestElement('@prompts/confirm-on-device'); - cy.task('pressYes'); - cy.task('pressYes'); - cy.task('pressYes'); - cy.getTestElement('@send/copy-raw-transaction'); - }); - }); -}); diff --git a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputElement.tsx b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputElement.tsx index 51431f8641c..dfad1d18aa9 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputElement.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputElement.tsx @@ -175,8 +175,8 @@ export const TransactionReviewOutputElement = forwardRef< {lines.map(line => ( - - + + {isActive && (line.id === 'address' || line.id === 'regular_legacy') ? line.confirmLabel : line.label}