diff --git a/apps/ledger-live-desktop/tests/page/asset.page.ts b/apps/ledger-live-desktop/tests/page/asset.page.ts index de5c43a2a5e0..625a9f818f0b 100644 --- a/apps/ledger-live-desktop/tests/page/asset.page.ts +++ b/apps/ledger-live-desktop/tests/page/asset.page.ts @@ -3,6 +3,7 @@ import { AppPage } from "tests/page/abstractClasses"; export class AssetPage extends AppPage { private stakeButton = this.page.getByTestId("asset-page-stake-button"); private buyButton = this.page.getByTestId("asset-page-buy-button"); + private swapButton = this.page.getByTestId("asset-page-swap-button"); async startStakeFlow() { await this.stakeButton.click(); @@ -12,4 +13,8 @@ export class AssetPage extends AppPage { async startBuyFlow() { await this.buyButton.click(); } + + async startSwapFlow() { + await this.swapButton.click(); + } } diff --git a/apps/ledger-live-desktop/tests/page/index.ts b/apps/ledger-live-desktop/tests/page/index.ts index d882b0ee807a..8d2d4544998f 100644 --- a/apps/ledger-live-desktop/tests/page/index.ts +++ b/apps/ledger-live-desktop/tests/page/index.ts @@ -22,6 +22,7 @@ import { PasswordlockModal } from "./modal/passwordlock.modal"; import { LockscreenPage } from "tests/page/lockscreen.page"; import { NFTDrawer } from "./drawer/nft.drawer"; import { NftGallery } from "./nftGallery.page"; +import { AssetPage } from "./asset.page"; export class Application extends PageHolder { public account = new AccountPage(this.page); @@ -47,4 +48,5 @@ export class Application extends PageHolder { public LockscreenPage = new LockscreenPage(this.page); public nftDrawer = new NFTDrawer(this.page); public nftGallery = new NftGallery(this.page); + public assetPage = new AssetPage(this.page); } diff --git a/apps/ledger-live-desktop/tests/page/market.page.ts b/apps/ledger-live-desktop/tests/page/market.page.ts index f097c4e9f42c..d139e85248f1 100644 --- a/apps/ledger-live-desktop/tests/page/market.page.ts +++ b/apps/ledger-live-desktop/tests/page/market.page.ts @@ -13,6 +13,7 @@ export class MarketPage extends AppPage { private buyButton = (ticker: string) => this.page.getByTestId(`market-${ticker}-buy-button`); readonly swapButton = (ticker: string) => this.page.getByTestId(`market-${ticker}-swap-button`); private stakeButton = (ticker: string) => this.page.getByTestId(`market-${ticker}-stake-button`); + private swapButtonOnAsset = this.page.getByTestId("market-coin-swap-button"); @step("Search for $0") async search(query: string) { @@ -41,7 +42,7 @@ export class MarketPage extends AppPage { @step("Open coin page for $0") async openCoinPage(ticker: string) { - await this.coinRow(ticker).click(); + await this.coinRow(ticker.toLowerCase()).click(); await this.coinPageContainer.waitFor({ state: "attached" }); await this.loadingPlaceholder.first().waitFor({ state: "detached" }); } @@ -69,6 +70,16 @@ export class MarketPage extends AppPage { await this.swapButton("btc").waitFor({ state: "attached" }); // swap buttons are displayed few seconds after } + @step("Click on swap button for $0") + async startSwapForSelectedTicker(ticker: string) { + await this.swapButton(ticker.toLowerCase()).click(); + } + + @step("Click on swap button on asset") + async clickOnSwapButtonOnAsset() { + await this.swapButtonOnAsset.click(); + } + @step("Wait for search bar to be empty") async waitForSearchBarToBeEmpty() { await this.page.waitForFunction(async () => { diff --git a/apps/ledger-live-desktop/tests/page/portfolio.page.ts b/apps/ledger-live-desktop/tests/page/portfolio.page.ts index 4c30a760fff5..44311ed1fb9c 100644 --- a/apps/ledger-live-desktop/tests/page/portfolio.page.ts +++ b/apps/ledger-live-desktop/tests/page/portfolio.page.ts @@ -40,6 +40,11 @@ export class PortfolioPage extends AppPage { await expect(this.swapEntryButton).toBeVisible(); } + @step("Click on swap button") + async clickSwapButton() { + await this.swapEntryButton.click(); + } + @step("Check 'Stake' button visibility") async checkStakeButtonVisibility() { await expect(this.stakeEntryButton).toBeVisible(); @@ -74,6 +79,11 @@ export class PortfolioPage extends AppPage { await this.buySellEntryButton.click(); } + @step("Click on asset row $0") + async clickOnSelectedAssetRow(asset: string) { + await this.assetRow(asset).click(); + } + @step("Click stake button") async startStakeFlow() { await this.stakeEntryButton.click(); diff --git a/apps/ledger-live-desktop/tests/page/swap.page.ts b/apps/ledger-live-desktop/tests/page/swap.page.ts index 650f9e3b7531..6468326a89e9 100644 --- a/apps/ledger-live-desktop/tests/page/swap.page.ts +++ b/apps/ledger-live-desktop/tests/page/swap.page.ts @@ -208,6 +208,18 @@ export class SwapPage extends AppPage { await this.chooseAssetDrawer.chooseFromAsset(accountToSwapFrom.currency.name); } + @step("Expect Highest market cap currency to be selected") + async expectHighestMcapToBeSelected(electronApp: ElectronApplication) { + const [, webview] = electronApp.windows(); + expect(webview.getByTestId(this.fromAccountCoinSelector)).toContainText("BTC"); + } + + @step("Expect asset or account selected $0 to be displayed") + async expectSelectedAssetDisplayed(asset: string, electronApp: ElectronApplication) { + const [, webview] = electronApp.windows(); + expect(webview.getByTestId(this.fromAccountCoinSelector)).toContainText(asset); + } + @step("Fill in amount: $1") async fillInOriginCurrencyAmount(electronApp: ElectronApplication, amount: string) { const [, webview] = electronApp.windows(); diff --git a/apps/ledger-live-desktop/tests/specs/speculos/swap.spec.ts b/apps/ledger-live-desktop/tests/specs/speculos/swap.spec.ts index ded688c1aee2..e4dec07c470b 100644 --- a/apps/ledger-live-desktop/tests/specs/speculos/swap.spec.ts +++ b/apps/ledger-live-desktop/tests/specs/speculos/swap.spec.ts @@ -415,6 +415,162 @@ for (const { swap, xrayTicket } of tooLowAmountForQuoteSwaps) { }); } +const swapEntryPoint = { + swap: new Swap( + Account.BTC_NATIVE_SEGWIT_1, + Account.ETH_1, + "0.0006", + Fee.MEDIUM, + Provider.CHANGELLY, + Rate.FLOAT, + ), +}; + +test.describe("Swap flow from different entry point", () => { + test.beforeAll(async () => { + process.env.SWAP_DISABLE_APPS_INSTALL = "true"; + process.env.SWAP_API_BASE = "https://swap-stg.ledger-test.com/v5"; + process.env.DISABLE_TRANSACTION_BROADCAST = "1"; + }); + + test.afterAll(async () => { + delete process.env.SWAP_DISABLE_APPS_INSTALL; + delete process.env.SWAP_API_BASE; + delete process.env.DISABLE_TRANSACTION_BROADCAST; + }); + + test.use({ + userdata: "speculos-tests-app", + speculosApp: app, + }); + + test( + "Entry Point - Portfolio page", + { + annotation: { + type: "TMS", + description: "B2CQA-2985", + }, + }, + async ({ app, electronApp }) => { + await addTmsLink(getDescription(test.info().annotations, "TMS").split(", ")); + await app.layout.goToPortfolio(); + await app.portfolio.clickSwapButton(); + await app.swap.waitForPageNetworkIdleState(); + await app.swap.expectHighestMcapToBeSelected(electronApp); + }, + ); + + test( + "Entry Point - Asset Allocation", + { + annotation: { + type: "TMS", + description: "B2CQA-2986", + }, + }, + async ({ app, electronApp }) => { + await addTmsLink(getDescription(test.info().annotations, "TMS").split(", ")); + await app.layout.goToPortfolio(); + await app.portfolio.clickOnSelectedAssetRow(swapEntryPoint.swap.accountToDebit.currency.name); + await app.assetPage.startSwapFlow(); + await app.swap.waitForPageNetworkIdleState(); + await app.swap.expectSelectedAssetDisplayed( + swapEntryPoint.swap.accountToDebit.currency.name, + electronApp, + ); + }, + ); + + test( + "Entry Point - Market page - 1", + { + annotation: { + type: "TMS", + description: "B2CQA-2987", + }, + }, + async ({ app, electronApp }) => { + await addTmsLink(getDescription(test.info().annotations, "TMS").split(", ")); + await app.layout.goToMarket(); + await app.market.startSwapForSelectedTicker( + swapEntryPoint.swap.accountToDebit.currency.ticker, + ); + await app.swap.waitForPageNetworkIdleState(); + await app.swap.expectSelectedAssetDisplayed( + swapEntryPoint.swap.accountToDebit.currency.name, + electronApp, + ); + await app.swap.expectSelectedAssetDisplayed( + swapEntryPoint.swap.accountToDebit.accountName, + electronApp, + ); + }, + ); + + test( + "Entry Point - Market page - 2", + { + annotation: { + type: "TMS", + description: "B2CQA-2988", + }, + }, + async ({ app, electronApp }) => { + await addTmsLink(getDescription(test.info().annotations, "TMS").split(", ")); + await app.layout.goToMarket(); + await app.market.openCoinPage(swapEntryPoint.swap.accountToDebit.currency.ticker); + await app.market.clickOnSwapButtonOnAsset(); + await app.swap.waitForPageNetworkIdleState(); + await app.swap.expectSelectedAssetDisplayed( + swapEntryPoint.swap.accountToDebit.currency.name, + electronApp, + ); + }, + ); + + test( + "Entry Point - Account page", + { + annotation: { + type: "TMS", + description: "B2CQA-2989", + }, + }, + async ({ app, electronApp }) => { + await addTmsLink(getDescription(test.info().annotations, "TMS").split(", ")); + await app.layout.goToAccounts(); + await app.accounts.navigateToAccountByName(swapEntryPoint.swap.accountToDebit.accountName); + await app.account.navigateToSwap(); + await app.swap.waitForPageNetworkIdleState(); + await app.swap.expectSelectedAssetDisplayed( + swapEntryPoint.swap.accountToDebit.currency.name, + electronApp, + ); + await app.swap.expectSelectedAssetDisplayed( + swapEntryPoint.swap.accountToDebit.accountName, + electronApp, + ); + }, + ); + + test( + "Entry Point - left menu", + { + annotation: { + type: "TMS", + description: "B2CQA-2990, B2CQA-523", + }, + }, + async ({ app, electronApp }) => { + await addTmsLink(getDescription(test.info().annotations, "TMS").split(", ")); + await app.layout.goToSwap(); + await app.swap.waitForPageNetworkIdleState(); + await app.swap.expectHighestMcapToBeSelected(electronApp); + }, + ); +}); + async function performSwapUntilQuoteSelectionStep( app: Application, electronApp: ElectronApplication,