Skip to content

Authenticated visual-regression suite (full leg) broken in CI — and the gate doesn't catch it #189

Description

@Danswar

Summary

The full matrix leg of the Visual Regression workflow (e2e/visual/authenticated.test.ts) has never passed in CI. It was introduced in #186 and merged without the leg ever going green — possible because the check is non-required and only runs on PR open/label (not on pushes). Two distinct bugs block it: the first is fixed and validated locally; the second needs a small test redesign.

Symptom

  • Job: iOS Visual Regression (full). Example failing run: https://github.com/DFXswiss/dfx-wallet/actions/runs/27835644312
  • Onboard (PIN + legal) → reaches the dashboard times out; every later authenticated block (Settings, Seed export, Hardware connect, Multi-sig ×2) then cascade-fails on verify-pin-screen, because the wallet the blocks reuse was never created.
  • The 2 passkey screens (no wallet init) pass.

Root cause #1 — onboard hang (FIXED, validated locally)

On "Continue", app/(onboarding)/create-wallet.tsx calls WDK restoreWallet() and only navigates to setup-pin after it resolves. WDK initializes all 8 configured chains (ethereum/arbitrum/polygon/base/spark/bitcoin/plasma/sepolia) on first wallet setup, each with its own RPC/bundler round-trips. On a fresh CI simulator this exceeds the test timeout (observed: 225 s, still unfinished). The suite's own German handbook entry already documents "WDK-Init nach Continue … bis zu 120 s".

Fix: gate the chain set behind an allowlist env var so the E2E build inits a minimal set. Production is unaffected — the allowlist only applies when the env var is set.

src/config/chains.ts — split the network object into buildAllNetworks() and filter:

export const getWdkConfigs = (): WdkConfigs => {
  const networks = buildAllNetworks();
  const allow = process.env.EXPO_PUBLIC_WDK_CHAINS?.split(',')
    .map((id: string) => id.trim())
    .filter(Boolean);
  if (!allow?.length) return { networks }; // unset → all chains (prod)
  const filtered = Object.fromEntries(
    Object.entries(networks).filter(([id]) => allow.includes(id)),
  ) as WdkConfigs['networks'];
  return { networks: filtered };
};

.env.testnet:

EXPO_PUBLIC_WDK_CHAINS=sepolia,bitcoin

Local validation (iOS release build, iPhone 17 Pro sim): with the trim, Onboard (PIN + legal) → reaches the dashboard completes in ~43 s (was hanging > 180 s). Passkey + onboard tests pass.

Root cause #2 — relaunch + PIN-unlock hang (NOT yet fixed)

Once a wallet exists, the WDK worklet keeps the app's JS thread continuously busy — the app never goes "idle" (the suite header comment acknowledges this: "the WDK keeps the main queue busy"). The per-screen pattern relaunchToDashboard() cold-restarts the app and re-enters the PIN. Detox waits for the app to be idle during:

  • device.launchApp() — synchronization is re-enabled on every new instance (per Detox docs), and
  • enterPin() — which calls device.enableSynchronization().

So both block indefinitely (observed > 13 min stuck on Run loop "JS Run Loop" is awake). The Android launch arg that starts an instance with synchronization disabled (detoxEnableSynchronization) does not exist on iOS, so this is not a one-line fix.

Proposed fix (option A): restructure the suite to onboard once and navigate screen-to-screen without relaunching, keeping synchronization disabled throughout (exactly as the onboard flow already does successfully). Alternatives: (B) make the app idle in the E2E build by gating WDK/balance background activity — uncertain, since the busyness is the worklet itself, not just the 30 s balance refetch; (C) keep relaunch but drive launch + PIN-unlock fully sync-disabled.

Why CI didn't catch this (the gate hole)

The Visual Regression check is:

  • not a required check, so a red run never blocks merge; and
  • configured to skip pushes (types: [opened, reopened, ready_for_review, labeled] — no synchronize), so it doesn't run on iterative commits.

That combination let #186 merge a suite that had never passed, with the PR showing green. Recommendation: once the suite is fixed and proven stable, make it required and run it on push. Tradeoff: it's a ~30-min macOS build, so any flakiness would block merges — a team decision, not a pure win.

Next steps

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions