Skip to content

Commit 2869f01

Browse files
committed
test(ios): execute selector read ambiguity regression
1 parent b840ec1 commit 2869f01

4 files changed

Lines changed: 59 additions & 1 deletion

File tree

.github/workflows/ios.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ jobs:
9797
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testBareDelayedTypeFailsWhenTappedInputDisappearsMidCommand \
9898
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testSynthesizedTextCommitProgressWalksExpectedPrefixOnly \
9999
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testTextEntryTapWitnessIsBoundToTargetIdentity \
100+
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testQuerySelectorPrefersHittableMatchOverNonHittableDuplicate \
100101
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testActivateTargetSkipsForegroundAndActivatesNonForegroundApplication \
101102
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testMissingBundleCommandInvalidatesCompleteCachedTargetState \
102103
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testCachedTargetInvalidationClearsProcessBoundState \

apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,26 @@ - (void)viewDidLoad {
105105
[textField.heightAnchor constraintEqualToConstant:44],
106106
]];
107107
}
108+
109+
if ([NSProcessInfo.processInfo.arguments containsObject:@"--agent-device-selector-read-regression"]) {
110+
NSString *const duplicateIdentifier = @"agent-device-selector-read-duplicate";
111+
112+
UIButton *visibleButton = [UIButton buttonWithType:UIButtonTypeSystem];
113+
visibleButton.accessibilityIdentifier = duplicateIdentifier;
114+
[visibleButton setTitle:@"Readable target" forState:UIControlStateNormal];
115+
visibleButton.translatesAutoresizingMaskIntoConstraints = NO;
116+
[self.view addSubview:visibleButton];
117+
118+
UILabel *offscreenLabel = [[UILabel alloc] initWithFrame:CGRectMake(-200, -200, 100, 40)];
119+
offscreenLabel.accessibilityIdentifier = duplicateIdentifier;
120+
offscreenLabel.text = @"Decorative duplicate";
121+
[self.view addSubview:offscreenLabel];
122+
123+
[NSLayoutConstraint activateConstraints:@[
124+
[visibleButton.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
125+
[visibleButton.topAnchor constraintEqualToAnchor:label.bottomAnchor constant:24],
126+
]];
127+
}
108128
#endif
109129
}
110130

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1653,7 +1653,7 @@ extension RunnerTests {
16531653
return .context(ActiveCommandContext(app: activeApp))
16541654
}
16551655

1656-
private func executeOnMainPrepared(
1656+
func executeOnMainPrepared(
16571657
command: Command,
16581658
activeApp: XCUIApplication,
16591659
alertDeadline: Date? = nil

apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SelectorMatchPolicyTests.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,42 @@ extension RunnerTests {
8181
.selected(index: 1, usedNonHittableFallback: true)
8282
)
8383
}
84+
85+
#if os(iOS)
86+
func testQuerySelectorPrefersHittableMatchOverNonHittableDuplicate() throws {
87+
let duplicateIdentifier = "agent-device-selector-read-duplicate"
88+
app.launchArguments = ["--agent-device-selector-read-regression"]
89+
app.launch()
90+
defer {
91+
invalidateCachedTarget(reason: "unit_test_cleanup")
92+
app.terminate()
93+
}
94+
XCTAssertTrue(app.waitForExistence(timeout: appExistenceTimeout))
95+
96+
let matches = app.descendants(matching: .any)
97+
.matching(identifier: duplicateIdentifier)
98+
.allElementsBoundByIndex
99+
.filter(\.exists)
100+
XCTAssertEqual(matches.count, 2, "fixture must expose two raw identifier matches")
101+
XCTAssertEqual(matches.filter(\.isHittable).count, 1, "fixture must expose exactly one hittable match")
102+
103+
let command = try JSONDecoder().decode(
104+
Command.self,
105+
from: Data(
106+
#"{"command":"querySelector","commandId":"query-selector-duplicate","selectorKey":"id","selectorValue":"agent-device-selector-read-duplicate"}"#.utf8
107+
)
108+
)
109+
let response = try executeOnMainPrepared(command: command, activeApp: app)
110+
111+
guard response.ok else {
112+
XCTFail(String(describing: response.error))
113+
return
114+
}
115+
XCTAssertEqual(response.data?.found, true)
116+
XCTAssertEqual(response.data?.nodes?.count, 1)
117+
XCTAssertEqual(response.data?.nodes?.first?.identifier, duplicateIdentifier)
118+
XCTAssertEqual(response.data?.nodes?.first?.hittable, true)
119+
}
120+
#endif
84121
#endif
85122
}

0 commit comments

Comments
 (0)