Commit Graph
176 Commits
Author SHA1 Message Date
pj 0fae65d4f2 ci(replay-ui): point bun cache key at replay-ui/bun.lock 2026-06-06 13:07:43 +05:30
pj 09bcb9ea82 ci(replay-ui): run bun test via make web-test target 2026-06-06 13:07:43 +05:30
pj 5d1d083f57 test(replay-ui): add bun test script 2026-06-06 13:07:43 +05:30
pj c62f30621a test(cmd): pin pipeline error to bundle resolution on web platform 2026-06-06 13:07:10 +05:30
pj f821e9a306 test(cmd): drop flaky TestRun_Doctor that launched real Chromium 2026-06-06 13:07:10 +05:30
pj a6f39e3441 test(cmd): unit-test buildBrowseURL deep-link vs root 2026-06-06 13:07:10 +05:30
pj adcd10cd52 test(cmd): table-test hier-check parse and FindAll on fixture 2026-06-06 13:07:10 +05:30
pj 3197e64562 test(cmd): smoke-test bundle-check resolves spec aliases 2026-06-06 13:07:10 +05:30
pj da9455cd5a fix(cmd): point bundle-check aliases at pkg/spec/src 2026-06-06 13:07:10 +05:30
pj 3a8eea78fd test(testrun): exact-output tests for progressHandler line format 2026-06-06 13:06:40 +05:30
pj 483f3ceeab test(testrun): table-test resolveRuntimeSibling search edges 2026-06-06 13:06:40 +05:30
pj 2e06555714 test(testrun): cover prepareBundleInputs aliases and missing-runtime error 2026-06-06 13:06:40 +05:30
pj 5ea68869ae refactor(testrun): extract prepareBundleInputs from Execute 2026-06-06 13:06:40 +05:30
pj 2e700f34fb test(bundler): cover properties-only spec registration 2026-06-06 13:06:40 +05:30
pj a74fa46221 test(sidecarassets): assert reuse via sentinel bytes not mtime 2026-06-06 13:06:10 +05:30
pj c576462b7a test(sidecarassets): cover placeholder build path 2026-06-06 13:06:10 +05:30
pj 6a575665e1 test(ios): table-test simctl parsers and EnsureSimulator seams 2026-06-06 13:06:10 +05:30
pj 2de7b97894 refactor(ios): add command-runner seams for EnsureSimulator 2026-06-06 13:06:10 +05:30
pj e802338be2 refactor(ios): extract pure simctl JSON parsers 2026-06-06 13:06:10 +05:30
pj e359f4c606 fix(chrome): route hierarchy/screenshot/waitidle/metrics through runCtx 2026-06-06 13:05:34 +05:30
pj ee0716a2bf fix(chrome): route action methods through runCtx so caller cancellation aborts CDP 2026-06-06 13:05:34 +05:30
pj 6f69816ca5 test(sidecar): assert gRPC error status surfaces from action RPC 2026-06-06 13:05:34 +05:30
pj f3671f15ad test(sidecar): cover DoubleTapSelector composition and mid-gesture cancel 2026-06-06 13:05:34 +05:30
pj a80a5d0671 test(sidecar): cover swipe/longpress/doubletap/erase/presskey/metrics/logs translations 2026-06-06 13:05:34 +05:30
pj 7fdf5c6967 fix(sidecar): synchronize health fixture writes and exercise healthError 2026-06-06 13:05:34 +05:30
pj a0ee66db75 test(replay): Run coalesces creates, ignores write/chmod, closes subs on cancel 2026-06-06 13:04:55 +05:30
pj cadf908a8f test(replay): SSE client receives runs.changed after a broadcast 2026-06-06 13:04:55 +05:30
pj f4761a327c test(replay): corrupt meta/trace dirs return 500 with error body 2026-06-06 13:04:55 +05:30
pj a5e861ed5e test(replay): violation marker falls back to detection step when attributed missing 2026-06-06 13:04:55 +05:30
pj 54eb958578 test(replay): cache reuses on equal mtime, reparses after append 2026-06-06 13:04:55 +05:30
pj b0c714ff5d test(replay): drop unfailable assets and devproxy assertions 2026-06-06 13:04:55 +05:30
pj e21cd44089 test(trace): guard writer mutex via WriteStep/Close race on w.file 2026-06-06 13:04:15 +05:30
pj db3857a913 test(hierarchy): cover invalid-JSON and malformed-bounds parser paths 2026-06-06 13:04:15 +05:30
pj 925b0617ef test(trace): document ViolationsAreGreppable grep contract and lock-free WriteScreenshot 2026-06-06 13:04:15 +05:30
pj e3e810d8db test(trace): round-trip witnesses/changes/metrics/exceptions, pin step-0 witness 2026-06-06 13:04:15 +05:30
pj 3e9276bdc9 test(trace): set Hierarchy in round-trip and lock lossy Tree contract
Also add a -race concurrent WriteStep test that asserts N well-formed JSONL lines, catching torn lines if the writer mutex is dropped.
2026-06-06 13:04:15 +05:30
pj 042f5c7e7c test(runner): cover RenderSummary unsupported-verbs surfacing branch 2026-06-06 13:03:04 +05:30
pj a41998efda test(runner): assert PressKey/Wait trace encoding records kind-specific fields 2026-06-06 13:03:04 +05:30
pj dad565dcb3 test(runner): pin isWDADrop to sidecar reconnect-failed message origin 2026-06-06 13:03:04 +05:30
pj d5314531fd test(verifier): un-skip ax-find round trip with a committed tree fixture 2026-06-06 13:02:38 +05:30
pj 58afecd7b7 test(verifier): widen weighted-selection assertion to a 5x skew margin 2026-06-06 13:02:38 +05:30
pj 445a33daff test(verifier): assert WithPlatform(ios) reaches the picker host and key pool 2026-06-06 13:02:38 +05:30
pj 02c82c108d test(verifier): table-test DecodeAction kinds and lastAction field exposure 2026-06-06 13:02:38 +05:30
pj 237ce6975a test(verifier): cover LTL combinator verdict transitions and within unit panic 2026-06-06 13:02:38 +05:30
pj 94b6de8c53 test(ltl): marshal bounded Always steps/duration/deadline 2026-06-06 13:02:08 +05:30
pj 8ae9c2dafe test(ltl): pin reduce over pending inner for bound, Or, Not 2026-06-06 13:02:08 +05:30
pj f6d5d1f34f test(ltl): table-test finalize Kleene connective combinations 2026-06-06 13:02:08 +05:30
pj d554fe0d90 test(ltl): pin exact multi-obligation residual AST 2026-06-06 13:02:08 +05:30
pj 4566a91ea6 chore(test): start test-suite refactor sweep 2026-06-06 12:37:40 +05:30
pj 410602d2e1 Fix action-system audit findings (#60)
* fix(replay-ui): size overlay viewBox from hierarchy root bounds

Tap points are recorded in the hierarchy's coordinate space (iOS points,
Android pixels, web CSS px) while screenshots are device pixels, so the
overlay rendered at 1/3 position on iOS 3x screens. Derive the viewBox
from the root element bounds; natural image size stays the fallback.

