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
This commit is contained in:
pj authored and GitHub committed 2026-04-22 20:35:34 +07:00
1 parent 46abb28ed6
commit eed99e58aa
32 files changed
+870 -745

No files matched your search

+70
View File
@@ -0,0 +1,70 @@
import type {
AccessibilityElement,
Action,
ActionGenerator,
InputTextAction,
Key,
Point,
PressKeyAction,
Sampler,
SwipeAction,
TapAction,
WaitAction,
WeightedEntry,
} from "./types.ts";
export function actions(generator: () => Action[]): ActionGenerator {
return globalThis.__sanderling__.actions(generator);
}
export function weighted(...entries: WeightedEntry[]): ActionGenerator {
return globalThis.__sanderling__.weighted(...entries);
}
export function from<T>(items: readonly T[]): Sampler<T> {
return globalThis.__sanderling__.from(items);
}
export function Tap(parameters: { on: string | AccessibilityElement }): TapAction {
return globalThis.__sanderling__.tap(parameters);
}
export function InputText(parameters: {
into: string | AccessibilityElement;
text: string;
}): InputTextAction {
return globalThis.__sanderling__.inputText(parameters);
}
export function Swipe(parameters: {
from: Point | AccessibilityElement;
to: Point | AccessibilityElement;
durationMillis?: number;
}): SwipeAction {
return globalThis.__sanderling__.swipe(parameters);
}
export function PressKey(parameters: { key: Key }): PressKeyAction {
return globalThis.__sanderling__.pressKey(parameters);
}
export function Wait(parameters: { durationMillis: number }): WaitAction {
return globalThis.__sanderling__.wait(parameters);
}
function builtinGenerator(name: "taps" | "swipes" | "waitOnce" | "pressKeys"): ActionGenerator {
return new Proxy({} as ActionGenerator, {
get(_target, property) {
const runtime = globalThis.__sanderling__[name] as unknown as Record<
string | symbol,
unknown
>;
return runtime[property];
},
});
}
export const taps: ActionGenerator = builtinGenerator("taps");
export const swipes: ActionGenerator = builtinGenerator("swipes");
export const waitOnce: ActionGenerator = builtinGenerator("waitOnce");
export const pressKey: ActionGenerator = builtinGenerator("pressKeys");