Skip to content

test: E2E Testing Roadmap — End-Goal State & Phased Plan #599

@thepastaclaw

Description

@thepastaclaw

DET E2E Testing: End-Goal Plan

Current State

Test Infrastructure

DET has two test suites using egui_kittest:

1. tests/kittest/ — Offline UI Tests (32 tests)

Fast, no network, run in CI. Test basic rendering and interactions:

  • interactions.rs (17 tests): Welcome screen, screen switching, sidebar navigation, button presence
  • wallets_screen.rs (3 tests): Wallet screen rendering, action buttons, import mnemonic screen
  • identities_screen.rs (4 tests): Identity screen rendering, add identity buttons, key display
  • network_chooser.rs (3 tests): Network chooser screen rendering, network labels
  • create_asset_lock_screen.rs (3 tests): Asset lock screen rendering, wallet selector
  • startup.rs (1 test): App boots without panicking

2. tests/e2e/ — Live Testnet Journey (1 ignored test)

Sequential phased test against real testnet. Requires E2E_WALLET_MNEMONIC env var with a funded wallet:

Phase Name What It Tests Status
Smoke App Init Boot, AppContext, SPV idle, wallets lock, network ✅ Working
0 Setup Wallet import via UI, SPV sync, balance check ✅ Working
1 Wallet UI Sidebar nav, wallet card display, balance rendering ✅ Working
2 Wallet Ops Send/Receive buttons, wallet address verification ✅ Working
3 Platform Reads DPNS lookup by name, contract fetch by ID ✅ Working
4 Token Search Keyword search, results rendering ✅ Working
5 Identity Client-side validation tests only ⚠️ Partial (creation disabled)
6 DPNS Name registration ❌ Skipped (depends on Phase 5)
7 Teardown SPV stop, wallet/identity cleanup ✅ Working

