Swap E2E Skill

SkillWeb & browsing

Write or update Swap E2E tests for Ledger Live Desktop (Playwright) and Mobile (Detox). Use for swap spec updates, provider flows, multi-step approvals, page-object refactors, swap-history checks, KYC/validation banners, and review-driven cleanup.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Swap E2E Skill skill

What this skill tells your AI

The instructions your AI receives, as published by ledgerhq/ledger-live in .agents/skills/e2e-swap/SKILL.md and read by ahel’s review.

Use this skill when

  • Updating swap tests in e2e/desktop or e2e/mobile.
  • Refactoring swap page objects or moving reusable flow logic out of specs.
  • Fixing PR review comments about dead code, selector ownership, brittle amounts, or multi-step approval assertions.

Current source of truth

  • Desktop specs: e2e/desktop/tests/specs/*swap*.spec.ts
  • Desktop swap shared utils:
    • e2e/desktop/tests/utils/swapUtils.ts
  • Desktop page objects:
    • e2e/desktop/tests/page/swap.page.ts
    • e2e/desktop/tests/page/drawer/swap.confirmation.drawer.ts
  • Mobile builders/specs:
    • e2e/mobile/specs/swap/otherTestCases/swap.other.ts
    • e2e/mobile/specs/swap/**/*.spec.ts
  • Mobile page objects:
    • e2e/mobile/page/liveApps/swapLiveApp.ts
    • e2e/mobile/page/trade/swap.page.ts

Platform model

  • Desktop:
    • Electron can expose multiple windows (main app + one or more webviews).
    • Resolve swap webview via WebViewAppPage.getWebView() using webviewIdentifier title matching, not fixed electronApp.windows()[N] indexes.
    • SwapPage methods usually receive electronApp.
    • SwapConfirmationDrawer methods act on the main window.
  • Mobile:
    • Webview operations use Detox web helpers.
    • Native operations use regular Detox matchers.

Implementation rules

  • Keep selectors centralized in page objects, not inline in specs.
  • Keep test IDs as class properties in page objects (avoid repeated string literals in methods).
  • Do not define reusable workflow methods in spec files. Put them in page objects (for atomic UI actions) or shared utils (for multi-step flows).
  • Remove dead methods/fields quickly; do not keep unused helpers.
  • Keep single-use constants local to the narrowest scope that uses them.
  • Reuse existing provider helper selectSpecificProvider(...) before adding new variants.
  • Prefer runtime UI assertions over cross-repo filesystem assertions.
  • Prefer if/else in @Step methods over early return branches for readability and reporting consistency.
  • When replacing all occurrences in strings, prefer replaceAll() over regex-based replace() where equivalent.
  • Avoid unnecessary non-null assertions (!); prefer type-safe narrowing/guards.
  • For fragile swap amounts, fetch minimum dynamically with:
    • app.swap.getMinimumAmount(...) (desktop)
    • app.swapLiveApp.getMinimumAmount(...) (mobile)

Desktop patterns (current API)

  • Keep assertion method prefixes consistent within a page object (check*).
  • In SwapPage, prefer const webview = await this.getWebView() for swap webview context. Do not pass electronApp unless a method explicitly needs non-webview Electron windows/events.
  • Current Changelly UI swap pattern:
    • performSwapUntilQuoteSelectionStep(...)
    • app.swap.selectSpecificProvider(Provider.CHANGELLY, electronApp)
    • const amountToSend = await app.swap.getAmountToSend(electronApp) (only when needed by follow-up assertions)
  • Avoid reintroducing removed generic/dead helpers:
    • checkBannerVisibility(...) (removed)
    • verifyContinueButtonVisible() in desktop swap page (removed)
    • selectProviderQuoteWithRetry(...) in swap utils (removed)

Mobile patterns (current API)

  • Multi-step flow should assert progression, not only click:
    • tapExecuteSwap()
    • tapExecuteSwapOnStepApproval() (includes post-click wait to send summary)
  • Do not reintroduce removed JS-click helper tapSwapOnMultiStepApproval() unless there is a proven regression and a documented reason.
  • Swap history feedback link assertion should be page-object driven:
    • app.swap.checkSwapHistoryFeedbackFormUrl(expectedUrl)
    • Prefer platform-specific attributes for URL assertion (value on iOS, label on Android).
  • Do not add unused icon selector fields (networkFeesInfoIcon, rateInfoIcon).

Validation before finishing

Run validation for the impacted E2E package(s), not the whole monorepo:

  • Desktop:
    • pnpm --filter ledger-live-desktop-e2e-tests typecheck
    • Run targeted Playwright tests for changed swap specs when environment allows.
  • Mobile:
    • pnpm --filter ledger-live-mobile-e2e-tests typecheck
    • Run targeted Detox tests for changed swap specs when environment allows.

Validation workflow notes:

  • Reuse an existing watch terminal when available before starting a new watcher.
  • Prefer watch mode where scripts support it.

If unrelated pre-existing failures appear, explicitly report them as pre-existing and keep scope focused on swap changes.

PR review comment workflow

For each comment:

  1. Verify current code and usages (rg for symbol usage).
  2. Classify:
    • real change needed,
    • duplicate comment,
    • stale/already addressed.
  3. Implement only real changes.
  4. Prepare explicit PR replies for stale/duplicate/already-fixed comments.

Quick checklist

  • No inline repeated test IDs in specs when page object exists.
  • No dead selectors/helpers added.
  • Multi-step mobile flow has a post-click state assertion.
  • Amounts are not hardcoded where minimum is provider-dependent.
  • Desktop assertions use correct window context.
  • Typecheck and relevant test commands were attempted/reported.

Signals

GitHub stars
618
Forks
490
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
e2e-swap
Source
github.com/ledgerhq/ledger-live