This document describes the test order, the test sections, and which tests provide setup/inputs for later tests.
The test runner in this repo is the in-app Moniker harness. The order is determined by the tests=[...] array in the Moniker panel.
- Order matters. Some tests produce values (like onion hostnames) that later tests depend on.
- No fallback knowing. If a required prerequisite is missing, the test should fail fast.
- Bounded waits only. All waits/retries must be finite and verifiable.
That file lists tests in the intended run order.
Goal: Prove both apps are running and can exchange data deterministically before starting Tor-related tests.
Why this exists:
- Tor bootstrap can be variable on Android.
- Cross-device tests are much easier to reason about if we first confirm both sides are alive and able to coordinate.
- File: src/e2e_tests/duoAlign.js
- Runs in both Electron renderer and React Native.
- Uses the Duo coordinator (Socket.IO) started by the duo runner:
- Coordinator URL:
http://127.0.0.1:45820 - Android reaches it via
adb reverse(see duo runner steps below)
- Coordinator URL:
What it verifies (in order):
- Both sides connect to the coordinator and
registerwith arole(electronorandroid). - Both sides observe
peerConnected(meaning both roles are present). - Both sides signal
duoAlignedand wait for the coordinator’sduoAlignedbroadcast. - Data swap with validation: each side sends a small
duoDatapayload and waits until the coordinator broadcasts both payloads back.- Each side validates it got its own echoed payload and the peer’s payload.
Why the data swap matters:
- It proves the coordinator channel is bidirectional and not just “connected”.
- It removes “blind timeouts” where one side starts a test before the other side is ready.
Goal: Prove Tor is installable/bootable and that each platform can host or use Tor locally.
Order and purpose:
- RnTorSmoke (Android/React Native only)
- File: src/e2e_tests/rnTorSmoke.js
- Runs only in React Native.
- Verifies:
- RN Tor service is present and
tor.status()returns sane values
- RN Tor service is present and
- RnTorHosting (Android/React Native only)
- File: src/e2e_tests/rnTorHosting.js
- Runs only in React Native.
- Verifies:
- RN can host a local TCP server
- RN can configure a Tor hidden service with a fresh random onion
- RN can fetch that onion over Tor SOCKS
What this subsection provides:
- Confidence that Tor is installed and can boot.
- A baseline expectation for Tor startup time on the device.
Goal: Prove two devices can connect and exchange a small framed message over Tor (no Gun).
There are two tests that cooperate:
- TorProtoExchangeHost (Electron only)
- File: src/e2e_tests/torProtoExchangeHost.js
- Runs only in Electron renderer.
- Responsibilities:
- Start a local framed protocol server (TCP)
- Create a fresh hidden service (random onion) mapping onion port
8888→ local protocol TCP port - Publish exchange parameters to the Duo coordinator via Socket.IO (e.g. onion hostname and port)
- TorProtoExchangeClient (Android/React Native only)
- File: src/e2e_tests/torProtoExchangeClient.js
- Runs only in React Native.
- Responsibilities:
- Use the deep link only as the signal that the run is in “duo mode” (the deep link is fixed)
- Connect to the Duo coordinator and receive exchange parameters via Socket.IO
- Start Tor and wait until
tor.status().running === true - Dial
tcp://<onion>.onion:8888via Tor SOCKS usingguncelium-protocal - Send a framed
ping; wait for framedpong
What this subsection provides:
- A single, end-to-end signal that cross-device Tor + SOCKS + framed protocol are working.
- Script: scripts/duo-electron-android.js
What it does:
- Starts Electron via
npm run electron:start(which also starts Metro) - Starts a local Duo coordinator server (Socket.IO) on
127.0.0.1:45820 - Runs
adb reversefor required ports (defaults:8081and45820) - Stops/kills the Android app
- Launches Android via a fixed deep link (
guncelium://e2e/duo/v1) - Exits after two Moniker completions are observed
Coordinator behavior (high-level):
- Tracks which roles are connected (
electronandandroid). - Broadcasts
peerConnectedonce both roles are present. - Implements barriers/events used by tests:
duoAligned(both roles confirm they are ready)duoData(both roles send a small payload; coordinator broadcasts both back)exchangeParams(Electron host sends onion details; Android client receives them)
Common causes we’ve seen during runs:
- Tor on Android sometimes needs more time to bootstrap (especially on first run, or if the device is resource constrained).
- Starting network clients before
tor.status().running === trueleads to early SOCKS handshake failures.
Mitigations in current tests:
- Cross-device client waits for
tor.status()to report running before attempting any SOCKS dial. - Cross-device host allows a longer bounded wait for the Android ping.
Additional note:
- The Duo coordinator eliminates several race conditions (e.g., Android starting its Tor/Gun dial before Electron finished creating the hidden service), but Tor itself can still be slow to bootstrap.
Goal: Test Gun functionality separately from Tor connectivity, so failures are attributable.
These are the current default “local-first” Gun health checks:
- Electron: src/e2e_tests/gunLocalElectron.js
- React Native: src/e2e_tests/gunLocalReactNative.js
They verify basic put + once behavior in each environment without involving Tor.
- File: src/e2e_tests/torGunHosting.js
- Runs in Electron renderer.
- What it verifies (high-level):
- Electron Gun service can start an HTTP/WS peer endpoint.
- Two renderer Gun clients can connect and replicate a small value.
Note: This test is currently not in the default Moniker run order (the Tor section is intentionally protocol-only). To run it, add it back into the list in src/init/panels/MonikerPanel.js.
These are end-to-end integration tests for Gun replication over the framed TCP transport over Tor.
They are intentionally documented separately from Section 1 because:
- Tor bootstrap + SOCKS dial readiness is one failure domain.
- Gun replication behavior is a different failure domain.
If you enable these tests, keep src/e2e_tests/duoAlign.js first so coordinator alignment stays deterministic.
Tor tests may be temporarily commented out in the default Moniker run order while stabilizing the local-first Gun layer. Check the current test list in src/init/panels/MonikerPanel.js.