Releases: AlphaWaveSystems/flutter-probe
Releases · AlphaWaveSystems/flutter-probe
v0.9.9
Added
deliver signal "name" ["value"]— new ProbeScript step that resolves
a pendingawaitSignal(name)call in the Flutter app. Use to unblock any
OS-level interaction that isn't in the Flutter widget tree: push permission
dialogs, payment sheets, App Tracking Transparency, deep-link handlers, etc.
The value defaults to"true"when omitted.awaitSignal(String name)— new public function exported from
flutter_probe_agent. Returns aFuture<String>that resolves with the
value sent by the CLI. Generalises theawaitBiometricResult()pattern to
any named signal.DeliverSignal(String name, {String value})— new annotation step class
influtter_probe_annotation. Emitsdeliver signal "name"or
deliver signal "name" "value".- Parser:
TOKEN_DELIVER,TOKEN_SIGNAL,VerbDeliverSignal. - Agent:
probe.signalJSON-RPC method,ProbeMethods.signalconstant.
v0.9.8
Fixed
- Biometric no-match on iOS 26+ simulator —
notifyutilno-match notifications
no longer resolveLAContext.evaluatePolicyon iOS 26 / Xcode 26.5. The CLI now
sends aprobe.biometric_signal {result: bool}JSON-RPC command to the agent
after firing platform-level notifications. Test apps callawaitBiometricResult()
fromflutter_probe_agentinstead oflocal_auth.authenticate()in PROBE_AGENT
builds; the agent resolves a DartCompleterwith the CLI-delivered result, making
biometric no-match reliable on all iOS simulator versions.
Added
awaitBiometricResult()— new public function influtter_probe_agent.
Returns aFuture<bool>that resolves when the CLI delivers
probe.biometric_signal. Usage pattern in test apps:final ok = const bool.fromEnvironment('PROBE_AGENT') ? await awaitBiometricResult() : await localAuth.authenticate(...);
probe.biometric_signal— new JSON-RPC method. Sent by the CLI after
the platform-level biometric simulation commands so the result is always
delivered regardless of simulator version behavior.
v0.9.7
Added
- Biometric authentication testing — three new ProbeScript steps that drive Face ID / Touch ID / fingerprint flows on iOS Simulator and Android emulator without real hardware. Skipped on physical devices with a warning (same pattern as
set locationand other simulator-only ops).enroll biometric— marks the simulator/emulator as having an enrolled face or finger. iOS posts thecom.apple.BiometricKit.enrollmentChangedDarwin notification viaxcrun simctl spawn booted notifyutil. Android requires the fingerprint to be pre-enrolled in Settings.biometric match— simulates a successful capture, satisfying any pending biometric prompt. iOS posts*_Sim.faceCapture.matchAND*_Sim.fingerTouch.matchso the same step works on Face ID and Touch ID devices. Android runsadb -s <serial> emu finger touch 1.biometric no match— simulates a failed capture so the app's "authentication failed" path can be tested. iOS posts the.no-matchvariants; Android runsadb emu finger touch 9999(an unregistered id).- Annotation DSL: matching
EnrollBiometric(),BiometricMatch(),BiometricNoMatch()const Step classes influtter_probe_annotation, with a newbiometric_authgolden fixture influtter_probe_gen/test/fixtures/that round-trips through the Go parser via the cross-language integration test. - Parser: 2 new tokens (
TOKEN_BIOMETRIC,TOKEN_ENROLL), 3 newActionVerbconstants, 2 new parser dispatch cases. 3 new unit tests inparser_test.go. - Runner:
EnrollBiometric/BiometricMatch/BiometricNoMatchmethods onDeviceContext, dispatch cases inExecutor.runAction, and human-readable strings instepDescription. - Docs: new section in annotations.md and syntax.md on the website. Per-package CHANGELOGs updated.
v0.9.6
Fixed
flutter_probe_gen:Mockpath silently truncated. The emitter wrote the path unquoted (when the app calls GET /api/products), so the Go lexer split on/and the parser only recorded the first IDENT segment. Now emits the canonical quoted form. Caught by a newmock_and_callgolden + the existing cross-language integration test.flutter_probe_gen:Seesuffixes silently dropped. Whenstate,containing, andmatchingwere all set on a single assertion, only the last branch's text reached the output. Now composes all three suffixes additively:see "x" is enabled contains "y" matching "z". Caught by a newsee_statesgolden covering the matrix.
Added
flutter_probe_annotation:@ProbeCompositeTestannotation. The flagship multi-device composite testing feature finally has a DSL surface. Pair withDevice(alias, target: …),OnDevice(alias, steps: […])per-device groups, andSync(label)cross-device barriers. Emitter generates standardcomposite test/devices/<alias>:/syncblocks that the existing CLI runner picks up unchanged.flutter_probe_annotation:See.id/See.selectorfactories — assertions can now target byValueKeyor any rich selector (Ordinal, Below/Above/LeftOf/RightOf, InContainer, TypeSel) rather than only by literal visible text. Same factories onDontSee. The Go parser always supported this; the DSL just didn't expose it.flutter_probe_annotation:WaitUntil.idAppears/.idDisappears— emits unquoted#keyselector form (Go parser's WaitSelector branch), which is more reliable than text matching for stableValueKey-tagged widgets.flutter_probe_gen: 6 new golden fixtures.mock_and_call,see_states,composite_chat,wait_variants,examples_inline,kitchen_sink. The kitchen sink fixture exercises one of every step, selector kind, and control-flow construct. Every fixture round-trips throughinternal/parser/golden_integration_test.go. Total golden coverage went from 4 → 10 fixtures, builder tests from 5 → 11.
Changed
flutter_probe_annotation:PressandPinchare now@Deprecated. The Go parser has nopressorpinchcase, so emitted text fell through toparseRecipeCalland was misinterpreted. Marked deprecated until runtime support lands. UseGoBack()in place ofPress('back').flutter_probe_gen: emitter no longer coupled to enum declaration order._direction,_httpMethod, and theSeestate lookup now read the enum constant identifier (_namefield) instead of indexing a hard-coded array by.index. ReorderingDirection,HttpMethod, orSeeStateno longer silently corrupts emitted ProbeScript.
Docs
- New website page: Annotation-driven Tests — full reference for the annotation DSL with every step class, selector kind, and the new composite test syntax.
v0.9.5
Fixed
- Dart agent: iOS / Impeller screenshots —
take_screenshotpreviously calledOffsetLayer.toImage()on the root render view. On iOS with the Impeller renderer (Flutter's default on iOS 17+), that returns a GPU-backed texture whosetoByteData(ImageByteFormat.png)isnull, so capture silently produced nothing. The agent now primarily captures via the largest visibleRenderRepaintBoundaryin the widget tree (Impeller-supported); the legacyOffsetLayerpath is only used as a fallback when no boundary is found (Skia). Also awaitsWidgetsBinding.instance.endOfFramebefore capture so the latest frame is always in the image, and uses the actualView.devicePixelRatiorather than a hard-coded2.0.
v0.9.4
Added
- Claude Desktop Extension (
.mcpb) —probe-mcpis now packaged as a one-click Claude Desktop Extension. Users dragflutter-probe-<platform>-<arch>.mcpbonto Claude Desktop's Extensions settings, pick their Flutter project directory, and all 18 MCP tools are available. Nobrew install, no JSON config editing, no PATH setup. CI builds and attaches.mcpbartifacts for darwin-arm64, darwin-amd64, linux-amd64, and windows-amd64 to every release.- Manifest declares
server.type: "binary"and bundles the platform-specificprobe-mcpexecutable. user_config.projectRootis a directory picker surfaced as thePROBE_PROJECT_DIRenv var.probe-mcpreadsPROBE_PROJECT_DIRat startup andos.Chdirs into it sorun_tests,list_files,get_report, andinit_projectresolve paths against the user's Flutter project rather than Claude Desktop's working directory.scripts/build-mcpb.shproduces a bundle locally from any builtprobe-mcpbinary; usesnpx @anthropic-ai/mcpbfor schema validation and packing.- New
build-mcpbjob in.github/workflows/release.ymlruns afterbuild, downloads the per-platformprobe-mcpartifacts, packs them into.mcpbbundles, and attaches them to the GitHub release.
- Manifest declares
v0.9.3
Added
- Annotation-driven test generation — two new Dart packages,
flutter_probe_annotationandflutter_probe_gen, let you declare ProbeScript end-to-end tests as decorators on your Flutter screen classes. Abuild_runnerbuilder reads the annotations at build time and emits matching.probefiles intotests/generated/, picked up unchanged byprobe test.- Annotation API:
@ProbeSuite,@ProbeTest,@ProbeRecipeplus a fully type-checked step DSL covering all 31 ProbeScript action verbs (Tap, Type, See, Wait, Swipe, Scroll, Drag, Restart, Kill, ClearAppData, permissions, clipboard, location, screenshots, etc.), all 6 selector kinds (text, id, type, ordinal, positional, relational), hooks (beforeEach,afterEach,beforeAll,afterAll,onFailure), loops (Repeat), conditionals (If/otherwise), recipes with named parameters, data-drivenExamples, HTTP mocks (Mock), and inline Dart blocks (RunDart). - Builder: declares
lib/{{}}.dart→tests/generated/{{}}.probe. Cheap text pre-check skips files without annotations so it's safe to enable on a wholelib/tree. Each annotated class becomes a top-leveltest "..."block with optional tags and step body. - Cross-language validation: every Dart-emitted golden is parsed by the Go-side parser in CI (
internal/parser/golden_integration_test.go), so a malformed emitter line is caught immediately rather than at user runtime. - Docs: see
docs/wiki/Annotations.mdfor the full reference.
- Annotation API:
v0.9.2
Added
- Real-time step feedback — the runner now emits progress during test execution instead of staying silent until a step completes:
- Pre-step indicator (verbose mode): prints
→ step descriptionimmediately before each step runs. On a TTY the line is overwritten in place by the✓/✗result when the step finishes (clean single-line-per-step output). On non-TTY (CI) both lines are appended. - Progress ticker (all modes): a goroutine fires every 5 seconds while a step is still running and prints
⏱ step... (Ns). Stops immediately when the step completes — fast steps produce no ticker output. - Timeout warning (all modes): when a step has consumed ≥ 80% of its context deadline, a one-time
⚠ step still running — Ns elapsed, Ns timeoutwarning is printed. Gives time to react before the step times out. - Non-verbose TTY status line: even without
--verbose, a faint\r-overwriting status line shows the current step name while it runs and is cleared when it finishes. No output on non-TTY so CI logs stay clean.
- Pre-step indicator (verbose mode): prints
v0.9.1
Added
- MCP: 3 new tools —
init_project(scaffoldprobe.yaml+tests/),generate_report(HTML from JSON results),record(record interactions →.probefile with configurable timeout) - MCP: Android emulator shutdown —
shutdown_devicenow acceptsserialfor Android emulators in addition toudidfor iOS simulators - MCP: composite test support —
run_testsexposes acomposite_devicesparameter ("A=host:port/token B=udid") that maps directly to--composite-deviceflags;write_testdescription documents the fullcomposite testsyntax - MCP:
run_testsflags documented — tool description now enumerates key flags (--timeout,--format,--parallel,--shard,--host/--token,--disable-animations,--video,--stream) - MCP:
write_testvalidates before writing — content is parsed in-process before the file is created; syntax errors are returned immediately without touching the filesystem
Fixed
- MCP:
get_reportused alphabetical order instead of modification time —get_reportandgenerate_reportnow find the most recently modified JSON file inreports/, not the lexicographically last one
v0.9.0
Added
- Composite tests — a new
composite testkeyword lets a single.probefile orchestrate multiple devices simultaneously. Declare device aliases (A,B,C, …), write per-device step blocks (A: tap "Login"), and usesync "label"as a cross-device barrier that all goroutines must reach before any proceeds. Supports N devices. Files with composite tests coexist with regulartestblocks. Configure devices via--composite-device A=host:port/token(WiFi),--composite-device B=<udid>(iOS simulator), or--composite-device C=emulator-5554(Android). Probe.yaml can also setcomposite.devicesfor project-level defaults. If composite devices are not configured at runtime, composite tests are reported as SKIPPED. - Failure semantics: if one device fails mid-test, the shared context is cancelled immediately; all other devices are unblocked from any
syncbarrier they are waiting at and their next step returns a cancelled error. The final result marks the root cause device as FAIL and secondary devices as CANCELLED.