Skip to content

Commit d6e61ba

Browse files
committed
refactor(ios): extract snapshot presenter
1 parent d4623a1 commit d6e61ba

36 files changed

Lines changed: 1268 additions & 897 deletions

File tree

‎apple/runner/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
);
114114
name = AgentDeviceRunnerUITests;
115115
packageProductDependencies = (
116+
A1B2C3D4E5F60718293A4B5D /* AgentDeviceSnapshotPresentation */,
116117
);
117118
productName = AgentDeviceRunnerUITests;
118119
productReference = 20EA2EDD2F2CFC7C001CF0EF /* AgentDeviceRunnerUITests.xctest */;
@@ -146,6 +147,9 @@
146147
);
147148
mainGroup = 20EA2EBD2F2CFC7B001CF0EF;
148149
minimizedProjectReferenceProxies = 1;
150+
packageReferences = (
151+
A1B2C3D4E5F60718293A4B5C /* XCLocalSwiftPackageReference "snapshot-presentation" */,
152+
);
149153
preferredProjectObjectVersion = 77;
150154
productRefGroup = 20EA2EC72F2CFC7B001CF0EF /* Products */;
151155
projectDirPath = "";
@@ -157,6 +161,21 @@
157161
};
158162
/* End PBXProject section */
159163

164+
/* Begin XCLocalSwiftPackageReference section */
165+
A1B2C3D4E5F60718293A4B5C /* XCLocalSwiftPackageReference "snapshot-presentation" */ = {
166+
isa = XCLocalSwiftPackageReference;
167+
relativePath = ../../snapshot-presentation;
168+
};
169+
/* End XCLocalSwiftPackageReference section */
170+
171+
/* Begin XCSwiftPackageProductDependency section */
172+
A1B2C3D4E5F60718293A4B5D /* AgentDeviceSnapshotPresentation */ = {
173+
isa = XCSwiftPackageProductDependency;
174+
package = A1B2C3D4E5F60718293A4B5C /* XCLocalSwiftPackageReference "snapshot-presentation" */;
175+
productName = AgentDeviceSnapshotPresentation;
176+
};
177+
/* End XCSwiftPackageProductDependency section */
178+
160179
/* Begin PBXResourcesBuildPhase section */
161180
20EA2EC42F2CFC7B001CF0EF /* Resources */ = {
162181
isa = PBXResourcesBuildPhase;

‎apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSnapshotScopePolicy.swift‎

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,5 @@
11
import Foundation
2-
3-
enum SnapshotScopeSelection: Equatable {
4-
case unscoped
5-
case matched(Int)
6-
case missing
7-
}
8-
9-
/// Cross-runtime snapshot scope specification.
10-
///
11-
/// A non-empty scope selects the first node in presentation preorder whose label, identifier, or
12-
/// value contains the trimmed query case-insensitively and whose subtree contributes to the
13-
/// requested projection. Missing matches publish an empty projection.
14-
enum SnapshotScopePolicy {
15-
static func select<Node>(
16-
fromPreorder nodes: [Node],
17-
scope: String?,
18-
depth: (Node) -> Int,
19-
semanticValues: (Node) -> [String?],
20-
subtreeContributes: (Range<Int>) -> Bool
21-
) -> SnapshotScopeSelection {
22-
guard let query = normalized(scope) else { return .unscoped }
23-
for (index, node) in nodes.enumerated() {
24-
guard semanticValues(node).contains(where: { value in
25-
value?.lowercased().contains(query) == true
26-
}) else { continue }
27-
let range = subtreeRange(from: index, in: nodes, depth: depth)
28-
if subtreeContributes(range) {
29-
return .matched(index)
30-
}
31-
}
32-
return .missing
33-
}
34-
35-
static func isActive(_ scope: String?) -> Bool {
36-
normalized(scope) != nil
37-
}
38-
39-
private static func normalized(_ scope: String?) -> String? {
40-
guard let query = scope?.trimmingCharacters(in: .whitespacesAndNewlines), !query.isEmpty else {
41-
return nil
42-
}
43-
return query.lowercased()
44-
}
45-
46-
static func subtreeRange<Node>(
47-
from start: Int,
48-
in nodes: [Node],
49-
depth: (Node) -> Int
50-
) -> Range<Int> {
51-
let rootDepth = depth(nodes[start])
52-
var end = start + 1
53-
while end < nodes.count, depth(nodes[end]) > rootDepth {
54-
end += 1
55-
}
56-
return start..<end
57-
}
58-
}
2+
import AgentDeviceSnapshotPresentation
593

604
#if AGENT_DEVICE_RUNNER_UNIT_TESTS
615
private struct SnapshotScopeFixture: Decodable {

‎apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import XCTest
2+
import AgentDeviceSnapshotPresentation
23

34
extension RunnerTests {
45
private static let privateAXSnapshotMaxNodes = 5_000

‎apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import XCTest
2+
import AgentDeviceSnapshotPresentation
23

34
#if AGENT_DEVICE_RUNNER_UNIT_TESTS && os(iOS)
45
import ObjectiveC.runtime

‎apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Foundation
22
import XCTest
3+
import AgentDeviceSnapshotPresentation
34

45
enum RunnerCommandLifecycleState: String {
56
case notAccepted

‎apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import XCTest
2+
import AgentDeviceSnapshotPresentation
23

34
#if os(macOS)
45
import CoreGraphics

‎apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift‎

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import AgentDeviceSnapshotPresentation
2+
13
// MARK: - Wire Models
24

35
enum CommandType: String, Codable {
@@ -277,24 +279,3 @@ struct ErrorPayload: Codable {
277279
let message: String
278280
var hint: String?
279281
}
280-
281-
struct SnapshotRect: Codable {
282-
let x: Double
283-
let y: Double
284-
let width: Double
285-
let height: Double
286-
}
287-
288-
struct PresentationOptions {
289-
let interactiveOnly: Bool
290-
let depth: Int?
291-
let scope: String?
292-
let raw: Bool
293-
/// Internal daemon ask: capture with this backend first regardless of channel
294-
/// health ("private-ax"). Same-backend evidence probes (tap-outcome
295-
/// corroboration) must be captured the way their baseline was.
296-
var preferredBackend: String? = nil
297-
/// Read UIAccessibilityCustomActions for merged leaves. Opt-in: each element
298-
/// costs its own AX round trip (see RunnerAXSnapshotBridge).
299-
var customActions: Bool = false
300-
}

‎apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import XCTest
2+
import AgentDeviceSnapshotPresentation
23

34
/// Reported facts for one private-AX element, read once so every consumer describes a node the
45
/// same way.

‎apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import XCTest
2+
import AgentDeviceSnapshotPresentation
23

34
extension RunnerTests {
45
private static let axSnapshotErrorCode = "IOS_AX_SNAPSHOT_FAILED"

‎apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotActionability.swift‎

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)