* fix(runner): derive trace tap point from resolveCoordinates

stampSelectorTarget preferred possibly-stale action X/Y while dispatch
preferred the fresh tree-resolved center, so the trace could record a
different point than the one tapped. Both now share resolveCoordinates.

* fix(runner): settle after InputText focus tap before key events

The focus tap raises the keyboard; with no settle the keyboard
animation races the erase/type key events on iOS, landing them in the
wrong field or dropping them. Wait for idle after a successful focus
tap, bounded by the run's idle timeout.

* fix(driver): skip pre-erase for replace-on-input drivers

The web driver's InputText already replaces content via select-all, so
the runner's unconditional EraseText was a redundant round-trip on
every InputText. A new optional TextReplacer capability lets a driver
assert replace semantics; the runner skips the erase when asserted.

* fix(hierarchy): rank spatial-fallback matches by specificity

The bounds-containment fallback returned the first pre-order match, so
a screen-sized container could win over the intended small element.
Matches are now ordered smallest-area first; equal-area matches keep
pre-order, preserving the iOS-flat equal-bounds sibling pattern.

* fix(runner): treat an unchanging transitional tree as settled

A UI persistently showing two route-level Screen ids (overlay, both
route ids alive at rest) burned the full retry budget every step and
skipped the verifier forever. A tree byte-identical to the previous
attempt now breaks the retry loop as settled; genuine cross-fades
differ between attempts and keep the retry/skip behavior.

* fix(replay-ui): skip synthetic zero-bounds root in deviceSpaceOf

The iOS hierarchy prepends a zero-bounds node before the real root
window, so elements[0] returned undefined and the overlay fell back to
the screenshot's pixel size. Take the first element with positive
extent instead; pre-order puts the root window before any content.
Verified against a real iOS trace in the replay UI.

* fix(sidecar): never replay non-idempotent actions after reconnect

A dropped connection mid-action (e.g. a read timeout while the device
is still typing) re-ran the whole block after reconnecting, typing the
text twice and double-firing taps. Non-idempotent actions now reconnect
for the next RPC's benefit but surface UNAVAILABLE, which the runner
already treats as transient; idempotent reads keep the replay.

* fix(sidecar): land the second double-tap sequentially on gesture collision

The overlapped second tap can hit the XCTest runner while the first
gesture is still executing ('only one gesture can be performed at a
time'), failing the step. The second tap now waits the first out and
retries once, keeping the tight gap on the happy path.

* fix(sidecar): map non-Exception throwables to INTERNAL status

The vendored iOS client throws failures that do not extend Exception;
runRpc missed them, killing the RPC as a channel-level Unknown the
runner cannot classify. Catch Throwable instead.

* feat(sidecar): close the driver and app under test on shutdown

* test(sidecar): cover service shutdown paths

* fix(testrun): stop the sidecar with SIGTERM before killing

* fix(sidecar): reap orphaned XCTest runner sessions at iOS init

* fix(sidecar): probe channel liveness before restarting the XCTest runner

* test(sidecar): cover WdaRecovery restart and retry policy

* fix(sidecar): absorb first-leg double-tap collision sequentially

* fix(runner): scope WDA-drop detection and cap consecutive transient failures

* chore(sidecar): silence vendored loggers on expected failure paths

* fix(runner): absorb one-off apply errors; only an unbroken streak aborts

* fix(folio): install the current build before the Android fuzz run

* chore(sidecar): silence absorbed view-hierarchy poll noise in Android runs

The driver logs an ERROR for every on-device view-hierarchy fetch that the
device-side server cancels or times out while the UI animates. The stability
poll fetches the hierarchy on a sub-second cadence and swallows those throws
to keep polling, so each line is advisory with no effect on the run. Real
failures still reach the runner as gRPC status errors, so nothing is lost.
2026-06-06 12:21:11 +05:30