diff --git a/apps/ledger-live-desktop/src/renderer/drawers/OperationDetails/index.tsx b/apps/ledger-live-desktop/src/renderer/drawers/OperationDetails/index.tsx index ea7c3f7f7a00..14861c153c1e 100644 --- a/apps/ledger-live-desktop/src/renderer/drawers/OperationDetails/index.tsx +++ b/apps/ledger-live-desktop/src/renderer/drawers/OperationDetails/index.tsx @@ -325,6 +325,7 @@ const OperationD = (props: Props) => { color="palette.text.shade60" mt={0} mb={1} + data-testid="transaction-type" > @@ -492,7 +493,13 @@ const OperationD = (props: Props) => { /> ) : undefined} - + diff --git a/apps/ledger-live-desktop/tests/page/drawer/drawer.ts b/apps/ledger-live-desktop/tests/component/drawer.component.ts similarity index 75% rename from apps/ledger-live-desktop/tests/page/drawer/drawer.ts rename to apps/ledger-live-desktop/tests/component/drawer.component.ts index 2bd2f3c35901..4a60dd551309 100644 --- a/apps/ledger-live-desktop/tests/page/drawer/drawer.ts +++ b/apps/ledger-live-desktop/tests/component/drawer.component.ts @@ -1,6 +1,4 @@ import { Component } from "tests/page/abstractClasses"; -import { expect } from "@playwright/test"; -import { Transaction } from "tests/models/Transaction"; import { step } from "tests/misc/reporters/step"; export class Drawer extends Component { @@ -10,9 +8,6 @@ export class Drawer extends Component { private closeButton = this.page.getByTestId("drawer-close-button"); private currencyButton = (currency: string) => this.page.getByTestId(`currency-row-${currency.toLowerCase()}`).first(); - private addressValue = (address: string) => - this.page.locator('[data-testid="drawer-content"]').locator(`text=${address}`); - private amountValue = this.page.getByTestId("amountReceived-drawer"); readonly selectAssetTitle = this.page.getByTestId("select-asset-drawer-title").first(); readonly selectAccountTitle = this.page.getByTestId("select-account-drawer-title").first(); readonly swapAmountFrom = this.page.getByTestId("swap-amount-from").first(); @@ -25,17 +20,6 @@ export class Drawer extends Component { await this.continueButton.click(); } - @step("Verify address is visible") - async addressValueIsVisible(address: string) { - await this.addressValue(address).waitFor({ state: "visible" }); - } - - @step("Verify that the information of the transaction is visible") - async expectReceiverInfos(tx: Transaction) { - await expect(this.addressValue(tx.accountToCredit.address)).toBeVisible(); - await expect(this.amountValue).toBeVisible(); - } - async waitForDrawerToBeVisible() { await this.content.waitFor({ state: "visible" }); await this.closeButton.waitFor({ state: "visible" }); diff --git a/apps/ledger-live-desktop/tests/enum/Account.ts b/apps/ledger-live-desktop/tests/enum/Account.ts index 46f169e47570..2408d0a396e5 100644 --- a/apps/ledger-live-desktop/tests/enum/Account.ts +++ b/apps/ledger-live-desktop/tests/enum/Account.ts @@ -10,7 +10,7 @@ export class Account { static readonly BTC_NATIVE_SEGWIT_1 = new Account( Currency.BTC, "Bitcoin 1", - "bc1qx7f9plgr8msjatkv0dw2ne8gguwfjqr6xyjp50", + "bc1qm6tw2c0u842qjs7g2n2c7ulh76f6xn4sk0dsyt", ); static readonly BTC_NATIVE_SEGWIT_2 = new Account( diff --git a/apps/ledger-live-desktop/tests/enum/AppInfos.ts b/apps/ledger-live-desktop/tests/enum/AppInfos.ts index b3cbf78e879a..161ea689268a 100644 --- a/apps/ledger-live-desktop/tests/enum/AppInfos.ts +++ b/apps/ledger-live-desktop/tests/enum/AppInfos.ts @@ -5,12 +5,12 @@ export class AppInfos { public readonly name: string, public readonly sendPattern?: DeviceLabels[], public readonly receivePattern?: DeviceLabels[], - public readonly lsPattern?: DeviceLabels[], + public readonly delegatePattern?: DeviceLabels[], ) {} static readonly BITCOIN = new AppInfos( "Bitcoin", [ - DeviceLabels.AMOUT, + DeviceLabels.AMOUNT, DeviceLabels.ADDRESS, DeviceLabels.CONTINUE, DeviceLabels.REJECT, @@ -21,7 +21,7 @@ export class AppInfos { static readonly BITCOIN_TESTNET = new AppInfos( "Bitcoin Test", [ - DeviceLabels.AMOUT, + DeviceLabels.AMOUNT, DeviceLabels.ADDRESS, DeviceLabels.CONTINUE, DeviceLabels.REJECT, @@ -31,47 +31,48 @@ export class AppInfos { ); static readonly DOGECOIN = new AppInfos( "Dogecoin", - [DeviceLabels.AMOUT, DeviceLabels.ADDRESS, DeviceLabels.ACCEPT, DeviceLabels.REJECT], + [DeviceLabels.AMOUNT, DeviceLabels.ADDRESS, DeviceLabels.ACCEPT, DeviceLabels.REJECT], [DeviceLabels.ADDRESS, DeviceLabels.APPROVE, DeviceLabels.REJECT], ); static readonly ETHEREUM = new AppInfos( "Ethereum", - [DeviceLabels.AMOUT, DeviceLabels.TO, DeviceLabels.ACCEPT, DeviceLabels.REJECT], + [DeviceLabels.AMOUNT, DeviceLabels.TO, DeviceLabels.ACCEPT, DeviceLabels.REJECT], [DeviceLabels.ADDRESS, DeviceLabels.APPROVE, DeviceLabels.REJECT], ); static readonly ETHEREUM_HOLESKY = new AppInfos( "Ethereum Holesky", - [DeviceLabels.AMOUT, DeviceLabels.TO, DeviceLabels.ACCEPT, DeviceLabels.REJECT], + [DeviceLabels.AMOUNT, DeviceLabels.TO, DeviceLabels.ACCEPT, DeviceLabels.REJECT], [DeviceLabels.ADDRESS, DeviceLabels.APPROVE, DeviceLabels.REJECT], ); static readonly ETHEREUM_SEPOLIA = new AppInfos( "Ethereum Sepolia", - [DeviceLabels.AMOUT, DeviceLabels.TO, DeviceLabels.ACCEPT, DeviceLabels.REJECT], + [DeviceLabels.AMOUNT, DeviceLabels.TO, DeviceLabels.ACCEPT, DeviceLabels.REJECT], [DeviceLabels.ADDRESS, DeviceLabels.APPROVE, DeviceLabels.REJECT], ); static readonly ETHEREUM_CLASSIC = new AppInfos( "Ethereum Classic", - [DeviceLabels.AMOUT, DeviceLabels.TO, DeviceLabels.ACCEPT, DeviceLabels.REJECT], + [DeviceLabels.AMOUNT, DeviceLabels.TO, DeviceLabels.ACCEPT, DeviceLabels.REJECT], [DeviceLabels.ADDRESS, DeviceLabels.APPROVE, DeviceLabels.REJECT], ); static readonly SOLANA = new AppInfos( "Solana", [DeviceLabels.TRANSFER, DeviceLabels.RECIPIENT, DeviceLabels.APPROVE, DeviceLabels.REJECT], [DeviceLabels.PUBKEY, DeviceLabels.APPROVE, DeviceLabels.REJECT], + [DeviceLabels.DELEGATE_FROM, DeviceLabels.DEPOSIT, DeviceLabels.APPROVE, DeviceLabels.REJECT], ); static readonly POLKADOT = new AppInfos( "Polkadot", - [DeviceLabels.DEST, DeviceLabels.AMOUT, DeviceLabels.CAPS_APPROVE, DeviceLabels.CAPS_REJECT], + [DeviceLabels.DEST, DeviceLabels.AMOUNT, DeviceLabels.CAPS_APPROVE, DeviceLabels.CAPS_REJECT], [DeviceLabels.ADDRESS, DeviceLabels.CAPS_APPROVE, DeviceLabels.CAPS_REJECT], ); static readonly TRON = new AppInfos( "Tron", - [DeviceLabels.AMOUT, DeviceLabels.TO, DeviceLabels.SIGN, DeviceLabels.CANCEL], + [DeviceLabels.AMOUNT, DeviceLabels.TO, DeviceLabels.SIGN, DeviceLabels.CANCEL], [DeviceLabels.ADDRESS, DeviceLabels.APPROVE, DeviceLabels.CANCEL], ); static readonly RIPPLE = new AppInfos( "Ripple", - [DeviceLabels.AMOUT, DeviceLabels.DESTINATION, DeviceLabels.SIGN, DeviceLabels.REJECT], + [DeviceLabels.AMOUNT, DeviceLabels.DESTINATION, DeviceLabels.SIGN, DeviceLabels.REJECT], [DeviceLabels.ADDRESS, DeviceLabels.APPROVE, DeviceLabels.REJECT], ); static readonly CARDANO = new AppInfos( @@ -86,13 +87,13 @@ export class AppInfos { ); static readonly BITCOIN_CASH = new AppInfos( "Bitcoin Cash", - [DeviceLabels.AMOUT, DeviceLabels.ADDRESS, DeviceLabels.ACCEPT, DeviceLabels.REJECT], + [DeviceLabels.AMOUNT, DeviceLabels.ADDRESS, DeviceLabels.ACCEPT, DeviceLabels.REJECT], [DeviceLabels.ADDRESS, DeviceLabels.APPROVE, DeviceLabels.REJECT], ); static readonly ALGORAND = new AppInfos( "Algorand", [ - DeviceLabels.AMOUT, + DeviceLabels.AMOUNT, DeviceLabels.RECEIVER, DeviceLabels.CAPS_APPROVE, DeviceLabels.CAPS_REJECT, @@ -101,35 +102,51 @@ export class AppInfos { ); static readonly COSMOS = new AppInfos( "Cosmos", - [DeviceLabels.AMOUT, DeviceLabels.TO, DeviceLabels.CAPS_APPROVE, DeviceLabels.CAPS_REJECT], + [DeviceLabels.AMOUNT, DeviceLabels.TO, DeviceLabels.CAPS_APPROVE, DeviceLabels.CAPS_REJECT], [DeviceLabels.ADDRESS, DeviceLabels.CAPS_APPROVE, DeviceLabels.CAPS_REJECT], + [ + DeviceLabels.PLEASE_REVIEW, + DeviceLabels.AMOUNT, + DeviceLabels.CAPS_APPROVE, + DeviceLabels.CAPS_REJECT, + ], ); static readonly TEZOS = new AppInfos( "Tezos", - [DeviceLabels.AMOUT, DeviceLabels.DESTINATION, DeviceLabels.ACCEPT, DeviceLabels.REJECT], + [DeviceLabels.AMOUNT, DeviceLabels.DESTINATION, DeviceLabels.ACCEPT, DeviceLabels.REJECT], [DeviceLabels.ADDRESS, DeviceLabels.APPROVE, DeviceLabels.REJECT], ); static readonly POLYGON = new AppInfos( "Polygon", - [DeviceLabels.AMOUT, DeviceLabels.ADDRESS, DeviceLabels.ACCEPT, DeviceLabels.REJECT], + [DeviceLabels.AMOUNT, DeviceLabels.ADDRESS, DeviceLabels.ACCEPT, DeviceLabels.REJECT], [DeviceLabels.ADDRESS, DeviceLabels.APPROVE, DeviceLabels.REJECT], ); static readonly BINANCE_SMART_CHAIN = new AppInfos( "Binance Smart Chain", - [DeviceLabels.AMOUT, DeviceLabels.ADDRESS, DeviceLabels.ACCEPT, DeviceLabels.REJECT], + [DeviceLabels.AMOUNT, DeviceLabels.ADDRESS, DeviceLabels.ACCEPT, DeviceLabels.REJECT], [DeviceLabels.ADDRESS, DeviceLabels.APPROVE, DeviceLabels.REJECT], ); static readonly TON = new AppInfos( "Ton", - [DeviceLabels.AMOUT, DeviceLabels.TO, DeviceLabels.APPROVE, DeviceLabels.REJECT], + [DeviceLabels.AMOUNT, DeviceLabels.TO, DeviceLabels.APPROVE, DeviceLabels.REJECT], [DeviceLabels.ADDRESS, DeviceLabels.APPROVE, DeviceLabels.REJECT], ); static readonly NEAR = new AppInfos( "Near", - [DeviceLabels.AMOUT, DeviceLabels.DESTINATION, DeviceLabels.ACCEPT, DeviceLabels.REJECT], + [DeviceLabels.AMOUNT, DeviceLabels.DESTINATION, DeviceLabels.ACCEPT, DeviceLabels.REJECT], [DeviceLabels.WALLET_ID, DeviceLabels.APPROVE, DeviceLabels.REJECT], + [ + DeviceLabels.VIEW_HEADER, + DeviceLabels.RECEIVER, + DeviceLabels.CONTINUE_TO_ACTION, + DeviceLabels.VIEW_ACTION, + DeviceLabels.METHOD_NAME, + DeviceLabels.DEPOSIT, + DeviceLabels.REJECT, + DeviceLabels.SIGN, + ], ); - static readonly LS = new AppInfos("LedgerSync", [DeviceLabels.LOGIN_LEDGER_SYNC]); + static readonly LS = new AppInfos("LedgerSync"); static readonly EXCHANGE = new AppInfos("Exchange", [ DeviceLabels.SEND, DeviceLabels.GET, diff --git a/apps/ledger-live-desktop/tests/enum/DeviceLabels.ts b/apps/ledger-live-desktop/tests/enum/DeviceLabels.ts index c008d9e1db97..40d3767992e4 100644 --- a/apps/ledger-live-desktop/tests/enum/DeviceLabels.ts +++ b/apps/ledger-live-desktop/tests/enum/DeviceLabels.ts @@ -1,6 +1,6 @@ export enum DeviceLabels { CONTINUE = "Continue", - AMOUT = "Amount", + AMOUNT = "Amount", ADDRESS = "Address", REJECT = "Reject", SIGN = "Sign", @@ -23,9 +23,15 @@ export enum DeviceLabels { TRANSACTION_FEE = "Transaction fee", FINALIZE = "Finalize", RECEIVER = "Receiver", - LOGIN_LEDGER_SYNC = "Log in to Ledger Sync", GET = "Get", FEES = "Fees", ACCEPT_AND_SEND = "Accept and send", WALLET_ID = "Wallet ID", + VIEW_HEADER = "View Header", + CONTINUE_TO_ACTION = "Continue to action", + VIEW_ACTION = "View action", + METHOD_NAME = "Method name", + DEPOSIT = "Deposit", + DELEGATE_FROM = "Delegate from", + PLEASE_REVIEW = "Please review", } diff --git a/apps/ledger-live-desktop/tests/models/Delegate.ts b/apps/ledger-live-desktop/tests/models/Delegate.ts new file mode 100644 index 000000000000..f4142fb9b65e --- /dev/null +++ b/apps/ledger-live-desktop/tests/models/Delegate.ts @@ -0,0 +1,9 @@ +import { Account } from "../enum/Account"; + +export class Delegate { + constructor( + public account: Account, + public amount: string, + public provider: string, + ) {} +} diff --git a/apps/ledger-live-desktop/tests/page/drawer/delegate.drawer.ts b/apps/ledger-live-desktop/tests/page/drawer/delegate.drawer.ts new file mode 100644 index 000000000000..bec74710af40 --- /dev/null +++ b/apps/ledger-live-desktop/tests/page/drawer/delegate.drawer.ts @@ -0,0 +1,50 @@ +import { step } from "tests/misc/reporters/step"; +import { Drawer } from "tests/component/drawer.component"; +import { Currency } from "tests/enum/Currency"; +import { Delegate } from "tests/models/Delegate"; +import { expect } from "@playwright/test"; +import { Transaction } from "tests/models/Transaction"; + +export class DelegateDrawer extends Drawer { + private provider = (provider: string) => + this.page.getByTestId("drawer-content").locator(`text=${provider}`); + private amountValue = this.page.getByTestId("amountReceived-drawer"); + private transactionType = this.page.getByTestId("transaction-type"); + private addressValue = (address: string) => + this.page.locator('[data-testid="drawer-content"]').locator(`text=${address}`); + + @step("Verify address $0 is visible") + async addressValueIsVisible(address: string) { + await expect(this.addressValue(address)).toBeVisible(); + } + + @step("Verify provider is visible") + async providerIsVisible(account: Delegate) { + if (account.account.currency === Currency.ATOM) { + await expect(this.provider(account.provider)).toBeVisible(); + } + } + + @step("Verify amount is visible") + async amountValueIsVisible() { + await expect(this.amountValue).toBeVisible(); + } + + @step("Verify transaction type is correct") + async transactionTypeIsVisible() { + await expect(this.transactionType).toBeVisible(); + } + + @step("Verify that the information of the transaction is visible") + async expectReceiverInfos(tx: Transaction) { + await expect(this.addressValue(tx.accountToCredit.address)).toBeVisible(); + await expect(this.amountValue).toBeVisible(); + } + + @step("Verify that the information of the delegation is visible") + async expectDelegationInfos(delegationInfo: Delegate) { + await this.providerIsVisible(delegationInfo); + await this.amountValueIsVisible(); + await this.transactionTypeIsVisible(); + } +} diff --git a/apps/ledger-live-desktop/tests/page/drawer/ledger.sync.drawer.ts b/apps/ledger-live-desktop/tests/page/drawer/ledger.sync.drawer.ts index 09e6e346544f..bf9b0c40b3c4 100644 --- a/apps/ledger-live-desktop/tests/page/drawer/ledger.sync.drawer.ts +++ b/apps/ledger-live-desktop/tests/page/drawer/ledger.sync.drawer.ts @@ -1,6 +1,6 @@ import { step } from "tests/misc/reporters/step"; import { expect } from "@playwright/test"; -import { Drawer } from "./drawer"; +import { Drawer } from "../../component/drawer.component"; import { extractNumberFromText } from "tests/utils/textParserUtils"; export class LedgerSyncDrawer extends Drawer { diff --git a/apps/ledger-live-desktop/tests/page/drawer/send.drawer.ts b/apps/ledger-live-desktop/tests/page/drawer/send.drawer.ts new file mode 100644 index 000000000000..7d94ac086d32 --- /dev/null +++ b/apps/ledger-live-desktop/tests/page/drawer/send.drawer.ts @@ -0,0 +1,21 @@ +import { step } from "tests/misc/reporters/step"; +import { Drawer } from "tests/component/drawer.component"; +import { expect } from "@playwright/test"; +import { Transaction } from "tests/models/Transaction"; + +export class SendDrawer extends Drawer { + private addressValue = (address: string) => + this.page.locator('[data-testid="drawer-content"]').locator(`text=${address}`); + private amountValue = this.page.getByTestId("amountReceived-drawer"); + + @step("Verify address is visible") + async addressValueIsVisible(address: string) { + await expect(this.addressValue(address)).toBeVisible(); + } + + @step("Verify that the information of the transaction is visible") + async expectReceiverInfos(tx: Transaction) { + await expect(this.addressValue(tx.accountToCredit.address)).toBeVisible(); + await expect(this.amountValue).toBeVisible(); + } +} diff --git a/apps/ledger-live-desktop/tests/page/drawer/swap.confirmation.drawer.ts b/apps/ledger-live-desktop/tests/page/drawer/swap.confirmation.drawer.ts index f4a9a49836df..8220e5179ff2 100644 --- a/apps/ledger-live-desktop/tests/page/drawer/swap.confirmation.drawer.ts +++ b/apps/ledger-live-desktop/tests/page/drawer/swap.confirmation.drawer.ts @@ -1,12 +1,12 @@ import { expect } from "@playwright/test"; import { step } from "tests/misc/reporters/step"; -import { Drawer } from "tests/page/drawer/drawer"; +import { Drawer } from "tests/component/drawer.component"; import { capitalizeFirstLetter } from "tests/utils/textParserUtils"; export class SwapConfirmationDrawer extends Drawer { private amountSent = this.page.getByTestId("amountSent"); private amountReceived = this.page.getByTestId("amountReceived"); - private provider = this.page.getByTestId("provider"); + private swapProvider = this.page.getByTestId("provider"); private fees = this.page.getByTestId("fees"); private sourceAccount = this.page.getByTestId("sourceAccount"); private targetAccount = this.page.getByTestId("targetAccount"); @@ -24,7 +24,7 @@ export class SwapConfirmationDrawer extends Drawer { @step("Verify provider: $0") async verifyProvider(provider: string) { - await expect(this.provider).toHaveText(capitalizeFirstLetter(provider)); + await expect(this.swapProvider).toHaveText(capitalizeFirstLetter(provider)); } @step("Verify source currency: $0") diff --git a/apps/ledger-live-desktop/tests/page/index.ts b/apps/ledger-live-desktop/tests/page/index.ts index b26c41b8f2d2..fc3e9b512d4c 100644 --- a/apps/ledger-live-desktop/tests/page/index.ts +++ b/apps/ledger-live-desktop/tests/page/index.ts @@ -8,12 +8,14 @@ import { Modal } from "../component/modal.component"; import { ReceiveModal } from "../page/modal/receive.modal"; import { SpeculosPage } from "tests/page/speculos.page"; import { SendModal } from "tests/page/modal/send.modal"; -import { Drawer } from "tests/page/drawer/drawer"; +import { Drawer } from "tests/component/drawer.component"; import { SettingsPage } from "tests/page/settings.page"; import { LedgerSyncDrawer } from "./drawer/ledger.sync.drawer"; import { SwapPage } from "tests/page/swap.page"; import { SwapConfirmationDrawer } from "tests/page/drawer/swap.confirmation.drawer"; import { delegateModal } from "tests/page/modal/delegate.modal"; +import { DelegateDrawer } from "./drawer/delegate.drawer"; +import { SendDrawer } from "./drawer/send.drawer"; export class Application extends PageHolder { public account = new AccountPage(this.page); @@ -31,4 +33,6 @@ export class Application extends PageHolder { public ledgerSync = new LedgerSyncDrawer(this.page); public swap = new SwapPage(this.page); public swapDrawer = new SwapConfirmationDrawer(this.page); + public delegateDrawer = new DelegateDrawer(this.page); + public sendDrawer = new SendDrawer(this.page); } diff --git a/apps/ledger-live-desktop/tests/page/modal/delegate.modal.ts b/apps/ledger-live-desktop/tests/page/modal/delegate.modal.ts index 1df2c2d52bb5..e9eaf9e1ebe9 100644 --- a/apps/ledger-live-desktop/tests/page/modal/delegate.modal.ts +++ b/apps/ledger-live-desktop/tests/page/modal/delegate.modal.ts @@ -4,13 +4,14 @@ import { step } from "tests/misc/reporters/step"; export class delegateModal extends Modal { private titleProvider = this.page.getByTestId("modal-provider-title"); - private delegateContinueButton = this.page.locator("id=delegate-continue-button"); + private delegateContinueButton = this.page.getByText("Continue"); private rowProvider = this.page.getByTestId("modal-provider-row"); private searchOpenButton = this.page.getByText("Show all"); private searchCloseButton = this.page.getByText("Show less"); private inputSearchField = this.page.getByPlaceholder("Search by name or address..."); private stakeProviderContainer = (stakeProviderID: string) => this.page.getByTestId(`stake-provider-container-${stakeProviderID}`); + private detailsButton = this.page.getByRole("button", { name: "View details" }); @step("Get title provider") async getTitleProvider() { @@ -51,4 +52,18 @@ export class delegateModal extends Modal { async chooseStakeProvider(stakeProvider: string) { await this.stakeProviderContainer(stakeProvider).click(); } + + @step("Click on view details button") + async clickViewDetailsButton() { + await this.detailsButton.click(); + } + + @step("Fill amount $0") + async fillAmount(amount: string) { + if (amount == "send max") { + await this.toggleMaxAmount(); + } else { + await this.cryptoAmountField.fill(amount); + } + } } diff --git a/apps/ledger-live-desktop/tests/page/modal/send.modal.ts b/apps/ledger-live-desktop/tests/page/modal/send.modal.ts index 7d829d3aadb3..acd0af18873a 100644 --- a/apps/ledger-live-desktop/tests/page/modal/send.modal.ts +++ b/apps/ledger-live-desktop/tests/page/modal/send.modal.ts @@ -76,15 +76,6 @@ export class SendModal extends Modal { await expect(this.continueButton).toBeEnabled(); } - @step("Fill amount") - async fillAmount(amount: string) { - if (amount == "send max") { - await this.toggleMaxAmount(); - } else { - await this.cryptoAmountField.fill(amount); - } - } - @step("Click `Continue` button") async clickContinue() { await this.continueButton.click(); @@ -94,4 +85,13 @@ export class SendModal extends Modal { async checkContinueButtonDisabled() { await expect(this.continueButton).toBeDisabled(); } + + @step("Fill amount $0") + async fillAmount(amount: string) { + if (amount == "send max") { + await this.toggleMaxAmount(); + } else { + await this.cryptoAmountField.fill(amount); + } + } } diff --git a/apps/ledger-live-desktop/tests/page/speculos.page.ts b/apps/ledger-live-desktop/tests/page/speculos.page.ts index 1e4a1993e239..d982e9795325 100644 --- a/apps/ledger-live-desktop/tests/page/speculos.page.ts +++ b/apps/ledger-live-desktop/tests/page/speculos.page.ts @@ -1,17 +1,18 @@ import { AppPage } from "tests/page/abstractClasses"; import { step } from "tests/misc/reporters/step"; - import { pressBoth, pressRightUntil, verifyAddress as assertAddressesEquality, verifyAmount, verifySwapFeesAmount, + verifyProvider, waitFor, } from "@ledgerhq/live-common/e2e/speculos"; import { Account } from "../enum/Account"; import { expect } from "@playwright/test"; import { Transaction } from "tests/models/Transaction"; +import { Delegate } from "tests/models/Delegate"; import { DeviceLabels } from "tests/enum/DeviceLabels"; import { Currency } from "tests/enum/Currency"; import { Swap } from "tests/models/Swap"; @@ -86,4 +87,62 @@ export class SpeculosPage extends AppPage { await pressRightUntil(DeviceLabels.REJECT); await pressBoth(); } + + @step("Delegate Method - Solana") + async delegateSolana(delegatingAccount: Delegate) { + const { delegatePattern } = delegatingAccount.account.currency.speculosApp || {}; + if (!delegatePattern) { + return; + } + await waitFor(delegatePattern[0]); + await pressRightUntil(delegatePattern[2]); + await pressBoth(); + } + + @step("Delegate Method - Near") + async delegateNear(delegatingAccount: Delegate) { + const { delegatePattern } = delegatingAccount.account.currency.speculosApp || {}; + if (!delegatePattern) { + return; + } + await waitFor(delegatePattern[0]); + const provider = await pressRightUntil(delegatePattern[1]); + expect(verifyProvider(delegatingAccount.provider, provider)).toBe(true); + await pressRightUntil(delegatePattern[2]); + await pressBoth(); + await waitFor(delegatePattern[3]); + await pressRightUntil(delegatePattern[7]); + await pressBoth(); + } + + @step("Delegate Method - Cosmos") + async delegateCosmos(delegatingAccount: Delegate) { + const { delegatePattern } = delegatingAccount.account.currency.speculosApp || {}; + if (!delegatePattern) { + return; + } + await waitFor(delegatePattern[0]); + const amount = await pressRightUntil(delegatePattern[1]); + expect(verifyAmount(delegatingAccount.amount, amount)).toBe(true); + await pressRightUntil(delegatePattern[2]); + await pressBoth(); + } + + @step("Sign Delegation Transaction") + async signDelegationTransaction(delegatingAccount: Delegate) { + const currencyName = delegatingAccount.account.currency.name; + switch (currencyName) { + case Account.SOL_1.currency.name: + await this.delegateSolana(delegatingAccount); + break; + case Account.NEAR_1.currency.name: + await this.delegateNear(delegatingAccount); + break; + case Account.ATOM_1.currency.name: + await this.delegateCosmos(delegatingAccount); + break; + default: + throw new Error(`Unsupported currency: ${currencyName}`); + } + } } diff --git a/apps/ledger-live-desktop/tests/specs/general/layout.spec.ts b/apps/ledger-live-desktop/tests/specs/general/layout.spec.ts index d90afb201666..80c6f31f9506 100644 --- a/apps/ledger-live-desktop/tests/specs/general/layout.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/general/layout.spec.ts @@ -1,7 +1,7 @@ import test from "../../fixtures/common"; import { expect } from "@playwright/test"; import { Layout } from "../../component/layout.component"; -import { Drawer } from "../../page/drawer/drawer"; +import { Drawer } from "../../component/drawer.component"; import { SendModal } from "../../page/modal/send.modal"; import { ReceiveModal } from "../../page/modal/receive.modal"; import { SettingsPage } from "../../page/settings.page"; diff --git a/apps/ledger-live-desktop/tests/specs/manager/devicelocalization.spec.ts b/apps/ledger-live-desktop/tests/specs/manager/devicelocalization.spec.ts index 61057b8eba73..03702b43a09a 100644 --- a/apps/ledger-live-desktop/tests/specs/manager/devicelocalization.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/manager/devicelocalization.spec.ts @@ -4,7 +4,7 @@ import { ManagerPage } from "../../page/manager.page"; import { LanguageInstallation } from "../../page/drawer/language.installation.drawer"; import { DeviceAction } from "../../models/DeviceAction"; import { Layout } from "../../component/layout.component"; -import { Drawer } from "tests/page/drawer/drawer"; +import { Drawer } from "tests/component/drawer.component"; test.use({ userdata: "skip-onboarding" }); test.use({ env: { FORCE_PROVIDER: "12" } }); diff --git a/apps/ledger-live-desktop/tests/specs/services/confirmTransaction.spec.ts b/apps/ledger-live-desktop/tests/specs/services/confirmTransaction.spec.ts index 6a4774ec6dc1..3f0d31223bec 100644 --- a/apps/ledger-live-desktop/tests/specs/services/confirmTransaction.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/services/confirmTransaction.spec.ts @@ -3,7 +3,7 @@ import { expect } from "@playwright/test"; import { Modal } from "../../component/modal.component"; import { DiscoverPage } from "../../page/discover.page"; import { Layout } from "../../component/layout.component"; -import { Drawer } from "../../page/drawer/drawer"; +import { Drawer } from "../../component/drawer.component"; import { DeviceAction } from "../../models/DeviceAction"; import { randomUUID } from "crypto"; import { LiveAppWebview } from "../../models/LiveAppWebview"; diff --git a/apps/ledger-live-desktop/tests/specs/services/cosmosStaking.spec.ts b/apps/ledger-live-desktop/tests/specs/services/cosmosStaking.spec.ts index 6c68e4e7cfc0..52113cb6d44c 100644 --- a/apps/ledger-live-desktop/tests/specs/services/cosmosStaking.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/services/cosmosStaking.spec.ts @@ -1,6 +1,6 @@ import test from "../../fixtures/common"; import { expect } from "@playwright/test"; -import { Drawer } from "../../page/drawer/drawer"; +import { Drawer } from "../../component/drawer.component"; import { Modal } from "../../component/modal.component"; import { PortfolioPage } from "../../page/portfolio.page"; import { Layout } from "../../component/layout.component"; diff --git a/apps/ledger-live-desktop/tests/specs/services/dapp.spec.ts b/apps/ledger-live-desktop/tests/specs/services/dapp.spec.ts index 27280a6a4028..e737e6f24c5c 100644 --- a/apps/ledger-live-desktop/tests/specs/services/dapp.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/services/dapp.spec.ts @@ -4,7 +4,7 @@ import { DiscoverPage } from "../../page/discover.page"; import { Layout } from "../../component/layout.component"; import { WebviewLayout } from "../../component/webviewLayout.component"; -import { Drawer } from "../../page/drawer/drawer"; +import { Drawer } from "../../component/drawer.component"; import { Modal } from "../../component/modal.component"; import { DeviceAction } from "../../models/DeviceAction"; import dummyLiveApp from "./dapp.spec.ts-mocks/dummy-live-app"; diff --git a/apps/ledger-live-desktop/tests/specs/services/ethereumStaking.spec.ts b/apps/ledger-live-desktop/tests/specs/services/ethereumStaking.spec.ts index 1a18efd8a80a..ae23241b0aa5 100644 --- a/apps/ledger-live-desktop/tests/specs/services/ethereumStaking.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/services/ethereumStaking.spec.ts @@ -1,7 +1,7 @@ import test from "../../fixtures/common"; import { expect } from "@playwright/test"; import { Analytics } from "../../models/Analytics"; -import { Drawer } from "../../page/drawer/drawer"; +import { Drawer } from "../../component/drawer.component"; import { Modal } from "../../component/modal.component"; import { PortfolioPage } from "../../page/portfolio.page"; import { LiveAppWebview } from "../../models/LiveAppWebview"; diff --git a/apps/ledger-live-desktop/tests/specs/services/liveapp-sdk.spec.ts b/apps/ledger-live-desktop/tests/specs/services/liveapp-sdk.spec.ts index bc65ef58a175..17103341a189 100644 --- a/apps/ledger-live-desktop/tests/specs/services/liveapp-sdk.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/services/liveapp-sdk.spec.ts @@ -2,7 +2,7 @@ import test from "../../fixtures/common"; import { expect } from "@playwright/test"; import { DiscoverPage } from "../../page/discover.page"; import { Layout } from "../../component/layout.component"; -import { Drawer } from "../../page/drawer/drawer"; +import { Drawer } from "../../component/drawer.component"; import { Modal } from "../../component/modal.component"; import { DeviceAction } from "../../models/DeviceAction"; import { LiveAppWebview } from "../../models/LiveAppWebview"; diff --git a/apps/ledger-live-desktop/tests/specs/services/swap.spec.ts b/apps/ledger-live-desktop/tests/specs/services/swap.spec.ts index a392f5dfce1b..52ef6cad60a1 100644 --- a/apps/ledger-live-desktop/tests/specs/services/swap.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/services/swap.spec.ts @@ -6,7 +6,7 @@ import test from "../../fixtures/mockFixtures"; import { DeviceAction } from "../../models/DeviceAction"; import { AccountPage } from "../../page/account.page"; import { AccountsPage } from "../../page/accounts.page"; -import { Drawer } from "../../page/drawer/drawer"; +import { Drawer } from "../../component/drawer.component"; import { SwapPage } from "../../page/swap.page"; import { getBitcoinToDogecoinRatesMock, diff --git a/apps/ledger-live-desktop/tests/specs/services/wallet-api.spec.ts b/apps/ledger-live-desktop/tests/specs/services/wallet-api.spec.ts index f287adbb4842..78620026ecf8 100644 --- a/apps/ledger-live-desktop/tests/specs/services/wallet-api.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/services/wallet-api.spec.ts @@ -2,7 +2,7 @@ import test from "../../fixtures/common"; import { expect } from "@playwright/test"; import { DiscoverPage } from "../../page/discover.page"; import { Layout } from "../../component/layout.component"; -import { Drawer } from "../../page/drawer/drawer"; +import { Drawer } from "../../component/drawer.component"; import { Modal } from "../../component/modal.component"; import { DeviceAction } from "../../models/DeviceAction"; import { randomUUID } from "crypto"; diff --git a/apps/ledger-live-desktop/tests/specs/speculos/delegate.spec.ts b/apps/ledger-live-desktop/tests/specs/speculos/delegate.spec.ts index fdf0dbce837c..c315558cb9e9 100644 --- a/apps/ledger-live-desktop/tests/specs/speculos/delegate.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/speculos/delegate.spec.ts @@ -1,23 +1,21 @@ import { test } from "../../fixtures/common"; import { Account } from "../../enum/Account"; +import { Delegate } from "../../models/Delegate"; import { addTmsLink } from "tests/utils/allureUtils"; import { getDescription } from "../../utils/customJsonReporter"; const accounts = [ { - account: Account.ATOM_1, - xrayTicket: "B2CQA-2731", - provider: "Ledger", + delegate: new Delegate(Account.ATOM_1, "0.001", "Ledger"), + xrayTicket: "B2CQA-2731, B2CQA-2740", }, { - account: Account.SOL_1, - xrayTicket: "B2CQA-2730", - provider: "Ledger by Figment", + delegate: new Delegate(Account.SOL_1, "0.001", "Ledger by Figment"), + xrayTicket: "B2CQA-2730, B2CQA-2742", }, { - account: Account.NEAR_1, - xrayTicket: "B2CQA-2732", - provider: "ledgerbyfigment.poolv1.near", + delegate: new Delegate(Account.NEAR_1, "0.01", "ledgerbyfigment.poolv1.near"), + xrayTicket: "B2CQA-2732, B2CQA-2741", }, ]; @@ -25,10 +23,11 @@ for (const account of accounts) { test.describe("Delegate", () => { test.use({ userdata: "speculos-delegate", + speculosApp: account.delegate.account.currency.speculosApp, }); test( - `[${account.account.currency.name}] Delegate`, + `[${account.delegate.account.currency.name}] Delegate`, { annotation: { type: "TMS", @@ -38,10 +37,27 @@ for (const account of accounts) { async ({ app }) => { await addTmsLink(getDescription(test.info().annotations).split(", ")); await app.layout.goToAccounts(); - await app.accounts.navigateToAccountByName(account.account.accountName); + await app.accounts.navigateToAccountByName(account.delegate.account.accountName); await app.account.clickBannerCTA(); - await app.delegate.verifyProvider(account.provider); + await app.delegate.verifyProvider(account.delegate.provider); + + await app.delegate.continueDelegate(); + await app.delegate.fillAmount(account.delegate.amount); + await app.modal.countinueSendAmount(); + + await app.speculos.signDelegationTransaction(account.delegate); + await app.delegate.clickViewDetailsButton(); + + await app.drawer.waitForDrawerToBeVisible(); + await app.delegateDrawer.transactionTypeIsVisible(); + await app.delegateDrawer.providerIsVisible(account.delegate); + await app.delegateDrawer.amountValueIsVisible(); + await app.drawer.close(); + + await app.layout.syncAccounts(); + await app.account.clickOnLastOperation(); + await app.delegateDrawer.expectDelegationInfos(account.delegate); }, ); }); diff --git a/apps/ledger-live-desktop/tests/specs/speculos/send.tx.spec.ts b/apps/ledger-live-desktop/tests/specs/speculos/send.tx.spec.ts index c14dc91662ba..883f40ca9414 100644 --- a/apps/ledger-live-desktop/tests/specs/speculos/send.tx.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/speculos/send.tx.spec.ts @@ -185,7 +185,7 @@ for (const transaction of transactionE2E) { await app.speculos.expectValidTxInfo(transaction.transaction); await app.send.expectTxSent(); await app.account.navigateToViewDetails(); - await app.drawer.addressValueIsVisible(transaction.transaction.accountToCredit.address); + await app.sendDrawer.addressValueIsVisible(transaction.transaction.accountToCredit.address); await app.drawer.close(); await app.layout.goToAccounts(); @@ -194,7 +194,7 @@ for (const transaction of transactionE2E) { ); await app.layout.syncAccounts(); await app.account.clickOnLastOperation(); - await app.drawer.expectReceiverInfos(transaction.transaction); + await app.sendDrawer.expectReceiverInfos(transaction.transaction); }, ); }); @@ -366,6 +366,7 @@ test.describe("Verify send max user flow", () => { }, }, async ({ app }) => { + await addTmsLink(getDescription(test.info().annotations).split(", ")); await app.layout.goToAccounts(); await app.accounts.navigateToAccountByName(transactionInputValid.accountToDebit.accountName); @@ -386,7 +387,7 @@ for (const transaction of transactionAddressValid) { }); test( - `Check button enabled ${transaction.xrayTicket} - valid address input`, + `Check button enabled (from ${transaction.transaction.accountToDebit} to ${transaction.transaction.accountToCredit}) - valid address input ${transaction.xrayTicket}`, { annotation: { type: "TMS", @@ -394,6 +395,7 @@ for (const transaction of transactionAddressValid) { }, }, async ({ app }) => { + await addTmsLink(getDescription(test.info().annotations).split(", ")); await app.layout.goToAccounts(); await app.accounts.navigateToAccountByName( transaction.transaction.accountToDebit.accountName, @@ -415,7 +417,7 @@ for (const transaction of transactionsAddressInvalid) { }); test( - `Check "${transaction.expectedErrorMessage}" (${transaction.xrayTicket}) - invalid address input error`, + `Check "${transaction.expectedErrorMessage}" (from ${transaction.transaction.accountToDebit} to ${transaction.transaction.accountToCredit}) - invalid address input error${transaction.xrayTicket}`, { annotation: { type: "TMS", @@ -423,6 +425,7 @@ for (const transaction of transactionsAddressInvalid) { }, }, async ({ app }) => { + await addTmsLink(getDescription(test.info().annotations).split(", ")); await app.layout.goToAccounts(); await app.accounts.navigateToAccountByName( transaction.transaction.accountToDebit.accountName, diff --git a/libs/ledger-live-common/src/e2e/speculos.ts b/libs/ledger-live-common/src/e2e/speculos.ts index 64ca13d49fb2..a688762d58f5 100644 --- a/libs/ledger-live-common/src/e2e/speculos.ts +++ b/libs/ledger-live-common/src/e2e/speculos.ts @@ -375,6 +375,11 @@ export function verifyAmount(amount: string, text: string[]): boolean { return amountDevice.includes(amount); } +export function verifyProvider(provider: string, text: string[]): boolean { + const providerDevice = text.join(""); + return providerDevice.includes(provider); +} + export function verifySwapFeesAmount(amount: string, text: string[]): boolean { const amountDevice = text[3]; return amountDevice.includes(amount);