mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
7f5cf610bd707174a265589670927074ee4f9b09
The dedup key was the rendered description, which embeds the label, so two distinct controls sharing a visible label collapsed to one entry and the survivor carried the first one's action. The second control was not mislabelled, it was absent from the candidate list, so no policy could reach it. Two scrollable containers collapsed the same way, leaving the second unscrollable. The key is now the executable Action struct itself plus whether the model supplies the typed text, so a new Action field cannot silently fall out of it. Descriptions may now repeat; the numbering disambiguates and the echo guard is index-anchored, not description-anchored. This also makes the label source a pure observation-channel change. It was not one before: the label fed the dedup key, so the two arms of the labelling factor enumerated different-sized candidate lists, in both directions depending on the screen. Claude-Session: https://claude.ai/code/session_01A5KmftdEJ49A9z5mF5ESrX
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
- Introduction: what property-based testing is and how sanderling works
- Case study: Folio: sanderling finding a real bug in a mobile app
- Getting started: install the CLI and run it against Folio
- Spec language reference
- Examples: folio (KMP, Android/iOS/web), folio-web (React + Vite)
- Architecture for contributors
sanderling, a wading bird that probes the shoreline for bugs that lie beneath.
Languages
Go
74.6%
TypeScript
15.2%
Kotlin
5.5%
Shell
2.7%
Swift
1%
Other
0.9%