From ba936608c624d2db549d59c58be78ed6a04e5959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Wed, 23 Sep 2026 19:23:13 +0200 Subject: [PATCH] test(ios): stop cold-host timing from failing the occupancy test testAbandonedTreeCaptureSkipsQuerySweepAndHonorsWarmupExemption runs first in the targeted XCTest lane and absorbed a cold host twice over: - A cold viewport read overran its 1 s cap before the tree capture the test targets, so the abandonment reason read "preparing tree snapshot" (4 CI failures at line 106). The test now pays that read uncapped before the timed section; the production cap is unchanged. - The blocking stub's own 20 s timeout could release the main thread before the test read the abandoned-work count, reading Optional(0) (2 CI failures at line 111). It is now a named leak guard far past the plan deadline, so only the test's release ends the block. --- ...RunnerTests+SnapshotCapturePlanOccupancyTests.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/UnitTests/RunnerTests+SnapshotCapturePlanOccupancyTests.swift b/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/UnitTests/RunnerTests+SnapshotCapturePlanOccupancyTests.swift index afb15147d2..c4c92d80c7 100644 --- a/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/UnitTests/RunnerTests+SnapshotCapturePlanOccupancyTests.swift +++ b/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/UnitTests/RunnerTests+SnapshotCapturePlanOccupancyTests.swift @@ -15,9 +15,13 @@ private enum RunnerBlockingSnapshotGate { /// read the AX server gave up on. The swap is process-wide while installed, which serial XCTest /// execution tolerates. private final class RunnerBlockingSnapshotStub: NSObject { + /// Far past the plan deadline, so only the test's own release ends the block; it only stops a + /// stuck test from holding the main thread. + private static let leakGuard: TimeInterval = 75 + @objc(snapshotWithError:) func snapshot() throws -> XCUIElementSnapshot { - _ = RunnerBlockingSnapshotGate.release.wait(timeout: .now() + 20) + _ = RunnerBlockingSnapshotGate.release.wait(timeout: .now() + Self.leakGuard) throw NSError( domain: "AgentDeviceRunner.tests", code: 1, @@ -50,6 +54,10 @@ extension RunnerTests { // resolution is slow, and it must not be the block the plan abandons. XCTAssertTrue(app.wait(for: .runningForeground, timeout: 10)) XCTAssertFalse(app.frame.isEmpty) + // The traversal context reads the viewport under a 1 s cap; a cold first read can overrun it + // and abandon the wrong block, so pay it here, uncapped. + _ = safeSnapshotViewport(app: app) + _ = capturedInterfaceOrientation(app: app) currentApp = app currentBundleId = "com.callstack.agentdevice.runner.tree-capture-test" snapshotXCTestPenaltyWarmupExemptionPending = true