Commit Graph
5 Commits
Author SHA1 Message Date
pj 776becdf4b Remove in-app SDK (#43)
* chore: delete internal/agent package

* chore(build): remove sdk-android from gradle settings

* chore(makefile): remove sdk-android targets

* chore(ci): remove release-android job from release workflow

* chore(folio): remove sdk-android dependency

* chore(folio): remove SDK initialization from FolioApplication

* chore(folio): delete snapshot extractor files

* feat(folio): add balance to account card content description

* feat(folio): add hierarchy content descriptions to LedgerScreen

* refactor(folio): rewrite spec.ts to use ax extractors

* docs: remove in-app SDK from README

* feat(folio): add focused_input indicator to App

* docs: remove in-app SDK from index

* refactor(runner): remove agent SDK connection and snapshot step

* test(runner): update tests for SDK removal

* docs: remove Android SDK section from getting-started

* refactor(testrun): remove agent SDK connection setup

* docs: remove snapshots from writing-specs

* docs: remove in-app SDK from architecture doc

* docs(folio): update README for SDK removal

* docs: update per-step cycle diagram in architecture doc

* fix(folio): detect screens from unique element presence, not id: selectors

testTag() in Compose is not exposed as resource-id without testTagsAsResourceId.
Use desc: selectors for elements unique to each screen instead of id: path queries.

* feat(folio): add screen root contentDescription for scoped ax selection

Each screen root gets semantics { contentDescription = "ScreenName" } so
sanderling specs can scope element lookups through the screen: desc:LoginScreen > desc:login_submit.

* fix(folio): scope all ax selectors through screen root nodes

Use desc:ScreenName > desc:element path queries so every selector is
rooted at the screen level. focusedInput stays unscoped since it lives
in the app root, outside any screen.

* fix(folio): guard newAccountBalanceIsZero against navigation false positives

Scoped selectors return [] when not on HomeScreen so accounts vanish and
reappear as apparently-new on each visit. Skip the check when prev was empty.

* chore(folio): link @sanderling/spec to local pkg/spec for IDE type checking

* feat(spec): add desc, class, clickable, enabled, checked, focused, selected to AccessibilityElement

Runtime fields set by the verifier were missing from the TypeScript type,
causing linting errors on el.desc and related accesses in specs.

* chore(folio): switch to bun, add tsconfig.json for IDE type checking

- Remove package-lock.json, add bun.lock
- Add tsconfig.json so VSCode resolves @sanderling/spec types
- Fix parseAccount/parseLedgerRow to accept string | undefined
2026-04-25 20:04:29 +07:00
pj 97154cf580 feat(ios): launch via XCTest with env vars for hierarchy/tap access (#39)
* feat(proto): add env map to LaunchRequest

* feat(driver): add env param to Launch interface and all implementations

* feat(sidecar): add IosDriverBackend using Maestro IOSDriver + env pass-through

* feat(testrun): launch iOS app via XCTest with env vars instead of simctl

* fix(ios): replace LaunchApp with BootedUDID; simctl launch moved to XCTest path

* test(cli): add tests for ios platform flag and ios-device flag parsing

* fix(sdk-ios): check semaphore wait result; resolve port from args and env; register extractors before start
2026-04-23 17:35:31 +07:00
pj 007dcddd69 feat(ios): iOS e2e support — Kotlin Native SDK + simulator driver + test-ios (#38)
* feat(ios): add simulator management package

* feat(testrun): add iOS platform path (simctl launch + direct TCP)

* feat(cli): add --ios-device flag and IosDevice option

* feat(sdk-ios): add Kotlin Native iOS SDK (TCP agent + POSIX socket + dispatch pauser)

* feat(folio-ios): wire SanderlingIos.start() in MainViewController

* feat(folio-ios): add test-ios justfile recipe

* fix(sdk-ios): remove unavailable C macros; manual byte swap + no-cast warnings

* fix(testrun): simctl-first launch order for iOS; Maestro init after SDK connects
2026-04-23 17:29:53 +07:00
pj af7b7e27b0 feat(folio-web): web sample app + CDP spec tests (#36)
* fix(runner): allow nil connection for web platform

* fix(testrun): skip SDK handshake for web platform

* feat(folio-web): add React/Vite web sample app

* feat(folio-web): add sanderling spec

* fix(chrome): use InsertText for multi-char text input

* feat(hierarchy): add Screen field populated from sanderling-screen attr

* fix(chrome): auto-detect viewport from CSS vars, fix InputText accumulation, expose route as screen

* fix(runner): fall back to hierarchy root screen when snapshot screen is empty

* fix(folio-web): broaden loggedIn extractor to all authenticated pages
2026-04-22 23:59:30 +07:00
pj eed99e58aa refactor: code organization cleanup (#35)
* chore: fix gitignore + decisions doc after web->inspect-ui rename

Update web/ references to inspect-ui/ in .gitignore and Makefile. Add
decisions.md tracking architectural decisions from code-org discussion.

* refactor: rename pkg/spec-api to pkg/spec

Aligns the directory name with the npm package name @sanderling/spec.
Updates Makefile, package.json directory field, and resolveSpecAPIPath.

* refactor(verifier): split bindings.go into types.go + bindings.go

Move shared public types (Action, ActionKind, LogEntry, Exception) to
types.go. bindings.go retains internal JS runtime wiring only.

* refactor(inspect): split runs.go into runs.go, runs_cache.go, runs_decode.go

runs.go: types (RunSummary, StepSummary, RunDetail, Run) and Scan.
runs_cache.go: Cache type, Open/Step/Detail methods, parseRun, scanSteps.
runs_decode.go: readMeta, tallyTrace, decodeStepSummary, validRunID.

* refactor: move android_env.go to internal/android/

Extracts Android device/AVD/adb logic into internal/android package.
Exports EnsureDevice, AdbReverse, AdbReverseRemove, EnvWithAndroidPlatformTools, AdbBinary.
Moves tests to internal/android/android_test.go. cmd/sanderling becomes a thin caller.

* refactor: extract test pipeline to internal/testrun/

runTestPipeline logic moves to testrun.Execute. buildDriver, resolveSpecAPIPath,
pickFreePort, and the progress logger move to internal/testrun/. cmd/sanderling/test_run.go
becomes a thin adapter. Tests follow their code.

* ci: update workflow paths after pkg/spec-api -> pkg/spec rename
2026-04-22 20:35:34 +07:00