Skip to content

Investigate device-level (E2E) tests for the mobile app #791

Description

@hanzei

Background

The mobile app has 95 Jest files under mobile/__tests__/, all unit/component level. They are genuinely good — jest.setup.js provides an in-memory expo-file-system mock reachable as globalThis.mockFileSystem, so the real src/utils/fs.ts logic runs rather than being stubbed out. What none of them do is exercise the app on a device or emulator.

For comparison, the webapp has 21 Playwright specs (webapp/e2e/tests/) covering complete browser workflows. Mobile has zero equivalent coverage, and neither Detox nor Maestro appears in mobile/package.json.

There is already an artifact to test against: .github/workflows/mobile-apk.yml builds a release APK on master pushes and v* tags, using expo prebuild + gradle on ubuntu-latest with NDK/CMake pre-installed. A device-level suite could run against that build rather than standing up its own.

Why it matters here

The mobile app carries the most state-heavy logic in the repo, and it is exactly the logic that unit tests model rather than exercise:

  • Offline write queue and replaysrc/db/syncQueue.ts (1,018 lines), src/db/noteQueries.ts (1,045 lines). Correctness depends on real SQLite, real connectivity transitions, and app backgrounding/restart, all of which are simulated today.
  • Multi-server connect flowsrc/screens/ConnectToServerScreen.tsx (756 lines) plus src/store/upgradeToServer.ts (525 lines), covering local-only → server-backed migration.
  • Share-to-note intents (Android/iOS) and app-icon quick actions — both are OS-level integrations that cannot be tested in Jest at all.
  • SSE reconnect behaviour across network loss and process lifecycle.

See docs/specs/mobile-connectivity-handling.md for the invariants that currently have no end-to-end verification.

Scope of the investigation

  1. Compare Maestro vs Detox for this app: setup cost against an Expo prebuild project, flakiness, maintenance, and whether either can drive the OS-level share sheet and app-icon shortcuts.
  2. Determine CI cost: Android emulator boot + test time on ubuntu-latest, and whether that fits a PR gate or belongs on a nightly/master-only schedule. (iOS runners are considerably more expensive — decide whether the investigation covers iOS at all or Android only for now.)
  3. Pick the smallest set of flows worth covering first. Candidate smoke path: connect to server → create note → go offline → edit → come back online → verify the edit replayed.
  4. Decide how it hangs off the existing tooling — a task test-mobile-e2e sibling to task test-e2e, and whether it reuses the APK from mobile-apk.yml or builds its own.
  5. Decide the fixture story: the webapp e2e suite spins up a throwaway Go server via Playwright's webServer. A mobile suite needs the same thing reachable from an emulator.

Acceptance

  • A written recommendation (framework, CI placement, initial flow set, expected runtime), with the option of concluding that the emulator cost is not worth it right now.
  • If adopted: one smoke flow green in CI, plus documentation in mobile/CLAUDE.md and the README following the pattern task test-e2e uses (including how to install prerequisites, mirroring scripts/check-playwright-browser.sh).

Out of scope

  • Replacing any existing Jest coverage — device-level tests are additive, aimed at the flows Jest structurally cannot reach.
  • App store / release automation.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions