Skip to content

Commit

Permalink
test: 🎨 Refacto layout class
Browse files Browse the repository at this point in the history
  • Loading branch information
VicAlbr committed Jan 17, 2025
1 parent c0bff4d commit 762b976
Show file tree
Hide file tree
Showing 13 changed files with 149 additions and 112 deletions.
152 changes: 67 additions & 85 deletions apps/ledger-live-desktop/tests/component/layout.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,46 @@ export class Layout extends Component {
readonly renderError = this.page.getByTestId("render-error");
readonly appVersion = this.page.getByTestId("app-version");

// portfolio && accounts
readonly totalBalance = this.page.getByTestId("total-balance");

// drawer
readonly drawerCollapseButton = this.page.getByTestId("drawer-collapse-button");
readonly drawerPortfolioButton = this.page.getByTestId("drawer-dashboard-button");
// side bar
private drawerCollapseButton = this.page.getByTestId("drawer-collapse-button");
private drawerPortfolioButton = this.page.getByTestId("drawer-dashboard-button");
private drawerMarketButton = this.page.getByTestId("drawer-market-button");
private drawerAccountsButton = this.page.getByTestId("drawer-accounts-button");
private drawerDiscoverButton = this.page.getByTestId("drawer-catalog-button");
private drawerSendButton = this.page.getByTestId("drawer-send-button");
private drawerReceiveButton = this.page.getByTestId("drawer-receive-button");
private drawerManagerButton = this.page.getByTestId("drawer-manager-button");
private drawerBuycryptoButton = this.page.getByTestId("drawer-exchange-button");
private drawerEarnButton = this.page.getByTestId("drawer-earn-button");
private drawerBuycryptoButton = this.page.getByTestId("drawer-exchange-button");
private drawerSwapButton = this.page.getByTestId("drawer-swap-button");
readonly drawerExperimentalButton = this.page.getByTestId("drawer-experimental-button");
private bookmarkedAccountsList = this.page.getByTestId("drawer-bookmarked-accounts");
readonly bookmarkedAccounts = this.bookmarkedAccountsList.locator(".bookmarked-account-item");
readonly inputWarning = this.page.locator("id=input-warning");
private drawerExperimentalButton = this.page.getByTestId("drawer-experimental-button");
private drawerManagerButton = this.page.getByTestId("drawer-manager-button");
readonly bookmarkedAccounts = this.page
.getByTestId("drawer-bookmarked-accounts")
.locator(".bookmarked-account-item");

// topbar
private topbarDiscreetButton = this.page.getByTestId("topbar-discreet-button");
readonly topbarSynchronizeButton = this.page.getByTestId("topbar-synchronize-button");
private topbarSynchronizeButton = this.page.getByTestId("topbar-synchronize-button");
private topbarSettingsButton = this.page.getByTestId("topbar-settings-button");
readonly topbarLockButton = this.page.getByTestId("topbar-password-lock-button");
readonly topbarHelpButton = this.page.getByTestId("topbar-help-button");
private topbarLockButton = this.page.getByTestId("topbar-password-lock-button");
private topbarHelpButton = this.page.getByTestId("topbar-help-button");
private discreetTooltip = this.page.locator("#tippy-12"); // automatically generated tippy id but it's consistent

// general
readonly inputError = this.page.locator("id=input-error"); // no data-testid because css style is applied
readonly insufficientFundsWarning = this.page.getByTestId("insufficient-funds-warning");
readonly logo = this.page.getByTestId("logo");
readonly marketPerformanceWidget = this.page.getByTestId("market-performance-widget");

// updater
readonly appUpdateBanner = this.page.getByTestId("layout-app-update-banner");
// }

readonly marketPerformanceWidget = this.page.getByTestId("market-performance-widget");
@step("Close side bar")
async closeSideBar() {
await this.drawerCollapseButton.click();
}

@step("Go to Experimental Features")
async goToExperimentalFeatures() {
await this.drawerExperimentalButton.click();
}

@step("Go to Portfolio")
async goToPortfolio() {
Expand All @@ -55,109 +57,89 @@ export class Layout extends Component {
await this.drawerMarketButton.click();
}

@step("Check input error state visibibility: $0")
async checkInputErrorVisibibility(expectedState: "visible" | "hidden") {
await this.inputError.waitFor({ state: expectedState });
}

@step("synchronize accounts")
async syncAccounts() {
await this.topbarSynchronizeButton.click();
}

@step("Wait for accounts sync to be finished")
async waitForAccountsSyncToBeDone() {
await expect(this.topbarSynchronizeButton).not.toHaveText("Synchronizing");
}

@step("Open Accounts")
async goToAccounts() {
await this.drawerAccountsButton.click();
}

@step("Wait for balance to be visible")
async expectBalanceVisibility() {
await this.totalBalance.waitFor({ state: "visible" });
}

@step("Go to discover")
async goToDiscover() {
await this.drawerDiscoverButton.click();
}

@step("Go to manager")
async goToManager() {
await this.drawerManagerButton.click();
@step("Open send modal")
async openSendModalFromSideBar() {
await this.drawerSendButton.click();
}

@step("Go to buy crypto")
async goToBuyCrypto() {
await this.drawerBuycryptoButton.click();
@step("Open receive modal")
async openReceiveModalFromSideBar() {
await this.drawerReceiveButton.click();
}

@step("Go to earn")
async goToEarn() {
await this.drawerEarnButton.click();
}

async toggleDiscreetMode() {
await this.topbarDiscreetButton.click();
await this.discreetTooltip.waitFor({ state: "hidden" }); // makes sure the tooltip has disappeared to prevent flakiness
@step("Go to buy crypto")
async goToBuySellCrypto() {
await this.drawerBuycryptoButton.click();
}

@step("Go to swap")
async goToSwap() {
await this.drawerSwapButton.click();
}

@step("Go to manager")
async goToManager() {
await this.drawerManagerButton.click();
}

@step("Go to Settings")
async goToSettings() {
await this.topbarSettingsButton.click();
}

@step("Check warning message")
async checkAmoutWarningMessage(expectedWarningMessage: RegExp) {
if (expectedWarningMessage !== null) {
await expect(this.insufficientFundsWarning).toBeVisible();
const warningText = await this.insufficientFundsWarning.innerText();
expect(warningText).toMatch(expectedWarningMessage);
}
@step("synchronize accounts")
async syncAccounts() {
await this.topbarSynchronizeButton.click();
}

@step("Wait for accounts sync to be finished")
async waitForAccountsSyncToBeDone() {
await expect(this.topbarSynchronizeButton).not.toHaveText("Synchronizing");
}

@step("Toggle discreet mode")
async toggleDiscreetMode() {
await this.topbarDiscreetButton.click();
await this.discreetTooltip.waitFor({ state: "hidden" }); // makes sure the tooltip has disappeared to prevent flakiness
}

@step("Check warning message")
async checkInputWarningMessage(expectedWarningMessage: string | null) {
if (expectedWarningMessage !== null) {
await expect(this.inputWarning).toBeVisible();
const warningText = await this.inputWarning.innerText();
expect(warningText).toMatch(expectedWarningMessage);
}
@step("Expect top bar lock button to be visible")
async expectTopBarLockButtonToBeVisible() {
await expect(this.topbarLockButton).toBeVisible();
}

@step("Check if the error message is the same as expected")
async checkErrorMessage(errorMessage: string | null) {
if (errorMessage !== null) {
await this.inputError.waitFor({ state: "visible" });
const errorText: any = await this.inputError.textContent();
const normalize = (str: string) => str.replace(/\u00A0/g, " ").trim();
expect(normalize(errorText)).toEqual(normalize(errorMessage));
}
@step("Expect top bar lock button not to be visible")
async expectTopBarLockButtonNotToBeVisible() {
await expect(this.topbarLockButton).not.toBeVisible();
}

@step("Lock app")
async lockApp() {
async lockAppFromTopBar() {
await this.topbarLockButton.click();
}

@step("Open send modal")
async openSendModal() {
await this.drawerSendButton.click();
}

@step("Open receive modal")
async openReceiveModal() {
await this.drawerReceiveButton.click();
@step("open Help")
async openHelp() {
await this.topbarHelpButton.click();
}

@step("wait for loading spinner to have disappeared")
async waitForLoadingSpinnerToHaveDisappeared() {
await this.loadingSpinner.waitFor({ state: "detached" });
}

@step("Go to swap")
async goToSwap() {
await this.drawerSwapButton.click();
}
}
13 changes: 13 additions & 0 deletions apps/ledger-live-desktop/tests/page/lockscreen.page.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { AppPage } from "tests/page/abstractClasses";
import { step } from "tests/misc/reporters/step";

export class LockscreenPage extends AppPage {
readonly container = this.page.getByTestId("lockscreen-container");
private passwordInput = this.page.getByTestId("lockscreen-password-input");
private forgottenButton = this.page.getByTestId("lockscreen-forgotten-button");
private loginButton = this.page.getByTestId("lockscreen-login-button");
readonly inputError = this.page.locator("id=input-error"); // no data-testid because css style is applied
readonly logo = this.page.getByTestId("logo");

async login(password: string) {
await this.container.waitFor({ state: "visible" });
Expand All @@ -15,4 +18,14 @@ export class LockscreenPage extends AppPage {
async lostPassword() {
await this.forgottenButton.click();
}

@step("Check input error state visibibility: $0")
async checkInputErrorVisibibility(expectedState: "visible" | "hidden") {
await this.inputError.waitFor({ state: expectedState });
}

@step("Expect Ledger Logo to be visible")
async expectLogoToBeVisible() {
await this.logo.waitFor({ state: "visible" });
}
}
37 changes: 37 additions & 0 deletions apps/ledger-live-desktop/tests/page/modal/send.modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export class SendModal extends Modal {
private noTagButton = this.page.getByRole("button", { name: "Don’t add Tag" });
private ENSAddressLabel = this.page.getByTestId("ens-address-sendModal");

readonly inputError = this.page.locator("id=input-error"); // no data-testid because css style is applied
readonly insufficientFundsWarning = this.page.getByTestId("insufficient-funds-warning");
readonly inputWarning = this.page.locator("id=input-warning");

async selectAccount(name: string) {
await this.drowdownAccount.click();
await this.page.getByText(name).click();
Expand Down Expand Up @@ -133,4 +137,37 @@ export class SendModal extends Modal {
await this.cryptoAmountField.fill(amount);
}
}

@step("Check input error state visibibility: $0")
async checkInputErrorVisibibility(expectedState: "visible" | "hidden") {
await this.inputError.waitFor({ state: expectedState });
}

@step("Check if the error message is the same as expected")
async checkErrorMessage(errorMessage: string | null) {
if (errorMessage !== null) {
await this.inputError.waitFor({ state: "visible" });
const errorText: any = await this.inputError.textContent();
const normalize = (str: string) => str.replace(/\u00A0/g, " ").trim();
expect(normalize(errorText)).toEqual(normalize(errorMessage));
}
}

@step("Check warning message")
async checkAmoutWarningMessage(expectedWarningMessage: RegExp) {
if (expectedWarningMessage !== null) {
await expect(this.insufficientFundsWarning).toBeVisible();
const warningText = await this.insufficientFundsWarning.innerText();
expect(warningText).toMatch(expectedWarningMessage);
}
}

@step("Check warning message")
async checkInputWarningMessage(expectedWarningMessage: string | null) {
if (expectedWarningMessage !== null) {
await expect(this.inputWarning).toBeVisible();
const warningText = await this.inputWarning.innerText();
expect(warningText).toMatch(expectedWarningMessage);
}
}
}
5 changes: 5 additions & 0 deletions apps/ledger-live-desktop/tests/page/portfolio.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,9 @@ export class PortfolioPage extends AppPage {
const operationRow = this.operationRows.first();
await expect(operationRow).toContainText(counterValue);
}

@step("Wait for balance to be visible")
async expectBalanceVisibility() {
await this.totalBalance.waitFor({ state: "visible" });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ test("Countervalues: at least one call is made and successful to the API", async
});
});

await layout.topbarSynchronizeButton.click();
await layout.syncAccounts();

expect(await firstSuccessfulQuery).toBeDefined();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ test("Send flow", async ({ page }) => {
const sendModal = new SendModal(page);

await test.step("can open send modal and use a qr code from camera", async () => {
await layout.openSendModal();
await layout.openSendModalFromSideBar();
await sendModal.container.waitFor({ state: "visible" });
const sendButtonLoader = sendModal.container
.locator("id=send-recipient-continue-button")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ test("Send flow", async ({ page }) => {
const sendModal = new SendModal(page);

await test.step("can open send modal and max network fees label is shown", async () => {
await layout.openSendModal();
await layout.openSendModalFromSideBar();
await sendModal.container.waitFor({ state: "visible" });
const sendButtonLoader = sendModal.container
.locator("id=send-recipient-continue-button")
Expand Down
10 changes: 5 additions & 5 deletions apps/ledger-live-desktop/tests/specs/general/layout.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ test("Layout @smoke", async ({ page }) => {
const settingsPage = new SettingsPage(page);

await test.step("can open send modal", async () => {
await layout.openSendModal();
await layout.openSendModalFromSideBar();
await sendModal.container.waitFor({ state: "visible" });
const sendButtonLoader = sendModal.container
.locator("id=send-recipient-continue-button")
Expand All @@ -27,7 +27,7 @@ test("Layout @smoke", async ({ page }) => {
});

await test.step("can open receive modal", async () => {
await layout.openReceiveModal();
await layout.openReceiveModalFromSideBar();
await receiveModal.container.waitFor({ state: "visible" });
await expect.soft(sendModal.container).toHaveScreenshot("receive-modal.png");
await receiveModal.close();
Expand All @@ -52,7 +52,7 @@ test("Layout @smoke", async ({ page }) => {
await settingsPage.experimentalTab.click();
await settingsPage.enableDevMode();
await layout.goToPortfolio();
await layout.drawerExperimentalButton.click();
await layout.goToExperimentalFeatures();
await expect.soft(page).toHaveScreenshot("experimental-features.png");
});

Expand All @@ -72,14 +72,14 @@ test("Layout @smoke", async ({ page }) => {
});

await test.step("can collapse the main sidebar", async () => {
await layout.drawerCollapseButton.click();
await layout.closeSideBar();
await expect.soft(page).toHaveScreenshot("collapse-sidebar.png", {
mask: [page.locator("canvas"), layout.marketPerformanceWidget],
});
});

await test.step("can display the help modal", async () => {
await layout.topbarHelpButton.click();
await layout.openHelp();
await expect.soft(drawer.content).toHaveScreenshot("help-drawer.png");
});
});
Loading

0 comments on commit 762b976

Please sign in to comment.