Skip to content

Commit

Permalink
Merge pull request #8648 from LedgerHQ/support/qaa_309_detox_speculos…
Browse files Browse the repository at this point in the history
…_verify_address

[QAA-309][Detox][Speculos] Verify address test
  • Loading branch information
abdurrahman-ledger authored Dec 12, 2024
2 parents a4224a2 + 60882f1 commit d2b4cb5
Show file tree
Hide file tree
Showing 27 changed files with 230 additions and 27 deletions.
23 changes: 2 additions & 21 deletions apps/ledger-live-desktop/tests/page/speculos.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { step } from "tests/misc/reporters/step";
import {
pressBoth,
pressUntilTextFound,
waitFor,
containsSubstringInEvent,
activateLedgerSync,
expectValidAddressDevice,
} from "@ledgerhq/live-common/e2e/speculos";
import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
import { expect } from "@playwright/test";
Expand All @@ -29,26 +29,7 @@ import { delegateSolana, sendSolana } from "tests/families/solana";
export class SpeculosPage extends AppPage {
@step("Verify receive address correctness on device")
async expectValidAddressDevice(account: Account, addressDisplayed: string) {
let deviceLabels: string[];

switch (account.currency) {
case Currency.SOL:
deviceLabels = [DeviceLabels.PUBKEY, DeviceLabels.APPROVE, DeviceLabels.REJECT];
break;
case Currency.DOT:
case Currency.ATOM:
deviceLabels = [DeviceLabels.ADDRESS, DeviceLabels.CAPS_APPROVE, DeviceLabels.CAPS_REJECT];
break;
default:
deviceLabels = [DeviceLabels.ADDRESS, DeviceLabels.APPROVE, DeviceLabels.REJECT];
break;
}

await waitFor(deviceLabels[0]);
const events = await pressUntilTextFound(deviceLabels[1]);
const isAddressCorrect = containsSubstringInEvent(addressDisplayed, events);
expect(isAddressCorrect).toBeTruthy();
await pressBoth();
await expectValidAddressDevice(account, addressDisplayed);
}

@step("Activate Ledger Sync")
Expand Down
6 changes: 6 additions & 0 deletions apps/ledger-live-mobile/e2e/page/accounts/account.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default class AccountPage {
operationHistorySectionId = (accountId: string) => `operations-history-${accountId}`;
accountScreenScrollView = "account-screen-scrollView";
accountAdvancedLogsId = "account-advanced-logs";
receiveButton = () => getElementById("account-quick-action-button-Receive");

@Step("Open account settings")
async openAccountSettings() {
Expand Down Expand Up @@ -54,4 +55,9 @@ export default class AccountPage {
const advancedLogsJson = advancedLogsText ? JSON.parse(advancedLogsText) : null;
jestExpect(advancedLogsJson).toHaveProperty("index", indexNumber);
}

@Step("Tap on receive button")
async tapReceive() {
await tapByElement(this.receiveButton());
}
}
2 changes: 2 additions & 0 deletions apps/ledger-live-mobile/e2e/page/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import ReceivePage from "./trade/receive.page";
import SendPage from "./trade/send.page";
import SettingsGeneralPage from "./settings/settingsGeneral.page";
import SettingsPage from "./settings/settings.page";
import SpeculosPage from "./speculos.page";
import StakePage from "./trade/stake.page";
import SwapPage from "./trade/swap.page";
import TransfertMenuDrawer from "./wallet/transferMenu.drawer";
Expand Down Expand Up @@ -75,6 +76,7 @@ export class Application {
public send = new SendPage();
public settings = new SettingsPage();
public settingsGeneral = new SettingsGeneralPage();
public speculos = new SpeculosPage();
public stake = new StakePage();
public swap = new SwapPage();
public transfertMenu = new TransfertMenuDrawer();
Expand Down
9 changes: 9 additions & 0 deletions apps/ledger-live-mobile/e2e/page/speculos.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { expectValidAddressDevice } from "@ledgerhq/live-common/e2e/speculos";
import { Account } from "@ledgerhq/live-common/e2e/enum/Account";

export default class SpeculosPage {
@Step("Verify receive address correctness on device")
async expectValidAddressDevice(account: Account, addressDisplayed: string) {
await expectValidAddressDevice(account, addressDisplayed);
}
}
31 changes: 31 additions & 0 deletions apps/ledger-live-mobile/e2e/page/trade/receive.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getElementByText,
getTextOfElement,
openDeeplink,
scrollToId,
tapById,
waitForElementById,
} from "../../helpers";
Expand Down Expand Up @@ -32,10 +33,17 @@ export default class ReceivePage {
step2HeaderTitle = () => getElementById(this.step2HeaderTitleId);
titleReceiveConfirmationPageId = (t: string) => `receive-confirmation-title-${t}`;
accountNameReceiveId = (t: string) => `receive-account-name-${t}`;
receivePageScrollViewId = "receive-screen-scrollView";

step2Accounts = () => getElementById("receive-header-step2-accounts");
step2Networks = () => getElementById("receive-header-step2-networks");

tronNewAddressWarningId = "tron-receive-newAddress-warning";
tronNewAddressWarningDescription = () =>
getElementById(`${this.tronNewAddressWarningId}-description`);
tronNewAddressWarningText =
"You first need to send at least 0.1 TRX to this address to activate it.";

async openViaDeeplink() {
await openDeeplink(baseLink);
}
Expand Down Expand Up @@ -83,6 +91,7 @@ export default class ReceivePage {
await tapById(CurrencyRowId);
}

@Step("Accept to verify address")
async selectVerifyAddress() {
await waitForElementById(this.buttonVerifyAddressId);
await tapById(this.buttonVerifyAddressId);
Expand All @@ -98,6 +107,12 @@ export default class ReceivePage {
jestExpect(await getTextOfElement(this.accountAddress)).toEqual(address);
}

@Step("Get the fresh address displayed")
async getFreshAddressDisplayed() {
await waitForElementById(this.accountFreshAddress);
return await getTextOfElement(this.accountFreshAddress);
}

async expectNumberOfAccountInListIsDisplayed(currencyName: string, accountNumber: number) {
//set "account" in plural or not in fonction of number account
const accountCount: string = accountNumber + " account" + (accountNumber > 1 ? "s" : "");
Expand Down Expand Up @@ -141,6 +156,7 @@ export default class ReceivePage {
return tapById(this.noVerifyValidateButton);
}

@Step("Expect account receive page is displayed")
async expectReceivePageIsDisplayed(tickerName: string, accountName: string) {
const receiveTitleTickerId = this.titleReceiveConfirmationPageId(tickerName);
const accountNameId = this.accountNameReceiveId(accountName);
Expand All @@ -150,6 +166,21 @@ export default class ReceivePage {
await expect(getElementById(accountNameId)).toBeVisible();
}

@Step("Expect given address is displayed on receive page")
async expectAddressIsCorrect(address: string) {
await expect(getElementById(this.accountAddress)).toHaveText(address);
}

@Step("Expect tron new address warning")
async expectTronNewAddressWarning() {
await scrollToId(this.tronNewAddressWarningId, this.receivePageScrollViewId);
await expect(getElementById(this.tronNewAddressWarningId)).toBeVisible();
await expect(this.tronNewAddressWarningDescription()).toHaveText(
this.tronNewAddressWarningText,
);
}

@Step("Refuse to verify address")
async doNotVerifyAddress() {
await this.selectDontVerifyAddress();
await this.selectReconfirmDontVerify();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { CLI } from "../../../utils/cliUtils";
import { Application } from "../../../page";
import { Account } from "@ledgerhq/live-common/e2e/enum/Account";

export async function runVerifyAddressTest(account: Account, tmsLink: string) {
const app = new Application();

describe(`Verify Address - ${account.currency.name}`, () => {
beforeAll(async () => {
await app.init({
speculosApp: account.currency.speculosApp,
cliCommands: [
() => {
return CLI.liveData({
currency: account.currency.currencyId,
index: account.index,
appjson: app.userdataPath,
add: true,
});
},
],
});
await app.portfolio.waitForPortfolioPageToLoad();
});

$TmsLink(tmsLink);
it(`Verify address on ${account.currency.name}`, async () => {
await app.accounts.openViaDeeplink();
await app.common.goToAccountByName(account.accountName);
await app.account.tapReceive();
await app.receive.selectVerifyAddress();
const displayedAddress = await app.receive.getFreshAddressDisplayed();
await app.speculos.expectValidAddressDevice(account, displayedAddress);
await app.receive.expectReceivePageIsDisplayed(account.currency.ticker, account.accountName);
await app.receive.expectAddressIsCorrect(displayedAddress);
});

afterAll(async () => {
await app?.common.removeSpeculos();
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { runVerifyAddressTest } from "./verifyAddress";
import { Account } from "@ledgerhq/live-common/e2e/enum/Account";

runVerifyAddressTest(Account.ATOM_1, "B2CQA-2560, B2CQA-2694");
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { runVerifyAddressTest } from "./verifyAddress";
import { Account } from "@ledgerhq/live-common/e2e/enum/Account";

runVerifyAddressTest(Account.BCH_1, "B2CQA-2558, B2CQA-2693");
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { runVerifyAddressTest } from "./verifyAddress";
import { Account } from "@ledgerhq/live-common/e2e/enum/Account";

runVerifyAddressTest(Account.BSC_1, "B2CQA-2686, B2CQA-2696");
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { runVerifyAddressTest } from "./verifyAddress";
import { Account } from "@ledgerhq/live-common/e2e/enum/Account";

runVerifyAddressTest(Account.BTC_NATIVE_SEGWIT_1, "B2CQA-2559, B2CQA-2687");
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { runVerifyAddressTest } from "./verifyAddress";
import { Account } from "@ledgerhq/live-common/e2e/enum/Account";

runVerifyAddressTest(Account.DOT_1, "B2CQA-2562, B2CQA-2691");
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { runVerifyAddressTest } from "./verifyAddress";
import { Account } from "@ledgerhq/live-common/e2e/enum/Account";

runVerifyAddressTest(Account.ETH_1, "B2CQA-2561, B2CQA-2688");
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { runVerifyAddressTest } from "./verifyAddress";
import { Account } from "@ledgerhq/live-common/e2e/enum/Account";

runVerifyAddressTest(Account.SOL_1, "B2CQA-2563, B2CQA-2689");
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { runVerifyAddressTest } from "./verifyAddress";
import { Account } from "@ledgerhq/live-common/e2e/enum/Account";

runVerifyAddressTest(Account.TRX_1, "B2CQA-2565, B2CQA-2690");
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { runVerifyAddressTest } from "./verifyAddress";
import { Account } from "@ledgerhq/live-common/e2e/enum/Account";

runVerifyAddressTest(Account.XRP_1, "B2CQA-2566, B2CQA-2692");
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { runVerifyAddressTest } from "./verifyAddress";
import { Account } from "@ledgerhq/live-common/e2e/enum/Account";

runVerifyAddressTest(Account.XTZ_1, "B2CQA-2564, B2CQA-2695");
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { CLI } from "../../../utils/cliUtils";
import { Application } from "../../../page";
import { Account } from "@ledgerhq/live-common/e2e/enum/Account";

const app = new Application();
const account = Account.TRX_3;

describe(`Verify Address warnings - ${account.currency.name}`, () => {
beforeAll(async () => {
await app.init({
speculosApp: account.currency.speculosApp,
cliCommands: [
() => {
return CLI.liveData({
currency: account.currency.currencyId,
index: account.index,
appjson: app.userdataPath,
add: true,
});
},
],
});
await app.portfolio.waitForPortfolioPageToLoad();
});

$TmsLink("B2CQA-1551");
it(`Verify address warning for ${account.currency.name}`, async () => {
await app.accounts.openViaDeeplink();
await app.common.goToAccountByName(account.accountName);
await app.account.tapReceive();
await app.receive.doNotVerifyAddress();
await app.receive.expectReceivePageIsDisplayed(account.currency.ticker, account.accountName);
await app.receive.expectTronNewAddressWarning();
});

afterAll(async () => {
await app?.common.removeSpeculos();
});
});
12 changes: 9 additions & 3 deletions apps/ledger-live-mobile/src/components/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type Props = {
learnMoreUrl?: string;
learnMoreIsInternal?: boolean;
learnMoreIcon?: IconType;
testID?: string;
};

const alertPropsByType: Record<
Expand Down Expand Up @@ -139,6 +140,7 @@ export default function Alert(props: Props) {
learnMoreIsInternal = false,
learnMoreIcon,
learnMoreTransValues,
testID,
} = props;

const dismissedBanners = useSelector(dismissedBannersSelector);
Expand All @@ -164,10 +166,14 @@ export default function Alert(props: Props) {

return !isDismissed ? (
<BaseAlert {...alertProps}>
<Container>
{title && <BaseAlert.BodyText>{title}</BaseAlert.BodyText>}
<Container testID={testID}>
{title && <BaseAlert.BodyText testID={`${testID}-title`}>{title}</BaseAlert.BodyText>}
{description && (
<BaseAlert.BodyText mt={title ? 2 : undefined} mb={hasLearnMore ? 2 : undefined}>
<BaseAlert.BodyText
testID={`${testID}-description`}
mt={title ? 2 : undefined}
mb={hasLearnMore ? 2 : undefined}
>
{description}
</BaseAlert.BodyText>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ export const FabAccountMainActionsComponent: React.FC<FabAccountActionsProps> =
numColumns={2}
id="two_columns"
key="two_columns"
testID="account-quick-action-button"
/>
) : (
<QuickActionList
data={quickActions}
numColumns={3}
id="three_columns"
key="three_columns"
testID="account-quick-action-button"
/>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ const FabAssetActionsComponent: React.FC<Props> = ({ currency, accounts, default
numColumns={2}
id="asset_two_columns"
key="asset_two_columns"
testID="asset-quick-action-button"
/>
) : (
<QuickActionList
data={quickActions}
numColumns={3}
id="asset_three_columns"
key="asset_three_columns"
testID="asset-quick-action-button"
/>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const MarketQuickActions = (quickActionsProps: Required<QuickActionProps>
key={quickActionsData.length}
numColumns={quickActionsData.length}
id="asset_five_columns"
testID="market-quick-action-button"
/>
</Flex>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ export default function ReceiveConfirmationPostAlert({ mainAccount }: Props) {
return (
<>
{mainAccount.operationsCount === 0 ? (
<Alert type="warning" learnMoreUrl={urls.errors.TronSendTrc20ToNewAccountForbidden}>
<Alert
type="warning"
learnMoreUrl={urls.errors.TronSendTrc20ToNewAccountForbidden}
testID="tron-receive-newAddress-warning"
>
<Trans i18nKey="tron.receive.newAddressTRC20" />
</Alert>
) : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,14 @@ function PortfolioQuickActionsBar() {
},
].filter(<T extends QuickActionButtonProps>(v: T | undefined): v is T => !!v);

return <QuickActionList data={quickActionsData} numColumns={5} id="asset_five_columns" />;
return (
<QuickActionList
data={quickActionsData}
numColumns={5}
id="asset_five_columns"
testID="portoflio-quick-action-button"
/>
);
}

export default PortfolioQuickActionsBar;
Loading

0 comments on commit d2b4cb5

Please sign in to comment.