Raw
1 import XCTest
2 @testable import XCRSControlKit
3
4 final class XCRSControlKitTests: XCTestCase {
5 func testStandardCapabilitiesArePlatformSpecific() {
6 let iOSCapabilities = XCRSControlKitCapabilities.standard(for: .iOS)
7 let tvOSCapabilities = XCRSControlKitCapabilities.standard(for: .tvOS)
8
9 XCTAssertTrue(iOSCapabilities.supports(.touch))
10 XCTAssertFalse(iOSCapabilities.supports(.remoteButtons))
11 XCTAssertTrue(tvOSCapabilities.supports(.remoteButtons))
12 XCTAssertFalse(tvOSCapabilities.supports(.touch))
13 }
14
15 func testCapabilitiesAreCodable() throws {
16 let capabilities = XCRSControlKitCapabilities.standard(for: .macOS)
17 let encoded = try JSONEncoder().encode(capabilities)
18 let decoded = try JSONDecoder().decode(
19 XCRSControlKitCapabilities.self,
20 from: encoded
21 )
22
23 XCTAssertEqual(decoded, capabilities)
24 }
25
26 func testRequestHasStableTransportShape() throws {
27 let request = XCRSControlKitRequest(
28 id: "request-1",
29 method: "device.io.button",
30 parameters: ["button": "select"]
31 )
32
33 let object = try JSONSerialization.jsonObject(
34 with: JSONEncoder().encode(request)
35 ) as? [String: Any]
36
37 XCTAssertEqual(object?["id"] as? String, "request-1")
38 XCTAssertEqual(object?["method"] as? String, "device.io.button")
39 XCTAssertEqual(
40 (object?["parameters"] as? [String: String])?["button"],
41 "select"
42 )
43 }
44
45 func testAccessibilityNodeHasStableTransportShape() throws {
46 let node = XCRSControlKitAccessibilityNode(
47 type: "Button",
48 label: "Play",
49 name: "play-button",
50 rawIdentifier: "play-button",
51 rect: XCRSControlKitRect(x: 100, y: 200, width: 80, height: 40),
52 enabled: true,
53 selected: false,
54 focused: false,
55 hittable: true
56 )
57
58 let object = try JSONSerialization.jsonObject(
59 with: JSONEncoder().encode(node)
60 ) as? [String: Any]
61 let rect = object?["rect"] as? [String: Any]
62
63 XCTAssertEqual(object?["type"] as? String, "Button")
64 XCTAssertEqual(object?["label"] as? String, "Play")
65 XCTAssertEqual(object?["rawIdentifier"] as? String, "play-button")
66 XCTAssertEqual(rect?["x"] as? Double, 100)
67 XCTAssertEqual(rect?["width"] as? Double, 80)
68 XCTAssertEqual((object?["children"] as? [[String: Any]])?.count, 0)
69 }
70
71 func testAccessibilityParserReadsSingleXCTestSnapshot() throws {
72 let hierarchy = """
73 Attributes: Application, 0x1, pid: 42, label: 'Sample App'
74 Element subtree:
75 →Application, 0x1, pid: 42, label: 'Sample App'
76 Window (Main), 0x2, {{0.0, 0.0}, {1920.0, 1080.0}}
77 Button, 0x3, {{576.0, 64.0}, {63.0, 32.0}}, identifier: 'Start', label: 'Hem', Focused
78 Path to element:
79 →Application, 0x1, pid: 42, label: 'Sample App'
80 """
81
82 let root = try XCRSControlKitAccessibilityParser.parse(
83 debugDescription: hierarchy
84 )
85
86 XCTAssertEqual(root.type, "Application")
87 XCTAssertEqual(root.label, "Sample App")
88 XCTAssertEqual(root.children.count, 1)
89 let window = try XCTUnwrap(root.children.first)
90 XCTAssertEqual(window.type, "Window (Main)")
91 let button = try XCTUnwrap(window.children.first)
92 XCTAssertEqual(button.type, "Button")
93 XCTAssertEqual(button.label, "Hem")
94 XCTAssertEqual(button.rawIdentifier, "Start")
95 XCTAssertEqual(button.rect.x, 576)
96 XCTAssertEqual(root.depth, 0)
97 XCTAssertEqual(window.depth, 1)
98 XCTAssertEqual(button.depth, 2)
99 XCTAssertEqual(button.selected, false)
100 XCTAssertEqual(button.focused, true)
101 }
102
103 func testAccessibilityParserReadsQuotedAttributesAndStates() throws {
104 let hierarchy = """
105 Element subtree:
106 →Application, 0x1, label: 'Disabled, Selected, Focused'
107 Button, 0x2, label: 'O'Brien', Disabled, Selected, Focused
108 Path to element:
109 """
110
111 let root = try XCRSControlKitAccessibilityParser.parse(
112 debugDescription: hierarchy
113 )
114
115 XCTAssertEqual(root.label, "Disabled, Selected, Focused")
116 let button = try XCTUnwrap(root.children.first)
117 XCTAssertEqual(button.label, "O'Brien")
118 XCTAssertEqual(button.enabled, false)
119 XCTAssertEqual(button.selected, true)
120 XCTAssertEqual(button.focused, true)
121 XCTAssertEqual(root.enabled, true)
122 }
123
124 func testAccessibilityParserKeepsSiblingsAtTheSameIndentation() throws {
125 let hierarchy = """
126 Element subtree:
127 →Application, 0x1
128 Button, 0x2, label: 'First'
129 Button, 0x3, label: 'Second'
130 Path to element:
131 """
132
133 let root = try XCRSControlKitAccessibilityParser.parse(
134 debugDescription: hierarchy
135 )
136
137 XCTAssertEqual(root.children.map(\.label), ["First", "Second"])
138 XCTAssertTrue(root.children.allSatisfy(\.children.isEmpty))
139 }
140
141 func testAccessibilityParserReadsEscapedAndBraceTerminatedAttributes() throws {
142 let hierarchy = """
143 Element subtree:
144 →Application, 0x1, label: 'Sample'}
145 Button, 0x2, label: 'It\\'s ready', Selected
146 Path to element:
147 """
148
149 let root = try XCRSControlKitAccessibilityParser.parse(
150 debugDescription: hierarchy
151 )
152
153 XCTAssertEqual(root.label, "Sample")
154 let button = try XCTUnwrap(root.children.first)
155 XCTAssertEqual(button.label, "It\\'s ready")
156 XCTAssertEqual(button.selected, true)
157 }
158
159 func testAccessibilityParserRejectsMultipleRootElements() {
160 let hierarchy = """
161 Element subtree:
162 →Application, 0x1
163 →Window, 0x2
164 Path to element:
165 """
166
167 XCTAssertThrowsError(
168 try XCRSControlKitAccessibilityParser.parse(
169 debugDescription: hierarchy
170 )
171 ) { error in
172 XCTAssertEqual(
173 error as? XCRSControlKitError,
174 .invalidRequest("XCTest returned multiple root accessibility elements")
175 )
176 }
177 }
178 }