Files
sanderling/examples/folio/README.md
T
pj 3288364424 refactor(folio): delete :composeApp and retarget tooling
Removes the old monolithic module now that :core / :app:shared /
:app:ui-components / :app:androidApp own the source. Updates:

- justfile install/uninstall recipes -> :app:androidApp
- iosApp/project.yml framework path -> ../app/shared/...,
  baseName Shared (was ComposeApp); pre-build script invokes
  :app:shared:linkDebugFrameworkIosSimulatorArm64
- iosApp/iosApp/iOSApp.swift -> import Shared
- README -> mentions SQLDelight unification, drops the
  data-carrier contentDescription notes (now stale), no Layout
  section per repo convention
2026-04-26 14:32:01 +07:00

83 lines
2.2 KiB
Markdown

# Folio
A minimal Kotlin Multiplatform personal-ledger app: login with demo
credentials, create accounts, add credits and debits. Shared UI across
Android and iOS via Compose Multiplatform. Doubles as the example
sanderling runs its property-based specs against.
## Stack
- Kotlin Multiplatform + Compose Multiplatform (shared UI)
- SQLDelight for the data layer (unified across platforms)
- kotlinx.coroutines for state flows
- kotlinx.serialization for `@Serializable` route types
## Prerequisites
- `just`
- JDK 17
- Android SDK (auto-discovered under `$ANDROID_HOME`, `~/Library/Android/sdk`,
or the Homebrew cask)
- Xcode 16+ and `xcodegen` (`brew install xcodegen`) for iOS
## Android
```sh
just install # build + install on a booted emulator / device
just uninstall
just clean
```
## iOS
```sh
just ios # default device: iPhone 17 Pro
IOS_DEVICE="iPhone 15" just ios # pick a different simulator
```
`just ios` regenerates `iosApp/iosApp.xcodeproj` from `iosApp/project.yml`,
builds the KMP framework (`Shared.framework` from `:app:shared`), links it
into the SwiftUI host, installs, and launches.
## Demo credentials
```
email: [email protected]
password: ledger123
```
## Run a sanderling test (Android)
```sh
just test
```
If no device is connected, sanderling boots the single AVD it finds. With multiple
AVDs, pick one:
```sh
AVD=Pixel_7 just test
```
Persistent settings can live in `.env` alongside the justfile:
```
AVD=Pixel_7
DURATION=5m
```
Traces land in `./sanderling/runs/<timestamp>/`.
## How it connects to sanderling
- Each screen sets a stable Compose `testTag` (`HomeScreen`, `AccountCard`,
`LedgerRow`, `TxnAmount`, ...). The Sanderling SDK resolves `testTag` to
`resource-id` on Android and `accessibilityIdentifier` on iOS.
- Identity for list items is the visible text content (account name; txn
note + amount). No synthetic IDs encoded in semantics.
- `contentDescription` is reserved for real accessibility labels, never as a
data carrier.
- `sanderling/spec.ts` imports `@sanderling/spec`, reads state via `s.ax.*`,
asserts properties, and weights the actions the fuzzer picks from.
- `just test` invokes `sanderling test` against the installed APK.