Test Harness Features:

  • egui_kittest::Harness wrapping AppState with AccessKit queries
  • wait_until / wait_for_label polling helpers (like WebdriverIO's waitUntil)
  • Error classification (Network/Validation/Transient/Fatal) with retry logic
  • TestContext struct for cross-phase state
  • Emergency cleanup on panic
  • Navigation helpers (direct selected_main_screen manipulation + screen_stack)
  • SPV readiness gates before transaction phases

Key Limitations

  • AccessKit interactions are unreliable — clicks and text input via AccessKit don't always propagate in kittest. The tests work around this by manipulating screen state directly (e.g., import_wallet_via_ui sets fields programmatically, not via UI clicks).
  • Identity creation disabled — needs SPV mempool support for asset lock proof confirmation. This blocks DPNS registration too.
  • No mock/stub infrastructure — e2e tests hit real testnet. No way to run them without network.

Gaps Analysis

Screens/Features With ZERO Test Coverage

High Priority (Core Features)

  1. Wallet Send (WalletSendScreen) — no test for constructing or broadcasting a transaction
  2. Identity Creation (AddNewIdentityScreen) — only validation tests, no actual creation flow
  3. Identity Top-Up (TopUpIdentity) — untested
  4. DPNS Name Registration (RegisterDpnsName) — skipped, blocked on identity creation
  5. Credit Withdrawal (WithdrawalScreen) — untested
  6. Credit Transfer (TransferScreen) — untested
  7. Key Management (AddKeyScreen, KeyInfo, Keys) — untested

Medium Priority (Platform Features)

  1. Data Contracts — register (RegisterContract), update (UpdateContract), fetch (AddContracts)
  2. Document Operations — create, delete, replace, transfer, purchase, set price (6 screen types)
  3. DPNS Contested Names — active contests, past contests, scheduled votes, voting
  4. Token Operations — mint, burn, transfer, freeze/unfreeze, pause/resume, claim, purchase, set price, create, update config (12+ screen types)
  5. DashPay — contacts, profile, payments, search, QR codes (10+ screen types)
  6. Group Actions (GroupActions) — untested

Lower Priority (Tools/Visualization)

  1. Proof Log / Proof Visualizer — rendering tests only needed
  2. Transition Visualizer / Document Visualizer / Contract Visualizer — rendering
  3. Masternode List Diff — rendering
  4. Platform Info — rendering
  5. Grove STARK — rendering
  6. Address Balance — rendering + query

Infrastructure Gaps

  • No mocked network layer — can't test platform operations without testnet
  • No CI integration for e2e — tests are #[ignore]'d
  • No snapshot/screenshot testing — no visual regression detection
  • No error path testing — only happy paths in e2e; error dialogs untested beyond basic dismiss
  • No concurrent operation testing — what happens when multiple backend tasks run simultaneously
  • No persistence testing — close app, reopen, verify state survives

End-Goal Vision

Three-Tier Test Architecture

┌─────────────────────────────────────────────────┐
│  Tier 3: Live E2E (testnet)                     │
│  ─ Full user journeys against real network       │
│  ─ Runs nightly or on-demand                     │
│  ─ Tests: wallet→identity→DPNS→tokens→DashPay   │
│  ─ ~30 min runtime                               │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│  Tier 2: Integration Tests (mocked network)      │
│  ─ UI + backend with stubbed Platform/Core       │
│  ─ Runs in CI on every PR                        │
│  ─ Tests: all screen flows with mock responses   │
│  ─ ~5 min runtime                                │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│  Tier 1: Unit/Rendering Tests (offline)          │
│  ─ Screen rendering, navigation, validation      │
│  ─ Runs in CI on every PR                        │
│  ─ Tests: all screens render, inputs validate    │
│  ─ ~30 sec runtime                               │
└─────────────────────────────────────────────────┘

Tier 1: Offline Rendering & Validation Tests

Target: 100+ tests covering every screen and input validation path

Every ScreenType variant should have at least:

  • A "renders without panic" test
  • Input validation tests (where applicable)
  • Error state rendering tests

Organized by feature area:

tests/kittest/
├── startup.rs                    # App boot
├── interactions.rs               # Welcome screen, navigation
├── wallets/
│   ├── wallets_screen.rs         # List, card display
│   ├── import_mnemonic.rs        # Import flow validation
│   ├── send_screen.rs            # Address validation, amount validation
│   └── asset_lock.rs             # Asset lock screen
├── identities/
│   ├── identities_screen.rs      # List, buttons
│   ├── add_identity.rs           # Creation form validation
│   ├── add_existing.rs           # Load by ID / DPNS name
│   ├── key_management.rs         # Add key validation, key info display
│   ├── top_up.rs                 # Top-up form validation
│   ├── withdrawal.rs             # Withdrawal form validation
│   └── transfer.rs               # Transfer form validation
├── dpns/
│   ├── contested_names.rs        # Active/past contests rendering
│   ├── owned_names.rs            # My usernames list
│   ├── register_name.rs          # Registration form validation
│   └── scheduled_votes.rs        # Vote list rendering
├── tokens/
│   ├── token_balances.rs         # Balance display
│   ├── token_search.rs           # Search input/results
│   ├── token_creator.rs          # Creation form validation
│   └── token_operations.rs       # Transfer/mint/burn form validation
├── contracts/
│   ├── contracts_screen.rs       # List, document query
│   ├── register_contract.rs      # Registration form
│   └── document_actions.rs       # CRUD form validation
├── dashpay/
│   ├── contacts.rs               # Contact list rendering
│   ├── profile.rs                # Profile screen
│   ├── payments.rs               # Payment flow validation
│   └── qr_code.rs                # QR generation/scanning
├── tools/
│   └── tools_screens.rs          # All tool screens render
└── network_chooser.rs            # Network selection

Tier 2: Integration Tests (Mocked Network)

Target: 40-60 tests covering all backend task flows

Requires a mock SDK layer:

// tests/mocks/mock_sdk.rs
pub struct MockSdk {
    pub identity_responses: Vec<Result<Identity, String>>,
    pub document_responses: Vec<Result<Document, String>>,
    pub broadcast_results: Vec<Result<StateTransitionProofResult, String>>,
    // ...
}

This layer intercepts Sdk calls at the boundary where AppContext dispatches backend tasks. Each test:

  1. Creates a harness with a MockSdk injected
  2. Navigates to a screen
  3. Fills in the form
  4. Triggers the action (button click or direct state mutation)
  5. Verifies the mock was called with expected parameters
  6. Feeds back a mock response
  7. Verifies the UI updates correctly (success message, navigation, error dialog)

Priority integration test flows:

  • Wallet send: construct tx → broadcast → verify balance update
  • Identity create: asset lock → register → verify identity appears
  • Identity top-up: select amount → broadcast → verify balance
  • Credit withdrawal: fill address → broadcast → verify
  • Credit transfer: fill recipient → broadcast → verify
  • DPNS register: fill name → broadcast → verify
  • Token transfer: fill amount/recipient → broadcast → verify
  • Token mint/burn: fill amount → broadcast → verify
  • Document CRUD: each operation type
  • DashPay contact request: send → accept → verify
  • Contract register/update: fill schema → broadcast → verify

Tier 3: Live E2E Tests (Testnet)

Target: Complete user journey covering the "golden path"

Extend the existing phased approach:

Phase 0:  Setup (wallet import + SPV sync)
Phase 1:  Wallet UI verification
Phase 2:  Wallet operations (send small amount to self)
Phase 3:  Platform reads (DPNS lookup, contract fetch)
Phase 4:  Identity creation (asset lock + register)
Phase 5:  Identity top-up
Phase 6:  DPNS name registration
Phase 7:  Token search + token operations (if tokens exist)
Phase 8:  Data contract registration
Phase 9:  Document operations (create, read, update, delete)
Phase 10: DashPay profile + contact request
Phase 11: Credit withdrawal (small amount)
Phase 12: Key management (add transfer key)
Phase 13: Teardown (cleanup all test artifacts)

Phased Roadmap

Phase 1: Expand Tier 1 (Weeks 1-2)

Goal: Every screen type has at least a rendering test

  1. Add rendering tests for all untested ScreenType variants
  2. Add input validation tests for all forms (identity creation, wallet send, token operations)
  3. Add error state tests (what does the UI show when an error occurs?)
  4. Refactor kittest helpers into tests/kittest/helpers/ module (shared harness creation, screen push/pop)
  5. Target: 80+ kittest tests, all passing in CI

Phase 2: Mock Infrastructure (Weeks 3-4)

Goal: Enable testing backend tasks without network

  1. Define a trait SdkProvider (or similar) that AppContext uses to get an SDK
  2. Create MockSdkProvider that returns canned responses
  3. Add test fixtures: sample identities, contracts, documents, tokens
  4. Build MockAppContext factory for integration tests
  5. First integration tests: identity load, contract fetch, DPNS lookup

Phase 3: Integration Tests (Weeks 5-8)

Goal: All critical user flows tested with mocked network

  1. Wallet send flow (mock tx broadcast)
  2. Identity creation flow (mock asset lock + register)
  3. DPNS registration flow
  4. Token operations (transfer, mint, burn)
  5. Document CRUD operations
  6. DashPay contact flow
  7. Error handling paths (network errors, validation errors, insufficient funds)
  8. Target: 40+ integration tests

Phase 4: CI & Live E2E (Weeks 9-10)

Goal: Full test pipeline in CI

  1. Set up GitHub Actions workflow for kittest (Tier 1) — runs on every PR
  2. Set up GitHub Actions workflow for integration tests (Tier 2) — runs on every PR
  3. Set up scheduled nightly workflow for live e2e (Tier 3) — requires funded testnet wallet as GitHub secret
  4. Unblock identity creation in e2e (SPV mempool support or alternative funding path)
  5. Extend e2e journey to cover identity → DPNS → tokens → documents → DashPay

Phase 5: Advanced Testing (Ongoing)

Goal: Robustness and regression prevention

  1. Visual regression: egui snapshot testing (render to image, compare against baseline)
  2. Persistence tests: create state → restart app → verify state loads correctly
  3. Concurrent operation tests: trigger multiple backend tasks, verify no race conditions
  4. Performance tests: measure UI responsiveness under load (many wallets, identities, contracts)
  5. Fuzz testing: random input to forms, verify no panics
  6. Accessibility audit: verify all interactive elements have AccessKit labels

Technical Recommendations

1. Mock SDK Layer Design

The biggest unlock is a mock layer. Recommended approach:

// In src/context/mod.rs or similar
pub trait PlatformClient: Send + Sync {
    async fn fetch_identity(&self, id: Identifier) -> Result<Option<Identity>, Error>;
    async fn broadcast(&self, st: StateTransition) -> Result<ProofResult, Error>;
    // ... other operations
}

// Production: wraps real Sdk
// Testing: returns canned responses from a VecDeque

This avoids modifying Sdk itself — just wrap the boundary.

2. Test Data Management

  • Create tests/fixtures/ with serialized test data (identities, contracts, documents)
  • Use deterministic test wallets (hardcoded mnemonic for offline tests, env var for live)
  • For live e2e: document the wallet funding requirements in tests/e2e/README.md

3. CI Integration

# .github/workflows/test.yml
jobs:
  kittest:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: cargo test --test kittest

  integration:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: cargo test --test integration

  e2e-nightly:
    runs-on: ubuntu-latest
    if: github.event_name == 'schedule'
    steps:
      - uses: actions/checkout@v4
      - run: cargo test --test e2e -- --ignored --nocapture
        env:
          E2E_WALLET_MNEMONIC: ${{ secrets.E2E_WALLET_MNEMONIC }}

4. Cargo Feature Gates

Keep expensive test infrastructure behind feature flags:

[features]
test-e2e = ["dep:egui_kittest"]
test-mock = ["test-e2e"]

5. Test Naming Convention

test_{screen}_{scenario}_{expected_outcome}
# Examples:
test_wallet_send_invalid_address_shows_error
test_identity_create_insufficient_funds_shows_error
test_dpns_register_name_too_short_validation_fails
test_token_transfer_success_updates_balance

Success Metrics

Metric Current Phase 1 Phase 3 Phase 5
Tier 1 tests 32 80+ 100+ 120+
Tier 2 tests 0 0 40+ 60+
Tier 3 phases 5 working 5 8+ 13
Screen coverage ~8/82 40/82 70/82 82/82
CI integration Tier 1 Tier 1+2 All tiers
Avg CI time N/A <1min <5min <6min

Generated from analysis of PR #598 (e2e branch) and the full DET codebase. See PR #598 for the current implementation.

/cc @PastaPastaPasta @QuantumExplorer

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions