diff --git a/.github/workflows/test-mobile-e2e-reusable.yml b/.github/workflows/test-mobile-e2e-reusable.yml
index a7fbb34e8a1e..24ec324da54e 100644
--- a/.github/workflows/test-mobile-e2e-reusable.yml
+++ b/.github/workflows/test-mobile-e2e-reusable.yml
@@ -52,10 +52,15 @@ permissions:
id-token: write
contents: read
+env:
+ SPECULOS_IMAGE_TAG: ghcr.io/ledgerhq/speculos:0.9.5
+ COINAPPS: ${{ github.workspace }}/coin-apps
+
jobs:
detox-tests-ios:
name: "LLM - iOS Detox Tests"
runs-on: [m1, ARM64]
+ if: ${{ !inputs.speculos_tests }}
env:
NODE_OPTIONS: "--max-old-space-size=7168"
LANG: en_US.UTF-8
@@ -89,7 +94,7 @@ jobs:
id: detox-build
with:
path: ${{ github.workspace }}/apps/ledger-live-mobile/ios/build/Build/Products/Release-iphonesimulator
- key: ${{ runner.os }}-detox-${{ hashFiles('apps/ledger-live-mobile/ios/Podfile.lock', 'apps/ledger-live-mobile/ios/ledgerlivemobile.xcodeproj/project.pbxproj', 'apps/ledger-live-mobile/detox.config.js') }}
+ key: ${{ runner.os }}-detox-${{ hashFiles('apps/ledger-live-mobile/ios/Podfile.lock', 'apps/ledger-live-mobile/ios/ledgerlivemobile.xcodeproj/project.pbxproj', 'apps/ledger-live-mobile/detox.config.js', 'apps/ledger-live-mobile/.env.mock') }}
accessKey: ${{ env.AWS_ACCESS_KEY_ID }}
secretKey: ${{ env.AWS_SECRET_ACCESS_KEY }}
sessionToken: ${{ env.AWS_SESSION_TOKEN}}
@@ -121,10 +126,21 @@ jobs:
- name: Build JS Bundle app for Detox test run
if: steps.detox-build.outputs.cache-hit == 'true'
run: pnpm mobile e2e:ci -p ios --bundle
+ - name: Setup Speculos image and Coin Apps
+ if: ${{ inputs.speculos_tests }}
+ uses: LedgerHQ/ledger-live/tools/actions/composites/setup-speculos_image@develop
+ with:
+ coinapps_path: ${{ env.COINAPPS }}
+ speculos_tag: ${{ env.SPECULOS_IMAGE_TAG }}
+ bot_id: ${{ secrets.GH_BOT_APP_ID }}
+ bot_key: ${{ secrets.GH_BOT_PRIVATE_KEY }}
- name: Test iOS app
id: detox
timeout-minutes: 75
- run: pnpm mobile e2e:ci -p ios -t
+ run: pnpm mobile e2e:ci -p ios -t $([[ "$INPUT_SPECULOS" == "true" ]] && printf %s '--speculos')
+ env:
+ SEED: ${{ secrets.SEED_QAA_B2C }}
+ INPUT_SPECULOS: ${{ inputs.speculos_tests }}
- name: Delete iOS simulator
if: ${{ always() && steps.simulator.outputs.id }}
run: |
@@ -180,8 +196,6 @@ jobs:
AVD_CORES: 4
AVD_RAM_SIZE: 4096M
AVD_OPTIONS: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
- SPECULOS_IMAGE_TAG: ghcr.io/ledgerhq/speculos:0.9.5
- COINAPPS: ${{ github.workspace }}/coin-apps
outputs:
status: ${{ steps.detox.outcome }}
steps:
diff --git a/apps/ledger-live-desktop/tests/component/drawer.component.ts b/apps/ledger-live-desktop/tests/component/drawer.component.ts
index 5aeb8d1b4527..8a2d0c4eadbd 100644
--- a/apps/ledger-live-desktop/tests/component/drawer.component.ts
+++ b/apps/ledger-live-desktop/tests/component/drawer.component.ts
@@ -1,6 +1,6 @@
import { Component } from "tests/page/abstractClasses";
import { step } from "tests/misc/reporters/step";
-import { Account } from "tests/enum/Account";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
export class Drawer extends Component {
readonly content = this.page.getByTestId("drawer-content");
diff --git a/apps/ledger-live-desktop/tests/fixtures/common.ts b/apps/ledger-live-desktop/tests/fixtures/common.ts
index 18c0c3fe7b83..c8e1ea39e646 100644
--- a/apps/ledger-live-desktop/tests/fixtures/common.ts
+++ b/apps/ledger-live-desktop/tests/fixtures/common.ts
@@ -11,7 +11,7 @@ import { safeAppendFile } from "tests/utils/fileUtils";
import { launchApp } from "tests/utils/electronUtils";
import { captureArtifacts } from "tests/utils/allureUtils";
import { randomUUID } from "crypto";
-import { AppInfos } from "tests/enum/AppInfos";
+import { AppInfos } from "@ledgerhq/live-common/e2e/enum/AppInfos";
import { lastValueFrom, Observable } from "rxjs";
import { commandCLI } from "tests/utils/cliUtils";
import { registerSpeculosTransport } from "@ledgerhq/live-cli/src/live-common-setup";
diff --git a/apps/ledger-live-desktop/tests/models/Delegate.ts b/apps/ledger-live-desktop/tests/models/Delegate.ts
index f4142fb9b65e..60811212792c 100644
--- a/apps/ledger-live-desktop/tests/models/Delegate.ts
+++ b/apps/ledger-live-desktop/tests/models/Delegate.ts
@@ -1,4 +1,4 @@
-import { Account } from "../enum/Account";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
export class Delegate {
constructor(
diff --git a/apps/ledger-live-desktop/tests/models/Swap.ts b/apps/ledger-live-desktop/tests/models/Swap.ts
index 8e9affb5cf7e..db010055ff56 100644
--- a/apps/ledger-live-desktop/tests/models/Swap.ts
+++ b/apps/ledger-live-desktop/tests/models/Swap.ts
@@ -1,7 +1,7 @@
import { Transaction } from "tests/models/Transaction";
-import { Fee } from "tests/enum/Fee";
-import { Account } from "../enum/Account";
-import { Provider, Rate } from "../enum/Swap";
+import { Fee } from "@ledgerhq/live-common/e2e/enum/Fee";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
+import { Provider, Rate } from "@ledgerhq/live-common/e2e/enum/Swap";
export class Swap extends Transaction {
provider: Provider;
diff --git a/apps/ledger-live-desktop/tests/models/Transaction.ts b/apps/ledger-live-desktop/tests/models/Transaction.ts
index 08333b27e952..e66649adc9b1 100644
--- a/apps/ledger-live-desktop/tests/models/Transaction.ts
+++ b/apps/ledger-live-desktop/tests/models/Transaction.ts
@@ -1,5 +1,5 @@
-import { Fee } from "tests/enum/Fee";
-import { Account } from "../enum/Account";
+import { Fee } from "@ledgerhq/live-common/e2e/enum/Fee";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
export class Transaction {
constructor(
diff --git a/apps/ledger-live-desktop/tests/page/account.page.ts b/apps/ledger-live-desktop/tests/page/account.page.ts
index af0b864f1d30..2bf10051e18e 100644
--- a/apps/ledger-live-desktop/tests/page/account.page.ts
+++ b/apps/ledger-live-desktop/tests/page/account.page.ts
@@ -1,7 +1,7 @@
import { expect } from "@playwright/test";
import { step } from "tests/misc/reporters/step";
import { AppPage } from "tests/page/abstractClasses";
-import { Account } from "tests/enum/Account";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
export class AccountPage extends AppPage {
readonly settingsButton = this.page.getByTestId("account-settings-button");
diff --git a/apps/ledger-live-desktop/tests/page/accounts.page.ts b/apps/ledger-live-desktop/tests/page/accounts.page.ts
index ebfa8cf9c2e8..537e6586aeb5 100644
--- a/apps/ledger-live-desktop/tests/page/accounts.page.ts
+++ b/apps/ledger-live-desktop/tests/page/accounts.page.ts
@@ -1,7 +1,7 @@
import { expect } from "@playwright/test";
import { step } from "tests/misc/reporters/step";
import { AppPage } from "tests/page/abstractClasses";
-import { Currency } from "../enum/Currency";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
export class AccountsPage extends AppPage {
private addAccountButton = this.page.getByTestId("accounts-add-account-button");
diff --git a/apps/ledger-live-desktop/tests/page/drawer/asset.drawer.ts b/apps/ledger-live-desktop/tests/page/drawer/asset.drawer.ts
index c3761fb7510f..02343f8dd2ec 100644
--- a/apps/ledger-live-desktop/tests/page/drawer/asset.drawer.ts
+++ b/apps/ledger-live-desktop/tests/page/drawer/asset.drawer.ts
@@ -1,7 +1,7 @@
import { step } from "tests/misc/reporters/step";
import { Drawer } from "tests/component/drawer.component";
-import { Currency } from "tests/enum/Currency";
-import { Account } from "tests/enum/Account";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
export class AssetDrawer extends Drawer {
private assetInput = this.page.getByTestId("select-asset-drawer-search-input");
diff --git a/apps/ledger-live-desktop/tests/page/drawer/delegate.drawer.ts b/apps/ledger-live-desktop/tests/page/drawer/delegate.drawer.ts
index bec74710af40..3312d8d8497c 100644
--- a/apps/ledger-live-desktop/tests/page/drawer/delegate.drawer.ts
+++ b/apps/ledger-live-desktop/tests/page/drawer/delegate.drawer.ts
@@ -1,6 +1,6 @@
import { step } from "tests/misc/reporters/step";
import { Drawer } from "tests/component/drawer.component";
-import { Currency } from "tests/enum/Currency";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
import { Delegate } from "tests/models/Delegate";
import { expect } from "@playwright/test";
import { Transaction } from "tests/models/Transaction";
diff --git a/apps/ledger-live-desktop/tests/page/modal/add.account.modal.ts b/apps/ledger-live-desktop/tests/page/modal/add.account.modal.ts
index 241c9bc619c8..b37b8c894ee1 100644
--- a/apps/ledger-live-desktop/tests/page/modal/add.account.modal.ts
+++ b/apps/ledger-live-desktop/tests/page/modal/add.account.modal.ts
@@ -1,8 +1,8 @@
import { expect } from "@playwright/test";
import { Modal } from "../../component/modal.component";
import { step } from "tests/misc/reporters/step";
-import { Account } from "tests/enum/Account";
-import { Currency } from "tests/enum/Currency";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
export class AddAccountModal extends Modal {
private selectAccount = this.page.locator("text=Choose a crypto asset"); // FIXME: I need an id
diff --git a/apps/ledger-live-desktop/tests/page/modal/receive.modal.ts b/apps/ledger-live-desktop/tests/page/modal/receive.modal.ts
index 10c88bb0694d..afd6f1a40d82 100644
--- a/apps/ledger-live-desktop/tests/page/modal/receive.modal.ts
+++ b/apps/ledger-live-desktop/tests/page/modal/receive.modal.ts
@@ -1,7 +1,7 @@
import { expect } from "@playwright/test";
import { Modal } from "../../component/modal.component";
import { step } from "tests/misc/reporters/step";
-import { Account } from "tests/enum/Account";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
export class ReceiveModal extends Modal {
private skipDeviceButton = this.page.getByTestId("receive-connect-device-skip-device-button");
diff --git a/apps/ledger-live-desktop/tests/page/speculos.page.ts b/apps/ledger-live-desktop/tests/page/speculos.page.ts
index bb64553da851..2c74010c2bfc 100644
--- a/apps/ledger-live-desktop/tests/page/speculos.page.ts
+++ b/apps/ledger-live-desktop/tests/page/speculos.page.ts
@@ -6,12 +6,12 @@ import {
waitFor,
containsSubstringInEvent,
} from "@ledgerhq/live-common/e2e/speculos";
-import { Account } from "../enum/Account";
+import { Account } from "@ledgerhq/live-common/e2e/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 { DeviceLabels } from "@ledgerhq/live-common/e2e/enum/DeviceLabels";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
import { Swap } from "tests/models/Swap";
import { extractNumberFromString } from "tests/utils/textParserUtils";
export class SpeculosPage extends AppPage {
diff --git a/apps/ledger-live-desktop/tests/page/swap.page.ts b/apps/ledger-live-desktop/tests/page/swap.page.ts
index b8332f731432..650f9e3b7531 100644
--- a/apps/ledger-live-desktop/tests/page/swap.page.ts
+++ b/apps/ledger-live-desktop/tests/page/swap.page.ts
@@ -3,7 +3,7 @@ import { waitFor } from "../utils/waitFor";
import { step } from "tests/misc/reporters/step";
import { ElectronApplication, expect } from "@playwright/test";
import { capitalizeFirstLetter } from "tests/utils/textParserUtils";
-import { Account } from "tests/enum/Account";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
import { ChooseAssetDrawer } from "tests/page/drawer/choose.asset.drawer";
export class SwapPage extends AppPage {
diff --git a/apps/ledger-live-desktop/tests/specs/speculos/add.account.spec.ts b/apps/ledger-live-desktop/tests/specs/speculos/add.account.spec.ts
index fcfa988b19bb..187dc09ebfe7 100644
--- a/apps/ledger-live-desktop/tests/specs/speculos/add.account.spec.ts
+++ b/apps/ledger-live-desktop/tests/specs/speculos/add.account.spec.ts
@@ -1,5 +1,5 @@
import { test } from "../../fixtures/common";
-import { Currency } from "../../enum/Currency";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
import { addTmsLink } from "tests/utils/allureUtils";
import { getDescription } from "../../utils/customJsonReporter";
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 e6900a7163af..d7258334afb2 100644
--- a/apps/ledger-live-desktop/tests/specs/speculos/delegate.spec.ts
+++ b/apps/ledger-live-desktop/tests/specs/speculos/delegate.spec.ts
@@ -1,5 +1,5 @@
import { test } from "../../fixtures/common";
-import { Account } from "../../enum/Account";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
import { Delegate } from "../../models/Delegate";
import { addTmsLink } from "tests/utils/allureUtils";
import { getDescription } from "../../utils/customJsonReporter";
diff --git a/apps/ledger-live-desktop/tests/specs/speculos/delete.account.spec.ts b/apps/ledger-live-desktop/tests/specs/speculos/delete.account.spec.ts
index 85b4c5f39d9d..eaab81c0cde5 100644
--- a/apps/ledger-live-desktop/tests/specs/speculos/delete.account.spec.ts
+++ b/apps/ledger-live-desktop/tests/specs/speculos/delete.account.spec.ts
@@ -1,5 +1,5 @@
import { test } from "../../fixtures/common";
-import { Account } from "../../enum/Account";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
import { addTmsLink } from "tests/utils/allureUtils";
import { getDescription } from "../../utils/customJsonReporter";
import { commandCLI } from "tests/utils/cliUtils";
diff --git a/apps/ledger-live-desktop/tests/specs/speculos/manage.ledgersync.spec.ts b/apps/ledger-live-desktop/tests/specs/speculos/manage.ledgersync.spec.ts
index 1291396fe02e..abd0ab3ede04 100644
--- a/apps/ledger-live-desktop/tests/specs/speculos/manage.ledgersync.spec.ts
+++ b/apps/ledger-live-desktop/tests/specs/speculos/manage.ledgersync.spec.ts
@@ -1,5 +1,5 @@
import { test } from "../../fixtures/common";
-import { AppInfos } from "tests/enum/AppInfos";
+import { AppInfos } from "@ledgerhq/live-common/e2e/enum/AppInfos";
import { addTmsLink } from "tests/utils/allureUtils";
import { getDescription } from "../../utils/customJsonReporter";
diff --git a/apps/ledger-live-desktop/tests/specs/speculos/receive.address.spec.ts b/apps/ledger-live-desktop/tests/specs/speculos/receive.address.spec.ts
index 5ecf99b5bc6e..6bb844f48edb 100644
--- a/apps/ledger-live-desktop/tests/specs/speculos/receive.address.spec.ts
+++ b/apps/ledger-live-desktop/tests/specs/speculos/receive.address.spec.ts
@@ -1,5 +1,5 @@
import { test } from "../../fixtures/common";
-import { Account } from "../../enum/Account";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
import { addTmsLink } from "tests/utils/allureUtils";
import { getDescription } from "../../utils/customJsonReporter";
import { commandCLI } from "tests/utils/cliUtils";
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 cdb5b54295c9..2f9200d84c51 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
@@ -1,6 +1,6 @@
import { test } from "../../fixtures/common";
-import { Account } from "../../enum/Account";
-import { Fee } from "../../enum/Fee";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
+import { Fee } from "@ledgerhq/live-common/e2e/enum/Fee";
import { Transaction } from "../../models/Transaction";
import { addTmsLink } from "tests/utils/allureUtils";
import { getDescription } from "../../utils/customJsonReporter";
diff --git a/apps/ledger-live-desktop/tests/specs/speculos/settings.spec.ts b/apps/ledger-live-desktop/tests/specs/speculos/settings.spec.ts
index e0887a23093e..d0700b121208 100644
--- a/apps/ledger-live-desktop/tests/specs/speculos/settings.spec.ts
+++ b/apps/ledger-live-desktop/tests/specs/speculos/settings.spec.ts
@@ -1,7 +1,7 @@
import { test } from "../../fixtures/common";
import { addTmsLink } from "tests/utils/allureUtils";
import { getDescription } from "../../utils/customJsonReporter";
-import { Account } from "tests/enum/Account";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
test.describe("Settings", () => {
test.use({
diff --git a/apps/ledger-live-desktop/tests/specs/speculos/subAccount.spec.ts b/apps/ledger-live-desktop/tests/specs/speculos/subAccount.spec.ts
index c351fe0aa532..329b8bee73c3 100644
--- a/apps/ledger-live-desktop/tests/specs/speculos/subAccount.spec.ts
+++ b/apps/ledger-live-desktop/tests/specs/speculos/subAccount.spec.ts
@@ -1,5 +1,5 @@
import { test } from "../../fixtures/common";
-import { Account } from "../../enum/Account";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
import { addTmsLink } from "tests/utils/allureUtils";
import { getDescription } from "../../utils/customJsonReporter";
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 ba908a500063..4c3aa6088567 100644
--- a/apps/ledger-live-desktop/tests/specs/speculos/swap.spec.ts
+++ b/apps/ledger-live-desktop/tests/specs/speculos/swap.spec.ts
@@ -1,10 +1,10 @@
import test from "../../fixtures/common";
-import { Account } from "tests/enum/Account";
-import { AppInfos } from "tests/enum/AppInfos";
+import { Account } from "@ledgerhq/live-common/e2e/enum/Account";
+import { AppInfos } from "@ledgerhq/live-common/e2e/enum/AppInfos";
import { setExchangeDependencies } from "@ledgerhq/live-common/e2e/speculos";
-import { Fee } from "tests/enum/Fee";
+import { Fee } from "@ledgerhq/live-common/e2e/enum/Fee";
import { Swap } from "tests/models/Swap";
-import { Provider, Rate } from "tests/enum/Swap";
+import { Provider, Rate } from "@ledgerhq/live-common/e2e/enum/Swap";
import { addTmsLink } from "tests/utils/allureUtils";
import { getDescription } from "tests/utils/customJsonReporter";
import { Application } from "tests/page";
diff --git a/apps/ledger-live-mobile/.env.mock b/apps/ledger-live-mobile/.env.mock
index f243d3f1eb60..e5688b9c296e 100644
--- a/apps/ledger-live-mobile/.env.mock
+++ b/apps/ledger-live-mobile/.env.mock
@@ -1,6 +1,7 @@
APP_NAME="LLmock"
MOCK=1
MOCK_COUNTERVALUES=1
+DETOX=1
DISABLE_YELLOW_BOX=1
GOOGLE_SERVICE_INFO_NAME="GoogleService-Info-Testing"
MOCK_SCAN_RECIPIENT=bitcoin:3HX3Q4wgYi8nKakxv7kmdCgLWJFrFgcqEt?amount=0.001
diff --git a/apps/ledger-live-mobile/e2e/bridge/client.ts b/apps/ledger-live-mobile/e2e/bridge/client.ts
index 84d9312fec7a..3a8586614751 100644
--- a/apps/ledger-live-mobile/e2e/bridge/client.ts
+++ b/apps/ledger-live-mobile/e2e/bridge/client.ts
@@ -24,7 +24,10 @@ const retryDelay = 500; // Initial retry delay in milliseconds
export function init() {
const wsPort = LaunchArguments.value()["wsPort"] || "8099";
+ const mock = LaunchArguments.value()["mock"];
+ log(`[E2E Bridge Client]: wsPort=${wsPort}, mock=${mock}`);
+ if (mock == "0") setEnv("MOCK", "");
if (ws) {
ws.close();
}
diff --git a/apps/ledger-live-mobile/e2e/helpers.ts b/apps/ledger-live-mobile/e2e/helpers.ts
index 566e16db7022..bdc5d54f1eb3 100644
--- a/apps/ledger-live-mobile/e2e/helpers.ts
+++ b/apps/ledger-live-mobile/e2e/helpers.ts
@@ -5,7 +5,7 @@ import { findFreePort, close as closeBridge, init as initBridge } from "./bridge
import { startSpeculos, stopSpeculos, specs } from "@ledgerhq/live-common/e2e/speculos";
import { SpeculosDevice } from "@ledgerhq/speculos-transport";
import invariant from "invariant";
-import { setEnv } from "@ledgerhq/live-env";
+import { getEnv, setEnv } from "@ledgerhq/live-env";
import { startProxy, closeProxy } from "./bridge/proxy";
const DEFAULT_TIMEOUT = 60000; // 60s !!
@@ -121,6 +121,14 @@ export async function getTextOfElement(id: string | RegExp, index = 0) {
return (!("elements" in attributes) ? attributes.text : attributes.elements[index].text) || "";
}
+export async function getIdOfElement(id: RegExp, index = 0) {
+ const attributes = await getElementById(id, index).getAttributes();
+ return (
+ (!("elements" in attributes) ? attributes.identifier : attributes.elements[index].identifier) ||
+ ""
+ );
+}
+
/**
* Waits for a specified amount of time
* /!\ Do not use it to wait for a specific element, use waitFor instead.
@@ -152,6 +160,7 @@ export async function launchApp() {
wsPort: port,
detoxURLBlacklistRegex:
'\\(".*sdk.*.braze.*",".*.googleapis.com/.*",".*clients3.google.com.*"\\)',
+ mock: getEnv("MOCK") ? getEnv("MOCK") : "0",
},
languageAndLocale: {
language: "en-US",
@@ -171,11 +180,11 @@ export async function launchSpeculos(appName: string, proxyPort: number) {
}
const speculosPort = portCounter++;
const speculosPidOffset =
- (speculosPort - BASE_PORT) * 1000 + parseInt(process.env.TEST_WORKER_INDEX || "0") * 100;
+ (speculosPort - BASE_PORT) * 1000 + parseInt(process.env.JEST_WORKER_ID || "0") * 100;
setEnv("SPECULOS_PID_OFFSET", speculosPidOffset);
const testName = expect.getState().testPath || "unknown";
- const speculosDevice = await startSpeculos(testName, specs[appName]);
+ const speculosDevice = await startSpeculos(testName, specs[appName.replace(/ /g, "_")]);
invariant(speculosDevice, "[E2E Setup] Speculos not started");
const speculosApiPort = speculosDevice.ports.apiPort;
diff --git a/apps/ledger-live-mobile/e2e/jest.globalTeardown.ts b/apps/ledger-live-mobile/e2e/jest.globalTeardown.ts
index 51b579b0e060..6843276b5904 100644
--- a/apps/ledger-live-mobile/e2e/jest.globalTeardown.ts
+++ b/apps/ledger-live-mobile/e2e/jest.globalTeardown.ts
@@ -1,10 +1,9 @@
const detoxGlobalTeardown = require("detox/runners/jest/globalTeardown");
import { promises as fs } from "fs";
-import { getEnvs, getFlags } from "./bridge/server";
+import { getEnvs, getFlags, loadConfig } from "./bridge/server";
import { formatFlagsData, formatEnvData } from "@ledgerhq/live-common/e2e/index";
-import { launchApp } from "./helpers";
+import { launchApp, waitForElementById } from "./helpers";
import detox from "detox/internals";
-import { Application } from "./page";
import { close as closeBridge } from "./bridge/server";
const environmentFilePath = "artifacts/environment.properties";
@@ -15,8 +14,8 @@ export default async () => {
try {
await initDetox();
await launchApp();
- const app = await Application.init("1AccountBTC1AccountETHReadOnlyFalse");
- await app.portfolio.waitForPortfolioPageToLoad();
+ await loadConfig("1AccountBTC1AccountETHReadOnlyFalse", true);
+ await waitForElementById("settings-icon", 120000);
const flagsData = formatFlagsData(JSON.parse(await getFlags()));
const envsData = formatEnvData(JSON.parse(await getEnvs()));
await fs.appendFile(environmentFilePath, flagsData + envsData);
diff --git a/apps/ledger-live-mobile/e2e/page/accounts/account.page.ts b/apps/ledger-live-mobile/e2e/page/accounts/account.page.ts
index f05bc02ef832..1c7e0f5d5729 100644
--- a/apps/ledger-live-mobile/e2e/page/accounts/account.page.ts
+++ b/apps/ledger-live-mobile/e2e/page/accounts/account.page.ts
@@ -1,43 +1,43 @@
+import { getElementById, getTextOfElement, scrollToId, tapByElement } from "../../helpers";
import { expect } from "detox";
-import {
- currencyParam,
- openDeeplink,
- waitForElementById,
- getElementById,
- tapByElement,
-} from "../../helpers";
-
-const baseLink = "account";
+import jestExpect from "expect";
export default class AccountPage {
- accountSettingsButton = () => getElementById("accounts-settings");
- assetBalance = () => getElementById("asset-graph-balance");
- accountTitleId = (assetName: string) => `accounts-title-${assetName}`;
- accountAssetId = (assetName: string) => `account-assets-${assetName}`;
-
- async waitForAccountPageToLoad(assetName: string) {
- await waitForElementById(this.accountTitleId(assetName));
- }
+ accountGraph = (accountId: string) => getElementById(`account-graph-${accountId}`);
+ accountBalance = (accountId: string) => getElementById(`account-balance-${accountId}`);
+ accountSettingsButton = () => getElementById("account-settings-button");
+ accountAdvancedLogRow = () => getElementById("account-advanced-log-row");
+ operationHistorySectionId = (accountId: string) => `operations-history-${accountId}`;
+ accountScreenScrollView = "account-screen-scrollView";
+ accountAdvancedLogsId = "account-advanced-logs";
- async expectAccountBalanceVisible() {
- await expect(this.assetBalance()).toBeVisible();
+ async openAccountSettings() {
+ await tapByElement(this.accountSettingsButton());
}
- async expectAccountBalance(expectedBalance: string) {
- await expect(this.assetBalance()).toHaveText(expectedBalance);
+ async openAccountAdvancedLogs() {
+ await tapByElement(this.accountAdvancedLogRow());
}
- async waitForAccountAssetsToLoad(assetName: string) {
- await waitForElementById(this.accountTitleId(assetName));
- await waitForElementById(this.accountAssetId(assetName));
+ @Step("Expect operation history to be visible")
+ async expectOperationHistoryVisible(accountId: string) {
+ const id = this.operationHistorySectionId(accountId);
+ await scrollToId(id, this.accountScreenScrollView);
+ await expect(getElementById(id)).toBeVisible();
}
- async openViaDeeplink(currencyLong?: string) {
- const link = currencyLong ? baseLink + currencyParam + currencyLong : baseLink;
- await openDeeplink(link);
+ @Step("Expect account balance to be visible")
+ async expectAccountBalanceVisible(accountId: string) {
+ await expect(this.accountGraph(accountId)).toBeVisible();
+ await expect(this.accountBalance(accountId)).toBeVisible();
}
- async openAccountSettings() {
- await tapByElement(this.accountSettingsButton());
+ @Step("Expect address index")
+ async expectAddressIndex(indexNumber: number) {
+ await this.openAccountSettings();
+ await this.openAccountAdvancedLogs();
+ const advancedLogsText = await getTextOfElement(this.accountAdvancedLogsId);
+ const advancedLogsJson = advancedLogsText ? JSON.parse(advancedLogsText) : null;
+ jestExpect(advancedLogsJson).toHaveProperty("index", indexNumber);
}
}
diff --git a/apps/ledger-live-mobile/e2e/page/accounts/addAccount.drawer.ts b/apps/ledger-live-mobile/e2e/page/accounts/addAccount.drawer.ts
index ccc16068d54c..4ed66448b778 100644
--- a/apps/ledger-live-mobile/e2e/page/accounts/addAccount.drawer.ts
+++ b/apps/ledger-live-mobile/e2e/page/accounts/addAccount.drawer.ts
@@ -1,18 +1,32 @@
import { expect } from "detox";
-import { getElementById, openDeeplink, tapById, waitForElementById } from "../../helpers";
-import { capitalize } from "../../models/currencies";
+import {
+ getElementById,
+ getIdOfElement,
+ openDeeplink,
+ scrollToId,
+ tapById,
+ waitForElementById,
+} from "../../helpers";
+import { getEnv } from "@ledgerhq/live-env";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
const baseLink = "add-account";
+const isMock = getEnv("MOCK");
export default class AddAccountDrawer {
- accountCardId = (id: string) => getElementById(`account-card-${id}`);
- accountId = (currency: string, index: number) => `mock:1:${currency}:MOCK_${currency}_${index}:`;
- accountTitleId = (accountName: string) => getElementById(`test-id-account-${accountName}`);
+ deselectAllButtonId = "add-accounts-deselect-all";
+ accountCardRegExp = (id = ".*") => new RegExp(`account-card-${id}`);
+ accountCard = (id: string) => getElementById(this.accountCardRegExp(id));
+ accountId = (currency: string, index: number) =>
+ isMock ? `mock:1:${currency}:MOCK_${currency}_${index}:` : `js:2:${currency}:.*`;
+ accountTitleId = (accountName: string, index: number) =>
+ getElementById(`test-id-account-${accountName}`, index);
modalButtonId = "add-accounts-modal-add-button";
currencyRow = (currencyId: string) => `currency-row-${currencyId}`;
continueButtonId = "add-accounts-continue-button";
succesCtaId = "add-accounts-success-cta";
+ @Step("Open add account via deeplink")
async openViaDeeplink() {
await openDeeplink(baseLink);
}
@@ -22,29 +36,49 @@ export default class AddAccountDrawer {
await tapById(this.modalButtonId);
}
+ @Step("Select currency")
async selectCurrency(currencyId: string) {
const id = this.currencyRow(currencyId);
- await waitForElementById(id);
+ await scrollToId(id);
await tapById(id);
}
+ @Step("Start accounts discovery")
async startAccountsDiscovery() {
- await waitForElementById(this.continueButtonId);
+ await waitForElementById(this.continueButtonId, 120000);
}
- async expectAccountDiscovery(currency: string, index: number) {
- const accountName = `${capitalize(currency)} ${index + 1}`;
- await expect(this.accountCardId(this.accountId(currency, index))).toBeVisible();
- await expect(this.accountTitleId(accountName)).toHaveText(accountName);
+ @Step("Expect account discovered")
+ async expectAccountDiscovery(currencyName: string, currencyId: string, index = 0) {
+ const accountName = `${currencyName} ${index + 1}`;
+ await expect(this.accountCard(this.accountId(currencyId, index))).toBeVisible();
+ await expect(this.accountTitleId(accountName, index)).toHaveText(accountName);
}
+ @Step("Finish account discovery")
async finishAccountsDiscovery() {
await waitForElementById(this.continueButtonId);
await tapById(this.continueButtonId);
}
+ @Step("Close add account success screen")
async tapSuccessCta() {
await waitForElementById(this.succesCtaId);
await tapById(this.succesCtaId);
}
+
+ @Step("Add only first discovered account")
+ async addFirstAccount(currency: Currency) {
+ await this.startAccountsDiscovery();
+ await this.expectAccountDiscovery(currency.name, currency.currencyId);
+ await tapById(this.deselectAllButtonId);
+ await tapById(this.accountCardRegExp(), 0);
+ const accountId = (await getIdOfElement(this.accountCardRegExp(), 0)).replace(
+ /^account-card-/,
+ "",
+ );
+ await this.finishAccountsDiscovery();
+ await this.tapSuccessCta();
+ return accountId;
+ }
}
diff --git a/apps/ledger-live-mobile/e2e/page/accounts/assetAccounts.page.ts b/apps/ledger-live-mobile/e2e/page/accounts/assetAccounts.page.ts
new file mode 100644
index 000000000000..2bf8992d5ccb
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/page/accounts/assetAccounts.page.ts
@@ -0,0 +1,49 @@
+import { expect } from "detox";
+import {
+ currencyParam,
+ openDeeplink,
+ waitForElementById,
+ getElementById,
+ scrollToId,
+ tapById,
+} from "../../helpers";
+
+const baseLink = "account";
+
+export default class AssetAccountsPage {
+ assetBalance = () => getElementById("asset-graph-balance");
+ titleId = (assetName: string) => `accounts-title-${assetName}`;
+ accountAssetId = (assetName: string) => `account-assets-${assetName}`;
+ accountRowId = (accountId: string) => `account-row-${accountId}`;
+ accountNameRegExp = /account-row-name-.*/;
+
+ @Step("Wait for asset page to load")
+ async waitForAccountPageToLoad(assetName: string) {
+ await waitForElementById(this.titleId(assetName.toLowerCase()));
+ }
+
+ @Step("Expect asset balance to be visible")
+ async expectAccountsBalanceVisible() {
+ await expect(this.assetBalance()).toBeVisible();
+ }
+
+ async expectAccountsBalance(expectedBalance: string) {
+ await expect(this.assetBalance()).toHaveText(expectedBalance);
+ }
+
+ async waitForAccountAssetsToLoad(assetName: string) {
+ await waitForElementById(this.titleId(assetName));
+ await waitForElementById(this.accountAssetId(assetName));
+ }
+
+ async openViaDeeplink(currencyLong?: string) {
+ const link = currencyLong ? baseLink + currencyParam + currencyLong : baseLink;
+ await openDeeplink(link);
+ }
+
+ @Step("Go to the account")
+ async goToAccount(accountId: string) {
+ await scrollToId(this.accountNameRegExp);
+ await tapById(this.accountRowId(accountId));
+ }
+}
diff --git a/apps/ledger-live-mobile/e2e/page/common.page.ts b/apps/ledger-live-mobile/e2e/page/common.page.ts
index f9593ac177e9..89ef37a2710c 100644
--- a/apps/ledger-live-mobile/e2e/page/common.page.ts
+++ b/apps/ledger-live-mobile/e2e/page/common.page.ts
@@ -27,6 +27,7 @@ export default class CommonPage {
scannedDeviceRow = (id: string) => `device-scanned-${id}`;
pluggedDeviceRow = (nano: DeviceUSB) => `device-item-usb|${JSON.stringify(nano)}`;
+ @Step("Perform search")
async performSearch(text: string) {
await waitForElementById(this.searchBarId);
await typeTextByElement(this.searchBar(), text, false);
@@ -83,8 +84,8 @@ export default class CommonPage {
return proxyPort;
}
- async removeSpeculos(proxyPort: number) {
+ async removeSpeculos(proxyPort?: number) {
await deleteSpeculos(proxyPort);
- await bridge.removeKnownSpeculos(`${proxyAddress}:${proxyPort}`);
+ proxyPort && (await bridge.removeKnownSpeculos(`${proxyAddress}:${proxyPort}`));
}
}
diff --git a/apps/ledger-live-mobile/e2e/page/index.ts b/apps/ledger-live-mobile/e2e/page/index.ts
index 67b420e9d432..2c61e9434d3d 100644
--- a/apps/ledger-live-mobile/e2e/page/index.ts
+++ b/apps/ledger-live-mobile/e2e/page/index.ts
@@ -1,3 +1,4 @@
+import AssetAccountsPage from "./accounts/assetAccounts.page";
import AccountPage from "./accounts/account.page";
import AccountsPage from "./accounts/accounts.page";
import AddAccountDrawer from "./accounts/addAccount.drawer";
@@ -28,8 +29,17 @@ import WalletTabNavigatorPage from "./wallet/walletTabNavigator.page";
import type { Account } from "@ledgerhq/types-live";
import { DeviceLike } from "~/reducers/types";
import { loadAccounts, loadBleState, loadConfig } from "../bridge/server";
+import { AppInfos } from "@ledgerhq/live-common/e2e/enum/AppInfos";
+
+type ApplicationOptions = {
+ speculosApp?: AppInfos;
+ userdata?: string;
+ knownDevices?: DeviceLike[];
+ testAccounts?: Account[];
+};
export class Application {
+ public assetAccountsPage = new AssetAccountsPage();
public account = new AccountPage();
public accounts = new AccountsPage();
public addAccount = new AddAccountDrawer();
@@ -57,11 +67,12 @@ export class Application {
public transfertMenu = new TransfertMenuDrawer();
public walletTabNavigator = new WalletTabNavigatorPage();
- static async init(userdata?: string, knownDevices?: DeviceLike[], testAccounts?: Account[]) {
+ static async init({ speculosApp, userdata, knownDevices, testAccounts }: ApplicationOptions) {
const app = new Application();
- if (userdata) await loadConfig(userdata, true);
- if (knownDevices) await loadBleState({ knownDevices: knownDevices });
- if (testAccounts) await loadAccounts(testAccounts);
+ userdata && (await loadConfig(userdata, true));
+ knownDevices && (await loadBleState({ knownDevices }));
+ testAccounts && (await loadAccounts(testAccounts));
+ speculosApp && (await app.common.addSpeculos(speculosApp.name));
return app;
}
diff --git a/apps/ledger-live-mobile/e2e/setup.ts b/apps/ledger-live-mobile/e2e/setup.ts
index 1f760136968f..92575443871a 100644
--- a/apps/ledger-live-mobile/e2e/setup.ts
+++ b/apps/ledger-live-mobile/e2e/setup.ts
@@ -11,6 +11,7 @@ import { setEnv } from "@ledgerhq/live-env";
const currentDate = new Date();
const date = format(currentDate, "MM-dd");
const directoryPath = `artifacts/${date}_LLM`;
+setEnv("MOCK", process.env.MOCK == "0" ? "" : "1");
beforeAll(
async () => {
diff --git a/apps/ledger-live-mobile/e2e/specs/addAccounts/addAccount.spec.ts b/apps/ledger-live-mobile/e2e/specs/addAccounts/addAccount.spec.ts
index 5c77a1314f19..da2d4e8f9d23 100644
--- a/apps/ledger-live-mobile/e2e/specs/addAccounts/addAccount.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/addAccounts/addAccount.spec.ts
@@ -1,6 +1,7 @@
import { knownDevices } from "../../models/devices";
import DeviceAction from "../../models/DeviceAction";
import { Application } from "../../page";
+import { capitalize } from "../../models/currencies";
let app: Application;
let deviceAction: DeviceAction;
@@ -11,7 +12,10 @@ const knownDevice = knownDevices.nanoX;
describe("Add account from modal", () => {
beforeAll(async () => {
- app = await Application.init("onboardingcompleted", [knownDevice]);
+ app = await Application.init({
+ userdata: "onboardingcompleted",
+ knownDevices: [knownDevice],
+ });
deviceAction = new DeviceAction(knownDevice);
await app.portfolio.waitForPortfolioPageToLoad();
@@ -29,14 +33,14 @@ describe("Add account from modal", () => {
await deviceAction.selectMockDevice();
await deviceAction.openApp();
await app.addAccount.startAccountsDiscovery();
- await app.addAccount.expectAccountDiscovery(testedCurrency, 1);
+ await app.addAccount.expectAccountDiscovery(capitalize(testedCurrency), testedCurrency, 0);
await app.addAccount.finishAccountsDiscovery();
await app.addAccount.tapSuccessCta();
});
$TmsLink("B2CQA-101");
it("displays Bitcoin accounts page summary", async () => {
- await app.account.waitForAccountPageToLoad(testedCurrency);
- await app.account.expectAccountBalance(expectedBalance);
+ await app.assetAccountsPage.waitForAccountPageToLoad(testedCurrency);
+ await app.assetAccountsPage.expectAccountsBalance(expectedBalance);
});
});
diff --git a/apps/ledger-live-mobile/e2e/specs/deeplinks.spec.ts b/apps/ledger-live-mobile/e2e/specs/deeplinks.spec.ts
index 9fb095c879b6..0bb233524466 100644
--- a/apps/ledger-live-mobile/e2e/specs/deeplinks.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/deeplinks.spec.ts
@@ -11,7 +11,10 @@ const bobaLong = "boba";
$TmsLink("B2CQA-1837");
describe("DeepLinks Tests", () => {
beforeAll(async () => {
- app = await Application.init("1AccountBTC1AccountETHReadOnlyFalse", [knownDevices.nanoX]);
+ app = await Application.init({
+ userdata: "1AccountBTC1AccountETHReadOnlyFalse",
+ knownDevices: [knownDevices.nanoX],
+ });
await app.portfolio.waitForPortfolioPageToLoad();
});
@@ -21,7 +24,7 @@ describe("DeepLinks Tests", () => {
});
it("should open Account page", async () => {
- await app.account.openViaDeeplink();
+ await app.assetAccountsPage.openViaDeeplink();
await app.accounts.waitForAccountsPageToLoad();
});
@@ -31,13 +34,13 @@ describe("DeepLinks Tests", () => {
});
it("should open ETH Account Asset page when given currency param", async () => {
- await app.account.openViaDeeplink(ethereumLong);
- await app.account.waitForAccountAssetsToLoad(ethereumLong);
+ await app.assetAccountsPage.openViaDeeplink(ethereumLong);
+ await app.assetAccountsPage.waitForAccountAssetsToLoad(ethereumLong);
});
it("should open BTC Account Asset page when given currency param", async () => {
- await app.account.openViaDeeplink(bitcoinLong);
- await app.account.waitForAccountAssetsToLoad(bitcoinLong);
+ await app.assetAccountsPage.openViaDeeplink(bitcoinLong);
+ await app.assetAccountsPage.waitForAccountAssetsToLoad(bitcoinLong);
});
it("should open Custom Lock Screen page", async () => {
diff --git a/apps/ledger-live-mobile/e2e/specs/delegate/cosmos.spec.ts b/apps/ledger-live-mobile/e2e/specs/delegate/cosmos.spec.ts
index 9cbd8ed1d96b..38d0872c75bb 100644
--- a/apps/ledger-live-mobile/e2e/specs/delegate/cosmos.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/delegate/cosmos.spec.ts
@@ -20,7 +20,11 @@ const knownDevice = knownDevices.nanoX;
describe("Cosmos delegate flow", () => {
beforeAll(async () => {
- app = await Application.init("onboardingcompleted", [knownDevice], [testAccount]);
+ app = await Application.init({
+ userdata: "onboardingcompleted",
+ knownDevices: [knownDevice],
+ testAccounts: [testAccount],
+ });
deviceAction = new DeviceAction(knownDevice);
await app.portfolio.waitForPortfolioPageToLoad();
diff --git a/apps/ledger-live-mobile/e2e/specs/languageChange.spec.ts b/apps/ledger-live-mobile/e2e/specs/languageChange.spec.ts
index b73d50486e09..b3f70435fe50 100644
--- a/apps/ledger-live-mobile/e2e/specs/languageChange.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/languageChange.spec.ts
@@ -26,7 +26,7 @@ const verifyLanguageCanBeChanged = (l10n: { lang: string; localization: string }
$TmsLink("B2CQA-2344");
describe("Change Language", () => {
beforeAll(async () => {
- app = await Application.init("1AccountBTC1AccountETHReadOnlyFalse");
+ app = await Application.init({ userdata: "1AccountBTC1AccountETHReadOnlyFalse" });
await app.portfolio.waitForPortfolioPageToLoad();
});
diff --git a/apps/ledger-live-mobile/e2e/specs/manager.spec.ts b/apps/ledger-live-mobile/e2e/specs/manager.spec.ts
index aa2136228c24..c250a9854992 100644
--- a/apps/ledger-live-mobile/e2e/specs/manager.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/manager.spec.ts
@@ -12,7 +12,7 @@ const knownDevice = knownDevices.nanoX;
describe("Test My Ledger", () => {
beforeAll(async () => {
- app = await Application.init("onboardingcompleted");
+ app = await Application.init({ userdata: "onboardingcompleted" });
deviceAction = new DeviceAction(knownDevice);
await app.portfolio.waitForPortfolioPageToLoad();
diff --git a/apps/ledger-live-mobile/e2e/specs/market.spec.ts b/apps/ledger-live-mobile/e2e/specs/market.spec.ts
index e98d91bfd164..6fdece52b615 100644
--- a/apps/ledger-live-mobile/e2e/specs/market.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/market.spec.ts
@@ -5,7 +5,7 @@ const asset = "Ethereum (ETH)";
describe("Market page for user with no device", () => {
beforeAll(async () => {
- app = await Application.init("1accountEth");
+ app = await Application.init({ userdata: "1accountEth" });
await app.portfolio.waitForPortfolioPageToLoad();
});
diff --git a/apps/ledger-live-mobile/e2e/specs/nftGallery.spec.ts b/apps/ledger-live-mobile/e2e/specs/nftGallery.spec.ts
index e54c94890a97..e30d7ee847f3 100644
--- a/apps/ledger-live-mobile/e2e/specs/nftGallery.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/nftGallery.spec.ts
@@ -7,7 +7,7 @@ const accountCurrency = "ethereum";
// To-Do Fix NFT not available in account
describe.skip("NFT Gallery screen", () => {
beforeAll(async () => {
- app = await Application.init("1Account1NFTNotSpam");
+ app = await Application.init({ userdata: "1Account1NFTNotSpam" });
await app.portfolio.waitForPortfolioPageToLoad();
await app.nftGallery.openViaDeeplink();
diff --git a/apps/ledger-live-mobile/e2e/specs/password.spec.ts b/apps/ledger-live-mobile/e2e/specs/password.spec.ts
index cce8b2d78e7d..01a35a9d9aeb 100644
--- a/apps/ledger-live-mobile/e2e/specs/password.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/password.spec.ts
@@ -7,7 +7,7 @@ const CORRECT_PASSWORD = "passWORD$123!";
describe("Password Lock Screen", () => {
beforeAll(async () => {
- app = await Application.init("1AccountBTC1AccountETHReadOnlyFalse");
+ app = await Application.init({ userdata: "1AccountBTC1AccountETHReadOnlyFalse" });
await app.portfolio.waitForPortfolioPageToLoad();
});
diff --git a/apps/ledger-live-mobile/e2e/specs/receive/currencies.spec.ts b/apps/ledger-live-mobile/e2e/specs/receive/currencies.spec.ts
index 3a163c142643..edd1ad3e23fc 100644
--- a/apps/ledger-live-mobile/e2e/specs/receive/currencies.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/receive/currencies.spec.ts
@@ -12,7 +12,10 @@ $TmsLink("B2CQA-651");
$TmsLink("B2CQA-1854");
describe("Receive different currency", () => {
beforeAll(async () => {
- app = await Application.init("onboardingcompleted", [knownDevice]);
+ app = await Application.init({
+ userdata: "onboardingcompleted",
+ knownDevices: [knownDevice],
+ });
deviceAction = new DeviceAction(knownDevice);
await app.portfolio.waitForPortfolioPageToLoad();
diff --git a/apps/ledger-live-mobile/e2e/specs/receive/receiveFlow.spec.ts b/apps/ledger-live-mobile/e2e/specs/receive/receiveFlow.spec.ts
index d53df9941973..5c2f4d78ce15 100644
--- a/apps/ledger-live-mobile/e2e/specs/receive/receiveFlow.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/receive/receiveFlow.spec.ts
@@ -10,7 +10,10 @@ const knownDevice = knownDevices.nanoX;
describe("Receive Flow", () => {
beforeAll(async () => {
- app = await Application.init("EthAccountXrpAccountReadOnlyFalse", [knownDevice]);
+ app = await Application.init({
+ userdata: "EthAccountXrpAccountReadOnlyFalse",
+ knownDevices: [knownDevice],
+ });
deviceAction = new DeviceAction(knownDevice);
await app.portfolio.waitForPortfolioPageToLoad();
diff --git a/apps/ledger-live-mobile/e2e/specs/send/currencies.spec.ts b/apps/ledger-live-mobile/e2e/specs/send/currencies.spec.ts
index 557f6929096f..33e16cf26f3e 100644
--- a/apps/ledger-live-mobile/e2e/specs/send/currencies.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/send/currencies.spec.ts
@@ -35,7 +35,11 @@ const knownDevice = knownDevices.nanoX;
$TmsLink("B2CQA-1823");
describe("Send flow", () => {
beforeAll(async () => {
- app = await Application.init("onboardingcompleted", [knownDevice], testAccounts);
+ app = await Application.init({
+ userdata: "onboardingcompleted",
+ knownDevices: [knownDevice],
+ testAccounts: testAccounts,
+ });
deviceAction = new DeviceAction(knownDevice);
await app.portfolio.waitForPortfolioPageToLoad();
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount.spec.ts
deleted file mode 100644
index 4465e86e6826..000000000000
--- a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount.spec.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { Application } from "../../page";
-
-let app: Application;
-
-const currencies = [
- { currency: "bitcoin", nanoApp: "Bitcoin", tmsLink: "B2CQA-101" },
- { currency: "ethereum", nanoApp: "Ethereum", tmsLink: "B2CQA-102" },
-];
-
-describe("Add accounts", () => {
- beforeAll(async () => {
- app = await Application.init("onboardingcompleted");
- await app.portfolio.waitForPortfolioPageToLoad();
- });
-
- currencies.forEach(({ currency, nanoApp, tmsLink }) => {
- let deviceNumber: number;
-
- $TmsLink(tmsLink);
- it(`${currency}: add accounts`, async () => {
- await app.addAccount.openViaDeeplink();
- await app.addAccount.selectCurrency(currency);
-
- deviceNumber = await app.common.addSpeculos(nanoApp);
-
- await app.addAccount.startAccountsDiscovery();
- await app.addAccount.expectAccountDiscovery(currency, 1);
- await app.addAccount.finishAccountsDiscovery();
- await app.addAccount.tapSuccessCta();
- await app.account.waitForAccountPageToLoad(currency);
- await app.account.expectAccountBalanceVisible();
- });
-
- afterEach(async () => {
- await app.common.removeSpeculos(deviceNumber);
- });
- });
-});
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccount.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccount.ts
new file mode 100644
index 000000000000..539fe2b199c7
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccount.ts
@@ -0,0 +1,35 @@
+import { Application } from "../../../page";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+export async function runAddAccountTest(currency: Currency, tmsLink: string) {
+ let app: Application;
+
+ describe(`Add accounts - ${currency.name}`, () => {
+ beforeAll(async () => {
+ app = await Application.init({
+ userdata: "onboardingcompleted",
+ speculosApp: currency.speculosApp,
+ });
+ await app.portfolio.waitForPortfolioPageToLoad();
+ });
+
+ $TmsLink(tmsLink);
+ it(`Perform an add account`, async () => {
+ await app.addAccount.openViaDeeplink();
+ await app.common.performSearch(currency.name);
+ await app.addAccount.selectCurrency(currency.currencyId);
+
+ const accountId = await app.addAccount.addFirstAccount(currency);
+ await app.assetAccountsPage.waitForAccountPageToLoad(currency.name);
+ await app.assetAccountsPage.expectAccountsBalanceVisible();
+ await app.assetAccountsPage.goToAccount(accountId);
+ await app.account.expectAccountBalanceVisible(accountId);
+ await app.account.expectOperationHistoryVisible(accountId);
+ await app.account.expectAddressIndex(0);
+ });
+
+ afterAll(async () => {
+ await app.common.removeSpeculos();
+ });
+ });
+}
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountADA.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountADA.spec.ts
new file mode 100644
index 000000000000..87cb6f45ef9e
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountADA.spec.ts
@@ -0,0 +1,4 @@
+import { runAddAccountTest } from "./AddAccount";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+runAddAccountTest(Currency.ADA, "B2CQA-2500, B2CQA-2650, B2CQA-2678");
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountALGO.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountALGO.spec.ts
new file mode 100644
index 000000000000..a3933d2af648
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountALGO.spec.ts
@@ -0,0 +1,4 @@
+import { runAddAccountTest } from "./AddAccount";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+runAddAccountTest(Currency.ALGO, "B2CQA-2497, B2CQA-2653, B2CQA-2681");
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountATOM.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountATOM.spec.ts
new file mode 100644
index 000000000000..314443b0f41d
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountATOM.spec.ts
@@ -0,0 +1,4 @@
+import { runAddAccountTest } from "./AddAccount";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+runAddAccountTest(Currency.ATOM, "B2CQA-2501, B2CQA-2654, B2CQA-2682");
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountBCH.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountBCH.spec.ts
new file mode 100644
index 000000000000..cfa248cea620
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountBCH.spec.ts
@@ -0,0 +1,4 @@
+import { runAddAccountTest } from "./AddAccount";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+runAddAccountTest(Currency.BCH, "B2CQA-2498, B2CQA-2652, B2CQA-2680");
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountBTC.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountBTC.spec.ts
new file mode 100644
index 000000000000..a023f24482d4
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountBTC.spec.ts
@@ -0,0 +1,4 @@
+import { runAddAccountTest } from "./AddAccount";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+runAddAccountTest(Currency.BTC, "B2CQA-2499, B2CQA-2644, B2CQA-2672, B2CQA-786");
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountDOT.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountDOT.spec.ts
new file mode 100644
index 000000000000..fedd5ccf18d7
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountDOT.spec.ts
@@ -0,0 +1,4 @@
+import { runAddAccountTest } from "./AddAccount";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+runAddAccountTest(Currency.DOT, "B2CQA-2504, B2CQA-2648, B2CQA-2676");
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountETC.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountETC.spec.ts
new file mode 100644
index 000000000000..801794424158
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountETC.spec.ts
@@ -0,0 +1,4 @@
+import { runAddAccountTest } from "./AddAccount";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+runAddAccountTest(Currency.ETC, "B2CQA-2502, B2CQA-2646, B2CQA-2674");
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountETH.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountETH.spec.ts
new file mode 100644
index 000000000000..225cc83eec46
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountETH.spec.ts
@@ -0,0 +1,4 @@
+import { runAddAccountTest } from "./AddAccount";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+runAddAccountTest(Currency.ETH, "B2CQA-2503, B2CQA-2645, B2CQA-26736");
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountSOL.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountSOL.spec.ts
new file mode 100644
index 000000000000..42eb44faeff6
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountSOL.spec.ts
@@ -0,0 +1,4 @@
+import { runAddAccountTest } from "./AddAccount";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+runAddAccountTest(Currency.SOL, "B2CQA-2642, B2CQA-2656, B2CQA-2684");
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountTON.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountTON.spec.ts
new file mode 100644
index 000000000000..28b01f50f71c
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountTON.spec.ts
@@ -0,0 +1,4 @@
+import { runAddAccountTest } from "./AddAccount";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+runAddAccountTest(Currency.TON, "B2CQA-2643, B2CQA-2657, B2CQA-2685");
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountTRX.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountTRX.spec.ts
new file mode 100644
index 000000000000..1310e7efadd8
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountTRX.spec.ts
@@ -0,0 +1,4 @@
+import { runAddAccountTest } from "./AddAccount";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+runAddAccountTest(Currency.TRX, "B2CQA-2508, B2CQA-2649, B2CQA-2677");
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountXLM.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountXLM.spec.ts
new file mode 100644
index 000000000000..42a0b7d7002b
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountXLM.spec.ts
@@ -0,0 +1,4 @@
+import { runAddAccountTest } from "./AddAccount";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+runAddAccountTest(Currency.XLM, "B2CQA-2506, B2CQA-2651, B2CQA-2679");
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountXRP.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountXRP.spec.ts
new file mode 100644
index 000000000000..1f6df1119d48
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountXRP.spec.ts
@@ -0,0 +1,4 @@
+import { runAddAccountTest } from "./AddAccount";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+runAddAccountTest(Currency.XRP, "B2CQA-2505, B2CQA-2647, B2CQA-2675");
diff --git a/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountXTZ.spec.ts b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountXTZ.spec.ts
new file mode 100644
index 000000000000..bce641c496b6
--- /dev/null
+++ b/apps/ledger-live-mobile/e2e/specs/speculos/addAccount/AddAccountXTZ.spec.ts
@@ -0,0 +1,4 @@
+import { runAddAccountTest } from "./AddAccount";
+import { Currency } from "@ledgerhq/live-common/e2e/enum/Currency";
+
+runAddAccountTest(Currency.XTZ, "B2CQA-2507, B2CQA-2655, B2CQA-2683");
diff --git a/apps/ledger-live-mobile/e2e/specs/swap/dexSwap.spec.ts b/apps/ledger-live-mobile/e2e/specs/swap/dexSwap.spec.ts
index e0766bbddd88..7b6498feaf13 100644
--- a/apps/ledger-live-mobile/e2e/specs/swap/dexSwap.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/swap/dexSwap.spec.ts
@@ -4,7 +4,7 @@ let app: Application;
describe("DEX Swap", () => {
beforeAll(async () => {
- app = await Application.init("1AccountBTC1AccountETHReadOnlyFalse");
+ app = await Application.init({ userdata: "1AccountBTC1AccountETHReadOnlyFalse" });
await app.portfolio.waitForPortfolioPageToLoad();
await app.swap.openViaDeeplink();
diff --git a/apps/ledger-live-mobile/e2e/specs/swap/swap.spec.ts b/apps/ledger-live-mobile/e2e/specs/swap/swap.spec.ts
index f3a75867e7a1..000658e9f72d 100644
--- a/apps/ledger-live-mobile/e2e/specs/swap/swap.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/swap/swap.spec.ts
@@ -4,7 +4,7 @@ let app: Application;
describe("Swap", () => {
beforeAll(async () => {
- app = await Application.init("1AccountBTC1AccountETHReadOnlyFalse");
+ app = await Application.init({ userdata: "1AccountBTC1AccountETHReadOnlyFalse" });
await app.portfolio.waitForPortfolioPageToLoad();
});
diff --git a/apps/ledger-live-mobile/e2e/specs/unknown-currency-resilience.spec.ts b/apps/ledger-live-mobile/e2e/specs/unknown-currency-resilience.spec.ts
index dc5a88431fb9..382dd923f7b5 100644
--- a/apps/ledger-live-mobile/e2e/specs/unknown-currency-resilience.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/unknown-currency-resilience.spec.ts
@@ -22,7 +22,7 @@ describe("Portfolio to load with unknown currency data in accounts", () => {
{ data: badAccount2, version: 0 },
]);
- app = await Application.init("onboardingcompleted");
+ app = await Application.init({ userdata: "onboardingcompleted" });
});
it("opens to empty state", async () => {
diff --git a/apps/ledger-live-mobile/e2e/specs/wallet-api.spec.ts b/apps/ledger-live-mobile/e2e/specs/wallet-api.spec.ts
index ad2c9e9ba93b..fb4b1d3ae642 100644
--- a/apps/ledger-live-mobile/e2e/specs/wallet-api.spec.ts
+++ b/apps/ledger-live-mobile/e2e/specs/wallet-api.spec.ts
@@ -4,7 +4,7 @@ let app: Application;
describe("Wallet API methods", () => {
beforeAll(async () => {
- app = await Application.init("1AccountBTC1AccountETHReadOnlyFalse");
+ app = await Application.init({ userdata: "1AccountBTC1AccountETHReadOnlyFalse" });
await app.dummyWalletApp.startApp();
await app.portfolio.waitForPortfolioPageToLoad();
diff --git a/apps/ledger-live-mobile/e2e/tsconfig.test.json b/apps/ledger-live-mobile/e2e/tsconfig.test.json
index 2f10c52d6d80..df42095480e2 100644
--- a/apps/ledger-live-mobile/e2e/tsconfig.test.json
+++ b/apps/ledger-live-mobile/e2e/tsconfig.test.json
@@ -1,6 +1,7 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
- "allowJs": true
+ "allowJs": true,
+ "experimentalDecorators": true
}
}
diff --git a/apps/ledger-live-mobile/package.json b/apps/ledger-live-mobile/package.json
index 31a39e855085..2f2251ee3f80 100644
--- a/apps/ledger-live-mobile/package.json
+++ b/apps/ledger-live-mobile/package.json
@@ -19,8 +19,8 @@
"gen-metafile": "zx ./scripts/gen-metafile.mjs",
"e2e:build": "pnpm detox build",
"e2e:ci": "zx ./scripts/e2e-ci.mjs",
- "e2e:test": "pnpm detox test",
- "e2e:test:speculos": "pnpm detox test --testMatch $(pwd)/e2e/specs/speculos/**/*.spec.ts",
+ "e2e:test": "export MOCK=1 && pnpm detox test",
+ "e2e:test:speculos": "export MOCK=0 && pnpm detox test --testMatch $(pwd)/e2e/specs/speculos/**/**/*.spec.ts",
"prebeta": "bundle install",
"debug:detox": "pnpm detox test -c ios.manual currencies.spec.ts",
"ios:staging": "ENVFILE=.env.ios.staging react-native run-ios --mode Staging",
diff --git a/apps/ledger-live-mobile/src/components/AccountGraphCard.tsx b/apps/ledger-live-mobile/src/components/AccountGraphCard.tsx
index 588384f494f2..23adfaa331c4 100644
--- a/apps/ledger-live-mobile/src/components/AccountGraphCard.tsx
+++ b/apps/ledger-live-mobile/src/components/AccountGraphCard.tsx
@@ -258,6 +258,7 @@ const GraphCardHeader = ({
event="SwitchAccountCurrency"
eventProperties={{ useCounterValue: shouldUseCounterValue }}
onPress={countervalueAvailable ? onSwitchAccountCurrency : undefined}
+ testID={`account-graph-${account.id}`}
>
@@ -273,7 +274,13 @@ const GraphCardHeader = ({
-
+
{typeof items[1]?.value === "number" ? (
) : (
diff --git a/apps/ledger-live-mobile/src/components/AccountRowLayout.tsx b/apps/ledger-live-mobile/src/components/AccountRowLayout.tsx
index 4b3e6b1391ab..01d5efd5ff16 100644
--- a/apps/ledger-live-mobile/src/components/AccountRowLayout.tsx
+++ b/apps/ledger-live-mobile/src/components/AccountRowLayout.tsx
@@ -14,6 +14,7 @@ type Props = {
currencyUnit?: Unit;
countervalueChange?: ValueChange;
name: string;
+ id: string;
parentAccountName?: string;
tag?: string | null | boolean;
onPress?: TouchableOpacityProps["onPress"];
@@ -29,6 +30,7 @@ const AccountRowLayout = ({
currency,
currencyUnit,
name,
+ id,
parentAccountName,
onPress,
topLink,
@@ -39,7 +41,7 @@ const AccountRowLayout = ({
const { colors, space } = useTheme();
return (
-
+
{topLink && (
{name}
diff --git a/apps/ledger-live-mobile/src/components/Animation.tsx b/apps/ledger-live-mobile/src/components/Animation.tsx
index 30016e081fdb..c226e39dd850 100644
--- a/apps/ledger-live-mobile/src/components/Animation.tsx
+++ b/apps/ledger-live-mobile/src/components/Animation.tsx
@@ -45,7 +45,7 @@ export default function Animation({
{...lottieProps}
style={[styles.default, { aspectRatio }, style]}
loop={lottieProps.loop ?? true}
- autoPlay={Config.MOCK ? false : lottieProps.autoPlay ?? true}
+ autoPlay={Config.DETOX ? false : lottieProps.autoPlay ?? true}
/>
);
diff --git a/apps/ledger-live-mobile/src/components/BleDevicePairingFlow/BleDevicePairing.tsx b/apps/ledger-live-mobile/src/components/BleDevicePairingFlow/BleDevicePairing.tsx
index 5c8c3f2cf99c..3955f5859aa1 100644
--- a/apps/ledger-live-mobile/src/components/BleDevicePairingFlow/BleDevicePairing.tsx
+++ b/apps/ledger-live-mobile/src/components/BleDevicePairingFlow/BleDevicePairing.tsx
@@ -169,7 +169,7 @@ const BleDevicePairing = ({ deviceToPair, onPaired, onRetry }: BleDevicePairingP
}
+ Icon={}
backgroundColor={colors.opacityDefault.c05}
size={64}
variant="circle"
diff --git a/apps/ledger-live-mobile/src/components/DeviceAction/rendering.tsx b/apps/ledger-live-mobile/src/components/DeviceAction/rendering.tsx
index 29d99f1f8904..3acc3942d885 100644
--- a/apps/ledger-live-mobile/src/components/DeviceAction/rendering.tsx
+++ b/apps/ledger-live-mobile/src/components/DeviceAction/rendering.tsx
@@ -883,7 +883,7 @@ export function renderLoading({
return (
-
+
{description ?? t("DeviceAction.loading")}
diff --git a/apps/ledger-live-mobile/src/components/KeyboardView.tsx b/apps/ledger-live-mobile/src/components/KeyboardView.tsx
index 9e6960a8bc5f..8c407273b0a5 100644
--- a/apps/ledger-live-mobile/src/components/KeyboardView.tsx
+++ b/apps/ledger-live-mobile/src/components/KeyboardView.tsx
@@ -21,7 +21,7 @@ const KeyboardView = React.memo(
const isExperimental = useExperimental();
const headerHeight = React.useContext(HeaderHeightContext) || 0;
let behaviorParam: KeyboardAvoidingViewProps["behavior"] | undefined;
- const keyboardVerticalOffset = isExperimental || Config.MOCK ? ExperimentalHeaderHeight : 0;
+ const keyboardVerticalOffset = isExperimental || Config.DETOX ? ExperimentalHeaderHeight : 0;
if (Platform.OS === "ios") {
behaviorParam = behavior || "height";
diff --git a/apps/ledger-live-mobile/src/components/LoadingFooter.tsx b/apps/ledger-live-mobile/src/components/LoadingFooter.tsx
index 3099265b22d4..0798bd5a782c 100644
--- a/apps/ledger-live-mobile/src/components/LoadingFooter.tsx
+++ b/apps/ledger-live-mobile/src/components/LoadingFooter.tsx
@@ -11,7 +11,7 @@ export default () => {
margin: 40,
}}
color={colors.live}
- animating={!Config.MOCK}
+ animating={!Config.DETOX}
/>
);
};
diff --git a/apps/ledger-live-mobile/src/components/Nft/NftGallery/NftList.tsx b/apps/ledger-live-mobile/src/components/Nft/NftGallery/NftList.tsx
index 619a02e4f1c8..9ac51b523b72 100644
--- a/apps/ledger-live-mobile/src/components/Nft/NftGallery/NftList.tsx
+++ b/apps/ledger-live-mobile/src/components/Nft/NftGallery/NftList.tsx
@@ -81,8 +81,8 @@ const NftList = ({ data, fetchNextPage, isLoading }: Props) => {
],
};
- const Fade_In_Down = Config.MOCK ? undefined : FadeInDown;
- const Fade_Out_Down = Config.MOCK ? undefined : FadeOutDown;
+ const Fade_In_Down = Config.DETOX ? undefined : FadeInDown;
+ const Fade_Out_Down = Config.DETOX ? undefined : FadeOutDown;
const renderItem = useCallback(
({ item, index }: { item: ProtoNFT; index: number; count?: number }) => (
diff --git a/apps/ledger-live-mobile/src/components/RequiresBLE/hooks/useEnableBluetooth.ts b/apps/ledger-live-mobile/src/components/RequiresBLE/hooks/useEnableBluetooth.ts
index c54f0972629e..ecaa2ca62e05 100644
--- a/apps/ledger-live-mobile/src/components/RequiresBLE/hooks/useEnableBluetooth.ts
+++ b/apps/ledger-live-mobile/src/components/RequiresBLE/hooks/useEnableBluetooth.ts
@@ -98,7 +98,7 @@ export function useEnableBluetooth(
const checkAndRequestAgain = useCallback(async () => {
// Early return when mocking, because when running LLM in an iOS simulator
// prompting the user to enable bluetooth services will randomly crash the app
- if (!isHookEnabled || Config.MOCK) return;
+ if (!isHookEnabled || Config.MOCK || Config.DETOX) return;
// We actually can't do anything with the result, as on iOS it will always be BLE_UNKNOWN_STATE
await promptBluetoothCallback();
diff --git a/apps/ledger-live-mobile/src/components/RootDrawer/InitialDrawers/PTXServicesAppleWarning.tsx b/apps/ledger-live-mobile/src/components/RootDrawer/InitialDrawers/PTXServicesAppleWarning.tsx
index 4b6012c7762a..f55e9d28b42d 100644
--- a/apps/ledger-live-mobile/src/components/RootDrawer/InitialDrawers/PTXServicesAppleWarning.tsx
+++ b/apps/ledger-live-mobile/src/components/RootDrawer/InitialDrawers/PTXServicesAppleWarning.tsx
@@ -44,7 +44,7 @@ export function PTXServicesAppleWarning() {
);
useEffect(() => {
- if (!exchangeDrawerEnabled && !ctaScreensEnabled && !Config.MOCK) {
+ if (!exchangeDrawerEnabled && !ctaScreensEnabled && !Config.DETOX) {
openDrawer();
} else {
_onClose();
diff --git a/apps/ledger-live-mobile/src/components/SelectableAccountsList.tsx b/apps/ledger-live-mobile/src/components/SelectableAccountsList.tsx
index 79d5aab3ecd7..b4a0bfaf616f 100644
--- a/apps/ledger-live-mobile/src/components/SelectableAccountsList.tsx
+++ b/apps/ledger-live-mobile/src/components/SelectableAccountsList.tsx
@@ -335,7 +335,11 @@ const Header = ({ text, areAllSelected, onSelectAll, onUnselectAll }: HeaderProp
onPress={areAllSelected ? onUnselectAll : onSelectAll}
hitSlop={selectAllHitSlop}
>
-
+
{areAllSelected ? (
) : (
diff --git a/apps/ledger-live-mobile/src/components/Skeleton.tsx b/apps/ledger-live-mobile/src/components/Skeleton.tsx
index 4bd12fd2d473..1a2ac52b4f40 100644
--- a/apps/ledger-live-mobile/src/components/Skeleton.tsx
+++ b/apps/ledger-live-mobile/src/components/Skeleton.tsx
@@ -27,7 +27,7 @@ const Skeleton: React.FC = ({
useEffect(() => {
// Disable animation when mock env because it was blocking Detox tests
- if (animated && !Config.MOCK) {
+ if (animated && !Config.DETOX) {
const duration = 1000;
const values = { min: 0.5, max: 1 };
diff --git a/apps/ledger-live-mobile/src/components/TabBar/Transfer.tsx b/apps/ledger-live-mobile/src/components/TabBar/Transfer.tsx
index be35d5e07376..b381dd9a8080 100644
--- a/apps/ledger-live-mobile/src/components/TabBar/Transfer.tsx
+++ b/apps/ledger-live-mobile/src/components/TabBar/Transfer.tsx
@@ -77,7 +77,7 @@ const BackdropPressable = Animated.createAnimatedComponent(styled(Pressable)`
background-color: rgba(0, 0, 0, 0.7);
`);
-const DURATION_MS = Config.MOCK ? 50 : 400;
+const DURATION_MS = Config.DETOX ? 50 : 400;
const Y_AMPLITUDE = 90;
const animParams = { duration: DURATION_MS };
@@ -199,7 +199,7 @@ export function TransferTabIcon() {
screenHeight -
bottomInset -
topInset -
- (isExperimental || Config.MOCK ? ExperimentalHeaderHeight : 0);
+ (isExperimental || Config.DETOX ? ExperimentalHeaderHeight : 0);
return (
<>
@@ -213,8 +213,8 @@ export function TransferTabIcon() {
maxHeight: drawerHeight,
paddingBottom: bottomInset + 16 + MAIN_BUTTON_SIZE + MAIN_BUTTON_BOTTOM,
},
- Config.MOCK ? {} : opacityStyle,
- Config.MOCK ? {} : translateYStyle,
+ Config.DETOX ? {} : opacityStyle,
+ Config.DETOX ? {} : translateYStyle,
]}
>
diff --git a/apps/ledger-live-mobile/src/families/cosmos/DelegationFlow/02-Summary.tsx b/apps/ledger-live-mobile/src/families/cosmos/DelegationFlow/02-Summary.tsx
index 2dcd50572893..b279b5da71ce 100644
--- a/apps/ledger-live-mobile/src/families/cosmos/DelegationFlow/02-Summary.tsx
+++ b/apps/ledger-live-mobile/src/families/cosmos/DelegationFlow/02-Summary.tsx
@@ -106,7 +106,7 @@ export default function DelegationSummary({ navigation, route }: Props) {
const [rotateAnim] = useState(() => new Animated.Value(0));
useEffect(() => {
- if (!Config.MOCK) {
+ if (!Config.DETOX) {
Animated.loop(
Animated.sequence([
Animated.timing(rotateAnim, {
diff --git a/apps/ledger-live-mobile/src/index.tsx b/apps/ledger-live-mobile/src/index.tsx
index 2cfc962a7b25..c0ce26ac9395 100644
--- a/apps/ledger-live-mobile/src/index.tsx
+++ b/apps/ledger-live-mobile/src/index.tsx
@@ -314,7 +314,7 @@ export default class Root extends Component {
}
onInitFinished = () => {
- if (Config.MOCK) {
+ if (Config.DETOX) {
init();
}
};
diff --git a/apps/ledger-live-mobile/src/screens/Account/AccountHeaderRight.tsx b/apps/ledger-live-mobile/src/screens/Account/AccountHeaderRight.tsx
index 7583dc446c95..dffadbe646f2 100644
--- a/apps/ledger-live-mobile/src/screens/Account/AccountHeaderRight.tsx
+++ b/apps/ledger-live-mobile/src/screens/Account/AccountHeaderRight.tsx
@@ -73,6 +73,7 @@ export default function AccountHeaderRight() {
)}
+
,
@@ -195,6 +200,7 @@ const AccountScreenInner = ({
keyExtractor={(_: unknown, index: number) => String(index)}
showsVerticalScrollIndicator={false}
onScroll={handleScroll}
+ testID={"account-screen-scrollView"}
/>
{
return (
}
arrowRight
onPress={() =>
diff --git a/apps/ledger-live-mobile/src/screens/AccountSettings/AdvancedLogs.tsx b/apps/ledger-live-mobile/src/screens/AccountSettings/AdvancedLogs.tsx
index 57b7775d6527..f576b67831a1 100644
--- a/apps/ledger-live-mobile/src/screens/AccountSettings/AdvancedLogs.tsx
+++ b/apps/ledger-live-mobile/src/screens/AccountSettings/AdvancedLogs.tsx
@@ -26,7 +26,7 @@ export default function AdvancedLogs({ route }: NavigationProps) {
const { t } = useTranslation();
const usefulData = {
xpub: (isAccount(account) && account?.xpub) || undefined,
- index: (isAccount(account) && account?.index) || undefined,
+ index: isAccount(account) && "index" in account ? account.index : undefined,
freshAddressPath: (isAccount(account) && account?.freshAddressPath) || undefined,
id: account?.id || undefined,
blockHeight: (isAccount(account) && account?.blockHeight) || undefined,
@@ -69,7 +69,7 @@ export default function AdvancedLogs({ route }: NavigationProps) {
time: readableDate,
})}
-
+
{JSON.stringify(usefulData, null, 2)}
diff --git a/apps/ledger-live-mobile/src/screens/Accounts/AccountRow.tsx b/apps/ledger-live-mobile/src/screens/Accounts/AccountRow.tsx
index 1b7a7398f310..16fd862b8a8b 100644
--- a/apps/ledger-live-mobile/src/screens/Accounts/AccountRow.tsx
+++ b/apps/ledger-live-mobile/src/screens/Accounts/AccountRow.tsx
@@ -110,6 +110,7 @@ const AccountRow = ({
currencyUnit={unit}
balance={account.balance}
name={name}
+ id={accountId}
countervalueChange={countervalueChange}
tag={tag}
topLink={topLink}
diff --git a/apps/ledger-live-mobile/src/screens/Accounts/ReadOnly/ReadOnlyAccountRow.tsx b/apps/ledger-live-mobile/src/screens/Accounts/ReadOnly/ReadOnlyAccountRow.tsx
index 8d4094dbb378..00599683bcc1 100644
--- a/apps/ledger-live-mobile/src/screens/Accounts/ReadOnly/ReadOnlyAccountRow.tsx
+++ b/apps/ledger-live-mobile/src/screens/Accounts/ReadOnly/ReadOnlyAccountRow.tsx
@@ -31,6 +31,7 @@ const ReadOnlyAccountRow = ({ navigation, currency, screen }: Props) => {
currencyUnit={units[0]}
balance={new BigNumber(0)}
name={name}
+ id={id}
progress={0}
/>
);
diff --git a/apps/ledger-live-mobile/src/screens/AddAccounts/03-Accounts.tsx b/apps/ledger-live-mobile/src/screens/AddAccounts/03-Accounts.tsx
index 7bc4695a5a7a..570aece13b10 100644
--- a/apps/ledger-live-mobile/src/screens/AddAccounts/03-Accounts.tsx
+++ b/apps/ledger-live-mobile/src/screens/AddAccounts/03-Accounts.tsx
@@ -350,7 +350,7 @@ function AddAccountsAccounts({
item.id}
ListHeaderComponent={ScanningHeader}
- ListEmptyComponent={}
+ ListEmptyComponent={}
/>
>
diff --git a/apps/ledger-live-mobile/src/screens/ReceiveFunds/ReceiveSecurityModal/index.tsx b/apps/ledger-live-mobile/src/screens/ReceiveFunds/ReceiveSecurityModal/index.tsx
index 5df10b5c5ba9..4aa398b06245 100644
--- a/apps/ledger-live-mobile/src/screens/ReceiveFunds/ReceiveSecurityModal/index.tsx
+++ b/apps/ledger-live-mobile/src/screens/ReceiveFunds/ReceiveSecurityModal/index.tsx
@@ -91,7 +91,7 @@ const ReceiveSecurityModal = ({
noCloseButton
preventBackdropClick
>
-
+
{component}
diff --git a/apps/ledger-live-mobile/src/sentry.ts b/apps/ledger-live-mobile/src/sentry.ts
index 2e8d5474bc46..331aa83079ad 100644
--- a/apps/ledger-live-mobile/src/sentry.ts
+++ b/apps/ledger-live-mobile/src/sentry.ts
@@ -82,7 +82,8 @@ const excludedErrorDescription = [
"Bad status on response: 503", // cryptoorg node
];
-const sentryEnabled = Config.SENTRY_DSN && (!__DEV__ || Config.FORCE_SENTRY) && !Config.MOCK;
+const sentryEnabled =
+ Config.SENTRY_DSN && (!__DEV__ || Config.FORCE_SENTRY) && !(Config.MOCK || Config.DETOX);
export function withSentry(App: React.ComponentType) {
if (sentryEnabled) {
diff --git a/apps/ledger-live-mobile/src/utils/constants.ts b/apps/ledger-live-mobile/src/utils/constants.ts
index 21855c86e586..77740f77e277 100644
--- a/apps/ledger-live-mobile/src/utils/constants.ts
+++ b/apps/ledger-live-mobile/src/utils/constants.ts
@@ -1,7 +1,7 @@
import Config from "react-native-config";
export const SYNC_DELAY = 2500;
-export const BLE_SCANNING_NOTHING_TIMEOUT = (Config.MOCK ? 60 : 30) * 1000;
+export const BLE_SCANNING_NOTHING_TIMEOUT = (Config.DETOX ? 60 : 30) * 1000;
export const GENUINE_CHECK_TIMEOUT = 120 * 1000;
export const VIBRATION_PATTERN_ERROR = [0, 150];
export const LEDGER_APPLE_WARNING_EXPLAINER_LINK =
diff --git a/libs/env/src/env.ts b/libs/env/src/env.ts
index b4936e40f388..7e2373d2b917 100644
--- a/libs/env/src/env.ts
+++ b/libs/env/src/env.ts
@@ -327,6 +327,11 @@ const envDefinitions = {
parser: boolParser,
desc: "disable the version check for firmware update eligibility",
},
+ DETOX: {
+ def: "",
+ parser: stringParser,
+ desc: "switch the app into a DETOX mode for test purpose. Avoid falsy values.",
+ },
EIP1559_MINIMUM_FEES_GATE: {
def: true,
parser: boolParser,
diff --git a/libs/ledger-live-common/.unimportedrc.json b/libs/ledger-live-common/.unimportedrc.json
index 58226330923f..3d7d50acefc8 100644
--- a/libs/ledger-live-common/.unimportedrc.json
+++ b/libs/ledger-live-common/.unimportedrc.json
@@ -306,6 +306,13 @@
"src/deviceSDK/commands/genuineCheck.ts",
"src/deviceSDK/commands/getAppAndVersion.ts",
"src/deviceSDK/tasks/genuineCheck.ts",
+ "src/e2e/enum/Account.ts",
+ "src/e2e/enum/AccountType.ts",
+ "src/e2e/enum/AppInfos.ts",
+ "src/e2e/enum/Currency.ts",
+ "src/e2e/enum/DeviceLabels.ts",
+ "src/e2e/enum/Fee.ts",
+ "src/e2e/enum/Swap.ts",
"src/exchange/swap/const/blockchain.ts",
"src/families/cardano/logic.ts",
"src/families/cardano/staking.ts",
diff --git a/apps/ledger-live-desktop/tests/enum/Account.ts b/libs/ledger-live-common/src/e2e/enum/Account.ts
similarity index 99%
rename from apps/ledger-live-desktop/tests/enum/Account.ts
rename to libs/ledger-live-common/src/e2e/enum/Account.ts
index 7009d6eb1ae5..44c1cace564e 100644
--- a/apps/ledger-live-desktop/tests/enum/Account.ts
+++ b/libs/ledger-live-common/src/e2e/enum/Account.ts
@@ -1,5 +1,5 @@
import { Currency } from "./Currency";
-import { AccountType } from "tests/enum/AccountType";
+import { AccountType } from "./AccountType";
export class Account {
constructor(
diff --git a/apps/ledger-live-desktop/tests/enum/AccountType.ts b/libs/ledger-live-common/src/e2e/enum/AccountType.ts
similarity index 100%
rename from apps/ledger-live-desktop/tests/enum/AccountType.ts
rename to libs/ledger-live-common/src/e2e/enum/AccountType.ts
diff --git a/apps/ledger-live-desktop/tests/enum/AppInfos.ts b/libs/ledger-live-common/src/e2e/enum/AppInfos.ts
similarity index 100%
rename from apps/ledger-live-desktop/tests/enum/AppInfos.ts
rename to libs/ledger-live-common/src/e2e/enum/AppInfos.ts
diff --git a/apps/ledger-live-desktop/tests/enum/Currency.ts b/libs/ledger-live-common/src/e2e/enum/Currency.ts
similarity index 98%
rename from apps/ledger-live-desktop/tests/enum/Currency.ts
rename to libs/ledger-live-common/src/e2e/enum/Currency.ts
index c4d7c3b57a46..33b217d0657b 100644
--- a/apps/ledger-live-desktop/tests/enum/Currency.ts
+++ b/libs/ledger-live-common/src/e2e/enum/Currency.ts
@@ -53,7 +53,7 @@ export class Currency {
"bsc",
AppInfos.BINANCE_SMART_CHAIN,
);
- static readonly TON = new Currency("Ton", "TON", "ton", AppInfos.TON);
+ static readonly TON = new Currency("TON", "TON", "ton", AppInfos.TON);
static readonly ETH_USDT = new Currency("Tether USD", "USDT", "ethereum", AppInfos.ETHEREUM);
static readonly ETH_LIDO = new Currency(
"LIDO Staked ETH",
diff --git a/apps/ledger-live-desktop/tests/enum/DeviceLabels.ts b/libs/ledger-live-common/src/e2e/enum/DeviceLabels.ts
similarity index 100%
rename from apps/ledger-live-desktop/tests/enum/DeviceLabels.ts
rename to libs/ledger-live-common/src/e2e/enum/DeviceLabels.ts
diff --git a/apps/ledger-live-desktop/tests/enum/Fee.ts b/libs/ledger-live-common/src/e2e/enum/Fee.ts
similarity index 100%
rename from apps/ledger-live-desktop/tests/enum/Fee.ts
rename to libs/ledger-live-common/src/e2e/enum/Fee.ts
diff --git a/apps/ledger-live-desktop/tests/enum/Swap.ts b/libs/ledger-live-common/src/e2e/enum/Swap.ts
similarity index 100%
rename from apps/ledger-live-desktop/tests/enum/Swap.ts
rename to libs/ledger-live-common/src/e2e/enum/Swap.ts
diff --git a/libs/ledger-live-common/src/hw/actions/implementations.ts b/libs/ledger-live-common/src/hw/actions/implementations.ts
index f2cca5571899..63470b675db5 100644
--- a/libs/ledger-live-common/src/hw/actions/implementations.ts
+++ b/libs/ledger-live-common/src/hw/actions/implementations.ts
@@ -63,7 +63,7 @@ export const defaultImplementationConfig: PollingImplementationConfig = {
pollingFrequency: 2000,
initialWaitTime: 5000,
reconnectWaitTime: 5000,
- connectionTimeout: getEnv("MOCK") ? 60000 : 20000,
+ connectionTimeout: getEnv("DETOX") ? 60000 : 20000,
};
type Implementation = (
params: PollingImplementationParams,
diff --git a/libs/ledger-live-common/src/platform/providers/RemoteLiveAppProvider/api/index.ts b/libs/ledger-live-common/src/platform/providers/RemoteLiveAppProvider/api/index.ts
index ee5db24befe3..aee10c2172d1 100644
--- a/libs/ledger-live-common/src/platform/providers/RemoteLiveAppProvider/api/index.ts
+++ b/libs/ledger-live-common/src/platform/providers/RemoteLiveAppProvider/api/index.ts
@@ -7,7 +7,7 @@ import mockData from "./mock.json";
const api = {
fetchLiveAppManifests: async (url: string, params?: FilterParams): Promise => {
- if (getEnv("MOCK")) {
+ if (getEnv("MOCK") || getEnv("DETOX")) {
if (getEnv("MOCK_REMOTE_LIVE_MANIFEST")) {
return [
...mockData,
diff --git a/libs/speculos-transport/src/index.ts b/libs/speculos-transport/src/index.ts
index d365acb56b46..16b33ff782b7 100644
--- a/libs/speculos-transport/src/index.ts
+++ b/libs/speculos-transport/src/index.ts
@@ -24,13 +24,13 @@ export type SpeculosDeviceInternal =
buttonPort: number;
automationPort: number;
transport: SpeculosTransportWebsocket;
- destroy: () => void;
+ destroy: () => Promise;
}
| {
process: ChildProcessWithoutNullStreams;
apiPort: string | undefined;
transport: SpeculosTransportHttp;
- destroy: () => void;
+ destroy: () => Promise;
};
// FIXME we need to figure out a better system, using a filesystem file?
@@ -235,10 +235,10 @@ export async function createSpeculosDevice(
});
let destroyed = false;
- const destroy = () => {
+ const destroy = async () => {
if (destroyed) return;
destroyed = true;
- new Promise((resolve, reject) => {
+ return new Promise((resolve, reject) => {
if (!data[speculosID]) return;
delete data[speculosID];
exec(`docker rm -f ${speculosID}`, (error, stdout, stderr) => {
@@ -259,7 +259,7 @@ export async function createSpeculosDevice(
}
});
let latestStderr: string | undefined;
- p.stderr.on("data", data => {
+ p.stderr.on("data", async data => {
if (!data) return;
latestStderr = data;
@@ -276,16 +276,16 @@ export async function createSpeculosDevice(
} else if (data.includes("address already in use")) {
if (maxRetry > 0) {
log("speculos", "retrying speculos connection");
- destroy();
+ await destroy();
resolveReady(false);
}
}
});
- p.on("close", () => {
+ p.on("close", async () => {
log("speculos", `${speculosID} closed`);
if (!destroyed) {
- destroy();
+ await destroy();
rejectReady(new Error(`speculos process failure. ${latestStderr || ""}`));
}
});