mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 11:07:10 +00:00
v0.0.2
* ci: replace the archived buf-setup-action with buf-action
buf-setup-action is archived and runs on node20, which the runners now
warn about. buf-action is its supported replacement and runs on node24.
setup_only keeps it an install, since buf lint is its own step.
* ci: bump bun to 1.3.14
* ci: bump setup-chrome to v2.2.0
* ci: move to node 24 and drop the npm oidc workaround
node 22 is in maintenance and ships npm 10, which is why the publish job
had to install npm@latest over it. node 24 is the active lts and bundles
npm 11.17.0, above the 11.5.1 oidc floor, so the extra step goes.
* ci: pin the protoc plugins instead of installing @latest
these generate the committed stubs, so @latest makes codegen depend on
whatever released most recently. pinned to the versions proto/ records:
protoc-gen-go v1.36.11, protoc-gen-go-grpc v1.6.0.
* ci: run the ios leg on macos-26, pinned to a device and a runtime
macos-26 carries no iPhone 16 Pro at all, and on macos-15 that name spanned
iOS 18.5 through 26.2, so the leg could boot a two-major-old runtime. the
pair is now iPhone 17 Pro on iOS 26.2, resolved to a udid before boot, and
an image that drops it fails naming what it does carry.
iPhone 17 Pro is what examples/folio/justfile already defaulted to.
* ci: keep IOS_DEVICE a device name, not the resolved udid
the boot step exported the udid as IOS_DEVICE, and just ios spends that as
xcodebuild's -destination name=, which matches the display name and
rejected it: 'unable to find a device matching { name:6F69910C-... }'.
nothing downstream needed it. install, launch and terminate all address
booted, and sanderling resolves --ios-device against booted simulators
first, so the simulator this step boots is the one they all get.
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%