pj a7ed433706 fix(runner): budget the foreground gate in time, not in polls
Eight polls is not a budget. Each poll costs whatever the driver's idle wait
happens to take, so the same launch cleared the gate on one device and
exhausted it on another: across 80 runs of one app, the gate reported "app
never reached foreground" on 38 of 40 Android 14 runs and 0 of 40 Android 16
runs, and it was wrong every time. On API 34 settleForForeground returned in
~100ms, so the eight polls gave up 1.2s into a launch whose window drew at
~1.9s; on API 36 the same eight polls spanned 3s and covered it. The Android 14
runs then spent their first step on the launch animation instead of the app,
which is the one-step offset that came out of that campaign looking like a
platform difference.

The gate now polls for a fixed 15s at a 250ms floor, so its verdict is the same
duration on every device, and a verdict of "not in front" ends the run instead
of warning and carrying on: a run that never got its app on screen holds no
evidence about the app, and the trace records why at step 0.
2026-08-17 14:35:29 +05:30
2026-06-09 20:13:54 +05:30

sanderling

Autonomous property-based testing for mobile and web apps.

You write rules that must always hold about your app. sanderling explores the app on its own for minutes or hours, performing thousands of taps, swipes, and inputs, and records every step where a rule breaks. No scripted test paths. One TypeScript spec runs against Android, iOS, and web builds of the same app.

import { extract, always } from "@sanderling/spec";
import { defaultActions } from "@sanderling/spec/defaults";
import { noUncaughtExceptions } from "@sanderling/spec/defaults/properties";

const balance = extract("balance", s =>
  parseInt(s.ax.find({ testTag: "Balance" })?.text ?? "0", 10));

export const properties = {
  noUncaughtExceptions,
  balanceNeverNegative: always(() => balance.current >= 0),
};

export const actionsRoot = defaultActions;

Every run produces a trace: one JSON line and one screenshot per step. sanderling replay opens it in a web UI for stepping through actions, screenshots, property timelines, and violations.

Alpha. Android, iOS, and web (Chrome driver only). Full scope in the v0.1.0 roadmap.

Docs


sanderling

sanderling, a wading bird that probes the shoreline for bugs that lie beneath.

S
Description
No description provided
Readme Apache-2.0
51 MiB
0 Stars 1 Watchers 0 Forks
Languages
Go 74.6%
TypeScript 15.2%
Kotlin 5.5%
Shell 2.7%
Swift 1%
Other 0.9%