Skip to content

E2E:Desktop

Victor Alber edited this page May 20, 2026 · 1 revision

Ledger Live Desktop E2E

Ledger Live Desktop E2E tests use Playwright with Electron and Speculos. Shared setup, Speculos behavior, reporting, best practices, and troubleshooting live in the shared E2E pages.

Before running Desktop tests, complete E2E prerequisites & environment.

Interactive Setup

Use the Cursor command /e2e-desktop-onboard for a guided setup. It checks prerequisites, validates the environment, builds the app, and runs a smoke test.

Local Execution

All Desktop build and test commands below are run from the repository root, ledger-live/.

Build

Before executing tests, build the app and dependencies whenever source code changes:

pnpm i --filter="ledger-live-desktop..." --filter="live-cli..." --filter="ledger-live" --filter="@ledgerhq/dummy-*-app..." --filter="ledger-live-desktop-e2e-tests" --unsafe-perm
pnpm build:lld:deps
pnpm build:cli
pnpm desktop build:testing

Install Playwright dependencies:

pnpm e2e:desktop test:playwright:setup

Run Tests

Run a single test:

pnpm e2e:desktop test:playwright <testFileName>

Run all tests:

pnpm e2e:desktop test:playwright

CI Execution

Nightly Run

A nightly run of the full test suite is scheduled to ensure ongoing bug detection. The result of this run is visible in the #live-repo-health Slack channel.

You can also execute Speculos tests on CI using the @Desktop - UI e2e - Test App workflow.

The workflow supports:

  • Filtering tests by suite name, for example swap.
  • Selecting the backend used to execute the tests.
  • Sending notifications to Slack.
  • Sending results to Xray.
  • Enabling or disabling transaction broadcast according to the workflow inputs.

To filter tests in CI, use the workflow input labeled:

Filter test pattern to execute only tests suites named according to pattern(s) separated by '|' (e.g., to execute accounts and settings describe blocks 'Accounts @smoke' or 'Accounts @smoke|Settings')

Investigating Failures

When a Desktop E2E test fails:

  1. Check screenshots in the Allure report.
  2. Review logs generated during execution.
  3. Rerun the failed test in isolation.
  4. Use Desktop debugging flags such as PWDEBUG and DEV_TOOLS for local investigation.

Reporting

Desktop test results are reported through Allure. For shared reporting behavior, see E2E CI, reporting & Xray.

To generate and access the Allure report locally, install allure-commandline and run:

cd e2e/desktop
allure serve

Writing Desktop Tests

Development Workflow

Before creating a new test, check whether the element, page object, or test already exists. If possible, add the scenario to the relevant existing test file.

Step 1 - Identify Elements

To interact with web elements such as buttons, input fields, and images, identify unique elements with a data-testId or multiple elements with a class.

Convention:

<context>-<text-or-purpose>-<element-type>

Example:

<button data-testId="onboarding-getstarted-button">Get started</button>

For shared selector guidance, see E2E best practices.

Step 2 - Create A Page Object

Page objects are JavaScript classes that encapsulate the elements and actions of a specific screen.

Desktop page object path:

ledger-live/apps/ledger-live-desktop/tests/page

Example for the onboarding screen:

private getStartedButton = this.page.getByTestId("onboarding-getstarted-button");

Add an action:

@step("Click on get Started Button")
async clickGetStarted() {
  await expect(this.getStartedButton).toBeVisible();
  await this.getStartedButton.click();
}

Annotate action methods with the @step decorator to improve reporting and traceability.

Complete example:

import { AppPage } from "tests/page/abstractClasses";
import { expect } from "@playwright/test";
import { step } from "tests/misc/reporters/step";

export class OnboardingPage extends AppPage {
  private getStartedButton = this.page.getByTestId("onboarding-getstarted-button");

  @step("Click on get Started Button")
  async clickGetStarted() {
    await expect(this.getStartedButton).toBeVisible();
    await this.getStartedButton.click();
  }
}

Step 3 - Create A Test File

If a test file already exists, do not create a new one. Add your test to the existing file that owns the scenario.

Desktop Speculos test path:

ledger-live/apps/ledger-live-desktop/tests/specs/speculos/

Example:

test.describe("Onboarding test - Example", () => {
  test.use({
    userdata: "skip-onboarding",
  });

  test(
    "Onboarding test - Example",
    {
      annotation: {
        type: "TMS",
        description: "B2CQA-xxx",
      },
    },
    async ({ app }) => {
      await addTmsLink(
        getDescription(test.info().annotations, "TMS").split(", "),
      );
      await app.onboarding.clickGetStarted();
    },
  );
});

Link every test case to the corresponding Xray ticket by replacing B2CQA-xxx with the correct key.

To use onboarding.clickGetStarted() in a test, import and instantiate the page object in ledger-live/apps/ledger-live-desktop/tests/page/index.ts:

import { PageHolder } from "tests/page/abstractClasses";
import { OnboardingPage } from "../page/onboarding.page";

export class Application extends PageHolder {
  public onboarding = new OnboardingPage(this.page);
}

When using Speculos, the test.use setup should include the Speculos app:

test.use({
  userdata: "skip-onboarding",
  speculosApp: currency.currency.speculosApp,
});

Step 4 - Run The Test

Run a new test at least three times before considering it stable:

pnpm desktop test:playwright:speculos <newTest>

If you have screenshot assertion issues, see the Playwright documentation for page screenshot assertions and locator screenshot assertions.

Desktop Debugging

Playwright And DevTools

To debug tests that fail locally, set the following environment variables before running tests:

  • PWDEBUG=1: enables the Playwright debugger.
  • DEV_TOOLS=1: opens the Ledger Live developer tools.

Example:

PWDEBUG=1 DEV_TOOLS=1 pnpm desktop test:playwright:speculos swap

Feature Flag Userdata

To run a test with specific feature flags without modifying Firebase, manually add the feature flags to the app.json file used by the test. The file is located in the userdata folder.

Custom Feature Flags

Use E2E_FEATURE_FLAGS_JSON to inject extra feature flags globally for Desktop E2E:

export E2E_FEATURE_FLAGS_JSON='{"myFeature":{"enabled":true,"params":{"foo":"bar"}}}'

The value must be a JSON object. Arrays, scalars, and invalid JSON are rejected.

E2E_FEATURE_FLAGS_JSON is merged with the default E2E flags. Per-test featureFlags fixture values still override environment-provided values when both set the same key.

Desktop Resources

Releases

Documentation

Code Coverage

Clone this wiki locally