Commit Graph

9 Commits

Author SHA1 Message Date
jay 419ad2fec1 feat(ios): T-2.10 background lifecycle — implementation (TDD step 2/3) 2026-05-17 02:53:53 +02:00
jay d627fe8e67 test(ios): XCUITest coverage for pairing/switcher/statusbar/settings/modbar/lock
Test target piRemoteUITests now covers 8 features across 7 files (~73s total).

UI tests:
  - SmokeUITests: app launches
  - PairingUITests: launchUnpaired→PairingFlow, deep-link auto-pair
  - StatusBarUITests: three icon buttons (Switcher/Settings/Unpair)
  - SessionSwitcherUITests: list, select, create-with-unique-name, cleanup
  - SettingsUITests: open sheet, Face-ID toggle flip, content checks
  - ModifierBarUITests: button presence, paste sheet
  - LockScreenUITests: lock overlay via --force-lock

App-source changes for testability (all dev/uitest-only):
  - AppState: --reset-state / --enable-faceid / --force-lock launch args
  - piRemoteApp: --pair-with-url launch arg auto-triggers .onOpenURL
  - MainTerminalView: --uitest mode replaces SwiftTerm with static
    placeholder and skips WS connection to keep app idle for XCUI
  - TerminalViewController.feed: defensive guard against nil terminalView

Accessibility identifiers added:
  - StatusBar buttons: accessibilityLabel + identifier
  - ModifierBar BarButton/RepeatingBarButton: accessibilityLabel + .isButton
  - SessionSwitcher '+' button

Tooling notes:
  - cliclick workaround replaced by simctl privacy grant pasteboard
  - Tests pre-fetch fresh pair-token from /pair-qr each run
  - SwiftUI Toggle inside Form needs coordinate tap (not .tap())

Bug fixes uncovered while writing tests:
  - Sidecar POST /sessions response was missing 'state' field
    (now returns { id, name, state, lastOutputAt } to match GET).
    iOS SessionItem decoder hardened to default state='idle' when missing.
2026-05-16 22:07:42 +02:00
jay 856f0ebf03 fix(ios): session switch — tear down and reconnect on activeSessionId change 2026-05-16 12:07:29 +02:00
jay df85c9e85b fix: remove public visibility from app-internal types; fix StatusBar arg order 2026-05-16 11:58:23 +02:00
jay 7be9e64a95 feat: merge T-2.6 SessionSwitcher + T-2.8 StatusBar + T-2.11 Face-ID
- SessionRegistry + SessionSwitcher + SessionRow (T-2.6)
- StatusBar component with pi-state indicator (T-2.8)
- FaceIDGate + SettingsView + LockView (T-2.11)
- Reconciled MainTerminalView: StatusBar wired with onSwitcher/onSettings/onUnpair,
  two .task modifiers, two .sheet modifiers (SessionSwitcher + SettingsView)
- AppState: appDidBackground/appWillForeground + isLocked (T-2.11)
- ContentView: scenePhase tracking + LockView overlay (T-2.11)
- Pairing.swift: fp param is optional pre-TLS (dev convenience)
2026-05-16 11:54:12 +02:00
jay d085444adc fix: clear terminal on connect, increase SIGWINCH settle time to 600ms 2026-05-16 04:00:02 +02:00
jay 994b450fe4 fix: fresh connect uses resize+snapshot instead of full history replay; wire onInput 2026-05-16 03:46:24 +02:00
jay 044a4920bb fix: terminal rendering — resize sync, TERM via sidecar, remove double-dot status 2026-05-16 03:30:31 +02:00
Johannes Merz 480a06981c feat: app wiring — ContentView + AppState + MainTerminalView
- AppState: loads credential from Keychain on launch, persists on pair
- ContentView: switches PairingFlowView ↔ MainTerminalView on credential
- PairingFlowView: onDismiss → onSuccess(credential) callback
- MainTerminalView: auto-resolves/creates session, connects WebSocket stream
  to TerminalViewController, ModifierBar wired to SessionConnection.send()
- piRemoteApp: AppState injected as environmentObject
2026-05-16 02:48:08 +02:00