fix(apple-runner): a penalized snapshot plan falls back to the bounded XCTest probe - #3051
Conversation
There was a problem hiding this comment.
All reported issues were addressed across 2 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
|
Both red jobs look unrelated to this change, which only touches the snapshot capture plan. I can't rerun them (no admin rights on the repo):
Could a maintainer rerun the failed jobs? |
…, and names the budget The query sweep's grind is what penalizes the channel, so it stays off a deferred plan; the occupancy test's no-sweep contract holds again. A capture the bounded tree recovered reports 'budget', not 'deferred'.
|
The fix looks right in code, but I can't call it ready yet, because the only live run is on an earlier commit and not on 3719be2. Thanks for the focused change. This is a device-facing runner change, and the live results (1/3 fail before, 4/4 pass after) are for fc1a335. Head 3719be2 changed the plan (querySweep is gone from the fallback) and the verdict reason ( Not blocking, and you can take or leave these: a verdict should say CI is green, with 14 checks and none failing. The earlier Coverage and iOS smoke failures are on routes this Swift-only diff does not touch. I read the code at 3719be2 but did not run the Swift tests or the simulator. Before merge, we need the live simulator run on 3719be2 that reaches the Save Password sheet route and shows the tree recovery stamped recovered/tree/budget. |
…the budget on every path The sparse terminal path kept the seeded 'deferred' reason after the bounded tree ran. Both paths now stamp 'budget' once an XCTest tier ran behind private AX. A unit-test seam lets plan-runner tests make private AX read nothing, as it does behind an out-of-process sheet, and pins recovered/tree/budget and sparse/budget.
|
Thanks @thymikee. Live run on the current head Live run. The mobile benchmark's agentic Login Form was driven by the model ( The snapshot response the client received for that capture (its {"snapshotQuality":{"state":"recovered","backend":"tree","reason":"XCTest-backed snapshot tiers are running with a short recovery probe after recent slow accessibility work on this screen","reasonCode":"budget","timing":{"acquisitionMs":138.6,"presentationMs":0.34}},"nodes":19,"appBundleId":"dev.e2e.benchmark","savePasswordSheet":true}There was no For full transparency: most other runs in that throttled setup failed. They failed on text entry, app install and runner timeouts ( The terminal path now stamps Plan-runner tests. A unit-test-only
Both pass 3 of 3 on an iOS 26.5 simulator with Release note. The repo has no CHANGELOG file, so the user-visible change is in the PR body. While the penalty lasts, captures the bounded tree recovered carry |
There was a problem hiding this comment.
All reported issues were addressed across 4 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic | Re-trigger cubic
…covery test On a host too loaded for the 1 s slice the plan ends sparse; the verdict must still say budget, and the recovery assertions skip with the reason.
|
The code at 4b3971d looks right, and the new occupancy tests pin the plan well. It still needs a live run on this head before it is ready. Since 3719be2 the fallback plan changed again: the penalized plan now checks window occupancy before it picks the bounded XCTest probe (RunnerTests+SnapshotCapturePlan.swift). The live results in the thread are for fc1a335, so they do not cover this route. Could you run the loaded iOS simulator Login Form scenario on 4b3971d, or any capture while an out-of-process sheet covers a penalized bundle? The runner log should show SNAPSHOT_XCTEST_CHANNEL_PENALIZED, then SNAPSHOT_XCTEST_CHANNEL_DEFERRED, then PRIVATE_AX_SNAPSHOT_FAILED, then SNAPSHOT_RECOVERED backend=tree, and CI is green and there are no conflicts. |
|
Correction to my previous comment on 4b3971d: please ignore the request for a new live run. The live run already covers this head. This looks good. The earlier concern is fixed: the live run now covers the production code at 4b3971d (the changes since 82a3548 touch tests only), and all 14 checks are green with 0 failing. Not blocking: on a slow host the bounded tree can miss its slice and the plan ends sparse, so the recovery test in RunnerTests+SnapshotCapturePlanOccupancyTests.swift (https://github.com/callstack/agent-device/blob/4b3971d/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/UnitTests/RunnerTests+SnapshotCapturePlanOccupancyTests.swift#L398) skips before its recovered and tree assertions and only the budget reason is checked there. You can take or leave a longer slice for the tree in that test so the recovered branch always runs. I did not run the Swift unit tests or the simulator. The 3/3 pass and red-on-revert claims are yours, and I only checked them by reading the pre-change code. The live run was on a throttled host. You report that the text-entry and install failures in other runs are unrelated, and I can only confirm that none of them was a snapshot refusal on your word. No conflicts. |
Summary
Once the XCTest channel is penalized for a bundle, the regular snapshot plan on a simulator is private AX alone. When private AX cannot match the app, nothing else runs, and the capture comes back as the sparse fallback with a zero root. Presentation then refuses it:
regular iOS snapshot presentation requires a valid viewport. Private AX fails to match the app withCould not match active AX application for XCTest application, which is what happens while the out-of-process "Save Password?" sheet is over it. That repeats on every capture for the whole 120 s penalty.This was the top flake in the e2e mobile benchmark. Login Form failed on its first pass in about 20 of 45 CI runs: every snapshot after submit failed, the agent could not see the sheet's Not Now, and it gave up. Runner log:
The penalized plan now keeps the tree, on the bounded probe's 1 s slice that physical devices already use, behind the independent backend:
[privateAX, recursiveTree]. The query sweep stays off, since its grind is what penalizes the channel. A private-AX capture that succeeds returns first, so nothing changes on screens where it works. A capture the bounded tree recovered reportsbudgetinstead of the seededdeferred.Touched: 1 runner source file, 1 unit test file.
Release note
While the XCTest channel is penalized, a capture the bounded tree recovered carries
reasonCode: "budget", notdeferred, and shows the recovered warning on each such capture, as physical devices already do. So does a deferred plan that ends sparse after the tree ran.Validation
Tested commit
82a354807(live run,check:affected, xctest selection reaches all 344 methods);4b3971da7after it only lets the tree-recovery test skip when the bounded tree misses its slice.CHANNEL_PENALIZED, thenCHANNEL_DEFERRED, thenPRIVATE_AX_SNAPSHOT_FAILED(Could not match active AX application), thenSNAPSHOT_RECOVERED backend=tree. The snapshot came back asrecovered/tree/budgetwith the sheet in the tree, and there was no viewport refusal. Details in the thread.c6c67d5ed: 18 of 18 passed unthrottled.RunnerTests+SnapshotCapturePlanTestspins the penalized plan as[.privateAX, .recursiveTree]and the verdict-reason rule.