@devicelab/maestro-runner-darwin-arm64 1.1.29 → 1.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -4
- package/bin/maestro-runner +0 -0
- package/drivers/android/devicelab-android-driver-test.apk +0 -0
- package/drivers/android/devicelab-android-driver.apk +0 -0
- package/drivers/ios/DevicelabIOSRunner/DevicelabIOSRunnerUITests/ATTRIBUTION.md +16 -0
- package/drivers/ios/DevicelabIOSRunner/DevicelabIOSRunnerUITests/RunnerTests+Lifecycle.swift +33 -0
- package/drivers/ios/DevicelabIOSRunner/DevicelabIOSRunnerUITests/RunnerTests+Snapshot.swift +195 -88
- package/drivers/ios/DevicelabIOSRunner/DevicelabIOSRunnerUITests/RunnerTests.swift +3 -0
- package/drivers/ios/WebDriverAgent/CHANGELOG.md +202 -0
- package/drivers/ios/WebDriverAgent/README.md +18 -9
- package/drivers/ios/WebDriverAgent/Scripts/ci/build-real.sh +6 -10
- package/drivers/ios/WebDriverAgent/Scripts/fetch-prebuilt-wda.mjs +3 -2
- package/drivers/ios/WebDriverAgent/WebDriverAgent.xcodeproj/project.pbxproj +119 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCAXClient_iOS+FBSnapshotReqParams.m +8 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h +3 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +30 -1
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCUIApplication+FBTouchAction.h +53 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCUIApplication+FBTouchAction.m +124 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h +6 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m +100 -23
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCUIDevice+FBHinge.h +41 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCUIDevice+FBHinge.m +215 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCUIDevice+FBRotation.m +8 -3
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCUIElement+FBFind.m +20 -7
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCUIElement+FBScrolling.m +110 -50
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCUIElement+FBTyping.h +7 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m +20 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m +14 -11
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Commands/FBCustomCommands.m +86 -10
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Commands/FBElementCommands.m +57 -7
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Commands/FBSessionCommands.m +3 -2
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Info.plist +2 -2
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Routing/FBHTTPServer.m +39 -16
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Routing/FBScreenRecordingRequest.m +7 -2
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Routing/FBSession.h +22 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Routing/FBSession.m +78 -12
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Routing/FBTCPSocket.h +5 -1
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Routing/FBTCPSocket.m +10 -1
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Routing/FBWebServer.m +4 -1
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBActiveAppDetectionPoint.h +2 -2
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBActiveAppDetectionPoint.m +20 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBConfiguration.h +8 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBConfiguration.m +2 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBHIDOperations.h +41 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBHIDOperations.m +244 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBImageProcessor.m +3 -1
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBMathUtils.h +11 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBMathUtils.m +38 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBMjpegServer.m +5 -3
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBScreen.h +17 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBScreen.m +76 -1
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBScreenshot.h +2 -2
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBScreenshot.m +6 -2
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBSettings.h +2 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBSettings.m +2 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBSettingsHandler.m +48 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m +121 -13
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/FBXPath.m +181 -128
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/LRUCache/LRUCache.m +8 -5
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/Utilities/LRUCache/LRUCacheNode.h +1 -1
- package/drivers/ios/WebDriverAgent/WebDriverAgentLib/WebDriverAgentLib.h +1 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationApp/COORDINATE_PROBE.md +3 -1
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationApp/Classes/FBCoordinateProbeViewController.m +18 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationApp/Classes/SceneDelegate.m +33 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationApp/Classes/ViewController.m +26 -7
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/FBConfigurationTests.m +52 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/FBDisplayGestureTests.m +541 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/FBElementSwipingTests.m +95 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/FBImageProcessorTests.m +34 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/FBScreenTests.m +392 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m +97 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/FBTypingTest.m +33 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m +126 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/XCUIApplicationHelperTests.m +111 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m +97 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/XCUIDeviceRotationTests.m +53 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m +113 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests_tvOS/FBTVFocusIntegrationTests.m +21 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests_watchOS/WDAAppLifecycleIntegrationTests.swift +12 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/UnitTests/FBCustomCommandsTests.m +61 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/UnitTests/FBElementUtilitiesTests.m +40 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/UnitTests/FBHTTPServerSessionTests.m +22 -4
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/UnitTests/FBHTTPServerTests.m +199 -5
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/UnitTests/FBLRUCacheTests.m +34 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/UnitTests/FBMathUtilsTests.m +45 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/UnitTests/FBSessionTests.m +201 -0
- package/drivers/ios/WebDriverAgent/WebDriverAgentTests/UnitTests/FBXPathTests.m +101 -0
- package/drivers/ios/WebDriverAgent/docs/hinge-angle.md +54 -0
- package/drivers/ios/WebDriverAgent/docs/multiple-displays.md +168 -0
- package/drivers/ios/WebDriverAgent/lib/webdriveragent.ts +1 -2
- package/drivers/ios/WebDriverAgent/lib/xcodebuild.ts +58 -10
- package/drivers/ios/WebDriverAgent/package.json +8 -15
- package/drivers/ios/WebDriverAgent/test/functional/helpers/display-settings.ts +49 -0
- package/drivers/ios/WebDriverAgent/test/functional/helpers/simulator.ts +7 -7
- package/drivers/ios/WebDriverAgent/test/functional/webdriveragent-e2e.spec.ts +4 -0
- package/drivers/ios/WebDriverAgent/test/unit/xcodebuild.spec.ts +230 -0
- package/drivers/ios/WebDriverAgent/tsconfig.json +2 -1
- package/drivers/ios/devicelab-ios-agent/README.md +12 -0
- package/drivers/ios/devicelab-ios-agent/device/DevicelabIOSAgent.app/DevicelabIOSAgent +0 -0
- package/drivers/ios/devicelab-ios-agent/device/DevicelabIOSAgentUITests-Runner.app/PlugIns/DevicelabIOSAgentUITests.xctest/DevicelabIOSAgentUITests +0 -0
- package/drivers/ios/devicelab-ios-agent/device/manifest.json +3 -3
- package/drivers/ios/devicelab-ios-agent/simulator/DevicelabIOSAgent.app/DevicelabIOSAgent +0 -0
- package/drivers/ios/devicelab-ios-agent/simulator/DevicelabIOSAgentUITests-Runner.app/PlugIns/DevicelabIOSAgentUITests.xctest/DevicelabIOSAgentUITests +0 -0
- package/drivers/ios/devicelab-ios-agent/simulator/manifest.json +3 -3
- package/package.json +1 -1
- package/drivers/ios/WebDriverAgent/.editorconfig +0 -11
- package/drivers/ios/WebDriverAgent/.github/ISSUE_TEMPLATE.md +0 -4
- package/drivers/ios/WebDriverAgent/.github/actions/xcode-setup/action.yml +0 -32
- package/drivers/ios/WebDriverAgent/.github/dependabot.yml +0 -22
- package/drivers/ios/WebDriverAgent/.github/workflows/functional-test.yml +0 -103
- package/drivers/ios/WebDriverAgent/.github/workflows/pr-title.yml +0 -10
- package/drivers/ios/WebDriverAgent/.github/workflows/publish.js.yml +0 -112
- package/drivers/ios/WebDriverAgent/.github/workflows/unit-test.yml +0 -32
- package/drivers/ios/WebDriverAgent/.github/workflows/wda-package.yml +0 -114
- package/drivers/ios/WebDriverAgent/.github/workflows/wda-tests.yml +0 -246
- package/drivers/ios/WebDriverAgent/oxfmt.config.mjs +0 -6
- package/drivers/ios/WebDriverAgent/oxlint.config.mjs +0 -6
- package/drivers/ios/WebDriverAgent/release.config.mjs +0 -14
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
#import <XCTest/XCTest.h>
|
|
10
10
|
|
|
11
11
|
#import "FBIntegrationTestCase.h"
|
|
12
|
+
#import "FBConfiguration.h"
|
|
13
|
+
#import "FBMathUtils.h"
|
|
14
|
+
#import "FBScreen.h"
|
|
12
15
|
|
|
13
16
|
#import "XCUIElement.h"
|
|
14
17
|
#import "XCUIDevice.h"
|
|
@@ -21,6 +24,7 @@
|
|
|
21
24
|
#import "XCSynthesizedEventRecord.h"
|
|
22
25
|
#import "XCPointerEventPath.h"
|
|
23
26
|
#import "XCPointerEvent.h"
|
|
27
|
+
#import "XCUIScreen.h"
|
|
24
28
|
|
|
25
29
|
@interface FBW3CTouchActionsIntegrationTestsPart1 : FBIntegrationTestCase
|
|
26
30
|
@end
|
|
@@ -32,9 +36,36 @@
|
|
|
32
36
|
|
|
33
37
|
@implementation FBW3CTouchActionsIntegrationTestsPart1
|
|
34
38
|
|
|
39
|
+
- (void)testDisplayIndependentActionsAfterSelectedDisplayDisappears
|
|
40
|
+
{
|
|
41
|
+
// setUp already opens the Alerts fixture; relaunching would reset that page
|
|
42
|
+
// and break the subsequent touch tests that share it.
|
|
43
|
+
NSNumber *previous = FBConfiguration.sharedInstance.currentDisplayId;
|
|
44
|
+
[self addTeardownBlock:^{ FBConfiguration.sharedInstance.currentDisplayId = previous; }];
|
|
45
|
+
NSArray *sequences = @[
|
|
46
|
+
@{@"id": @"keyboard", @"type": @"key", @"actions": @[@{@"type": @"keyDown", @"value": @"a"}, @{@"type": @"keyUp", @"value": @"a"}]},
|
|
47
|
+
@{@"id": @"finger", @"type": @"pointer", @"parameters": @{@"pointerType": @"touch"}, @"actions": @[@{@"type": @"pause", @"duration": @10}]}
|
|
48
|
+
];
|
|
49
|
+
for (NSDictionary *sequence in sequences) {
|
|
50
|
+
for (NSNumber *display in @[@1, @987654]) {
|
|
51
|
+
FBConfiguration.sharedInstance.currentDisplayId = display;
|
|
52
|
+
NSError *error = nil;
|
|
53
|
+
FBW3CActionsSynthesizer *synthesizer = [[FBW3CActionsSynthesizer alloc] initWithActions:@[sequence] forApplication:self.testedApplication elementCache:nil error:&error];
|
|
54
|
+
XCSynthesizedEventRecord *record = [synthesizer synthesizeWithError:&error];
|
|
55
|
+
XCTAssertNotNil(record, @"Display-independent %@ should succeed: %@", sequence[@"type"], error);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
35
60
|
- (void)verifyGesture:(NSArray<NSDictionary<NSString *, id> *> *)gesture orientation:(UIDeviceOrientation)orientation
|
|
36
61
|
{
|
|
37
62
|
[[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:orientation];
|
|
63
|
+
// XCTest may report the new interface orientation while the Alerts button
|
|
64
|
+
// still has transposed geometry from the rotation transition. The fixture's
|
|
65
|
+
// button is wider than it is tall in every settled orientation. Wait for that
|
|
66
|
+
// layout before resolving the W3C action's element-origin coordinates.
|
|
67
|
+
XCUIElement *button = self.testedApplication.buttons[FBShowAlertButtonName];
|
|
68
|
+
FBAssertWaitTillBecomesTrue(CGRectGetWidth(button.frame) > CGRectGetHeight(button.frame));
|
|
38
69
|
NSError *error;
|
|
39
70
|
XCTAssertTrue([self.testedApplication fb_performW3CActions:gesture elementCache:nil error:&error]);
|
|
40
71
|
FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count > 0);
|
|
@@ -53,11 +84,106 @@
|
|
|
53
84
|
|
|
54
85
|
- (void)tearDown
|
|
55
86
|
{
|
|
87
|
+
FBConfiguration.sharedInstance.currentDisplayId = nil;
|
|
56
88
|
[self clearAlert];
|
|
57
89
|
[self resetOrientation];
|
|
58
90
|
[super tearDown];
|
|
59
91
|
}
|
|
60
92
|
|
|
93
|
+
- (nullable XCSynthesizedEventRecord *)tapRecordWithError:(NSError **)error
|
|
94
|
+
{
|
|
95
|
+
NSArray *gesture = @[@{
|
|
96
|
+
@"type": @"pointer", @"id": @"finger", @"parameters": @{@"pointerType": @"touch"},
|
|
97
|
+
@"actions": @[
|
|
98
|
+
@{@"type": @"pointerMove", @"x": @100, @"y": @100, @"duration": @0},
|
|
99
|
+
@{@"type": @"pointerDown", @"button": @0},
|
|
100
|
+
@{@"type": @"pointerUp", @"button": @0},
|
|
101
|
+
],
|
|
102
|
+
}];
|
|
103
|
+
FBW3CActionsSynthesizer *synthesizer = [[FBW3CActionsSynthesizer alloc] initWithActions:gesture
|
|
104
|
+
forApplication:self.testedApplication
|
|
105
|
+
elementCache:nil
|
|
106
|
+
error:error];
|
|
107
|
+
return [synthesizer synthesizeWithError:error];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
- (NSArray<XCPointerEvent *> *)pointerEventsOfRecord:(XCSynthesizedEventRecord *)record
|
|
111
|
+
{
|
|
112
|
+
XCPointerEventPath *eventPath = record.eventPaths.firstObject;
|
|
113
|
+
return eventPath.pointerEvents;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
- (void)testMainDisplaySettingKeepsDefaultCoordinates
|
|
117
|
+
{
|
|
118
|
+
for (NSNumber *orientation in @[@(UIDeviceOrientationPortrait),
|
|
119
|
+
@(UIDeviceOrientationLandscapeLeft),
|
|
120
|
+
@(UIDeviceOrientationLandscapeRight)]) {
|
|
121
|
+
[[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:orientation.integerValue];
|
|
122
|
+
NSError *error = nil;
|
|
123
|
+
FBConfiguration.sharedInstance.currentDisplayId = nil;
|
|
124
|
+
XCSynthesizedEventRecord *baseline = [self tapRecordWithError:&error];
|
|
125
|
+
FBConfiguration.sharedInstance.currentDisplayId = @([FBScreen displayID]);
|
|
126
|
+
XCSynthesizedEventRecord *selected = [self tapRecordWithError:&error];
|
|
127
|
+
XCTAssertNotNil(baseline);
|
|
128
|
+
XCTAssertNotNil(selected);
|
|
129
|
+
XCTAssertNil(error);
|
|
130
|
+
NSArray<XCPointerEvent *> *baselineEvents = [self pointerEventsOfRecord:baseline];
|
|
131
|
+
NSArray<XCPointerEvent *> *selectedEvents = [self pointerEventsOfRecord:selected];
|
|
132
|
+
XCTAssertEqual(baselineEvents.count, selectedEvents.count);
|
|
133
|
+
for (NSUInteger i = 0; i < baselineEvents.count; i++) {
|
|
134
|
+
XCTAssertTrue(CGPointEqualToPoint(baselineEvents[i].coordinate, selectedEvents[i].coordinate));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
- (void)testUnavailableDisplaySettingIsRejected
|
|
140
|
+
{
|
|
141
|
+
long long maxID = 0;
|
|
142
|
+
for (NSDictionary<NSString *, id> *screen in [FBScreen screensWithError:nil]) {
|
|
143
|
+
maxID = MAX(maxID, [screen[@"displayId"] longLongValue]);
|
|
144
|
+
}
|
|
145
|
+
FBConfiguration.sharedInstance.currentDisplayId = @(maxID + 1);
|
|
146
|
+
NSError *error = nil;
|
|
147
|
+
XCTAssertNil([self tapRecordWithError:&error]);
|
|
148
|
+
XCTAssertNotNil(error);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
- (void)testSecondaryDisplaySetting
|
|
152
|
+
{
|
|
153
|
+
XCUIScreen *secondary = nil;
|
|
154
|
+
NSError *error = nil;
|
|
155
|
+
NSArray<NSDictionary<NSString *, id> *> *screens = [FBScreen screensWithError:&error];
|
|
156
|
+
XCTAssertNotNil(screens);
|
|
157
|
+
XCTAssertNil(error);
|
|
158
|
+
for (NSDictionary<NSString *, id> *screen in screens) {
|
|
159
|
+
long long displayID = [screen[@"displayId"] longLongValue];
|
|
160
|
+
if (displayID != [FBScreen displayID]) {
|
|
161
|
+
secondary = [FBScreen screenWithDisplayID:displayID error:&error];
|
|
162
|
+
XCTAssertNotNil(secondary);
|
|
163
|
+
XCTAssertNil(error);
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (nil == secondary) {
|
|
168
|
+
XCTSkip(@"The device has no secondary display");
|
|
169
|
+
}
|
|
170
|
+
XCSynthesizedEventRecord *baseline = [self tapRecordWithError:&error];
|
|
171
|
+
FBConfiguration.sharedInstance.currentDisplayId = @(secondary.displayID);
|
|
172
|
+
XCSynthesizedEventRecord *selected = [self tapRecordWithError:&error];
|
|
173
|
+
XCTAssertNotNil(selected);
|
|
174
|
+
XCTAssertNil(error);
|
|
175
|
+
XCTAssertEqual(selected.displayID, (unsigned long long)secondary.displayID);
|
|
176
|
+
XCUIScreen *main = XCUIScreen.mainScreen;
|
|
177
|
+
CGVector offset = FBDisplayCoordinateOffset(
|
|
178
|
+
CGSizeMake(main.bounds.size.width / main.scale, main.bounds.size.height / main.scale),
|
|
179
|
+
CGSizeMake(secondary.bounds.size.width / secondary.scale, secondary.bounds.size.height / secondary.scale),
|
|
180
|
+
selected.interfaceOrientation);
|
|
181
|
+
CGPoint expected = [self pointerEventsOfRecord:baseline].firstObject.coordinate;
|
|
182
|
+
CGPoint actual = [self pointerEventsOfRecord:selected].firstObject.coordinate;
|
|
183
|
+
XCTAssertEqual(actual.x, expected.x + offset.dx);
|
|
184
|
+
XCTAssertEqual(actual.y, expected.y + offset.dy);
|
|
185
|
+
}
|
|
186
|
+
|
|
61
187
|
- (void)testErroneousGestures
|
|
62
188
|
{
|
|
63
189
|
NSArray<NSArray<NSDictionary<NSString *, id> *> *> *invalidGestures =
|
package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/XCUIApplicationHelperTests.m
CHANGED
|
@@ -9,15 +9,29 @@
|
|
|
9
9
|
#import <XCTest/XCTest.h>
|
|
10
10
|
|
|
11
11
|
#import <mach/mach_time.h>
|
|
12
|
+
#import <math.h>
|
|
12
13
|
|
|
13
14
|
#import "FBIntegrationTestCase.h"
|
|
14
15
|
#import "FBElement.h"
|
|
16
|
+
#import "FBSession.h"
|
|
17
|
+
#import "FBSessionCommands.h"
|
|
15
18
|
#import "FBMacros.h"
|
|
16
19
|
#import "FBTestMacros.h"
|
|
17
20
|
#import "XCUIApplication.h"
|
|
18
21
|
#import "XCUIApplication+FBHelpers.h"
|
|
19
22
|
#import "XCUIElement+FBIsVisible.h"
|
|
20
23
|
#import "FBXCodeCompatibility.h"
|
|
24
|
+
#import "FBConfiguration.h"
|
|
25
|
+
#import "FBScreen.h"
|
|
26
|
+
#import "FBRunLoopSpinner.h"
|
|
27
|
+
#import "XCUIDevice+FBHinge.h"
|
|
28
|
+
|
|
29
|
+
// Exercise the session-start resume path without creating a second session.
|
|
30
|
+
@interface FBSessionCommands (FBActivationTests)
|
|
31
|
+
+ (id)activateBackgroundApplication:(XCUIApplication *)app
|
|
32
|
+
bundleID:(NSString *)bundleID
|
|
33
|
+
initialUrl:(nullable NSString *)initialUrl;
|
|
34
|
+
@end
|
|
21
35
|
|
|
22
36
|
void calculateMaxTreeDepth(NSDictionary *tree, NSNumber *currentDepth, NSNumber** maxDepth) {
|
|
23
37
|
if (nil == maxDepth) {
|
|
@@ -83,6 +97,103 @@ void calculateMaxTreeDepth(NSDictionary *tree, NSNumber *currentDepth, NSNumber*
|
|
|
83
97
|
XCTAssertTrue(self.testedApplication.buttons[@"Alerts"].exists);
|
|
84
98
|
}
|
|
85
99
|
|
|
100
|
+
- (void)testInputAfterDeactivate
|
|
101
|
+
{
|
|
102
|
+
[self verifyInputAfterBackgroundWithMode:0];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
- (void)testInputAfterSessionActivate
|
|
106
|
+
{
|
|
107
|
+
[self verifyInputAfterBackgroundWithMode:1];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
- (void)testInputAfterSessionLaunch
|
|
111
|
+
{
|
|
112
|
+
[self verifyInputAfterBackgroundWithMode:2];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
- (void)testInputAfterSessionStartActivate
|
|
116
|
+
{
|
|
117
|
+
[self verifyInputAfterBackgroundWithMode:3];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
- (void)verifyInputAfterBackgroundWithMode:(NSUInteger)mode
|
|
121
|
+
{
|
|
122
|
+
XCTSkipIf(self.class.isRunningInCI, @"Immediate input after activation is unreliable on slow CI hosts");
|
|
123
|
+
XCUIDevice *device = XCUIDevice.sharedDevice;
|
|
124
|
+
BOOL canFold = NO;
|
|
125
|
+
#if TARGET_OS_SIMULATOR
|
|
126
|
+
canFold = device.fb_canAttemptSimulatedHingeAngleInjection;
|
|
127
|
+
#endif
|
|
128
|
+
NSNumber *originalAngle = canFold ? [device fb_getSimulatedHingeAngle:nil] : nil;
|
|
129
|
+
NSNumber *originalDisplay = FBConfiguration.sharedInstance.currentDisplayId;
|
|
130
|
+
if (canFold) {
|
|
131
|
+
XCTAssertNotNil(originalAngle);
|
|
132
|
+
}
|
|
133
|
+
BOOL (^setAngleAndWait)(NSNumber *) = ^BOOL(NSNumber *angle) {
|
|
134
|
+
if (![device fb_setSimulatedHingeAngle:angle.doubleValue error:nil]) {
|
|
135
|
+
return NO;
|
|
136
|
+
}
|
|
137
|
+
return [[[FBRunLoopSpinner new] timeout:5] spinUntilTrue:^BOOL{
|
|
138
|
+
NSNumber *reading = [device fb_getSimulatedHingeAngle:nil];
|
|
139
|
+
return nil != reading && fabs(reading.doubleValue - angle.doubleValue) < 1;
|
|
140
|
+
}];
|
|
141
|
+
};
|
|
142
|
+
FBSession *session = mode != 0 ? [FBSession initWithApplication:self.testedApplication] : nil;
|
|
143
|
+
@try {
|
|
144
|
+
for (NSNumber *angle in (canFold ? @[@0, @90, @180] : @[@0])) {
|
|
145
|
+
if (canFold) {
|
|
146
|
+
XCTAssertTrue(setAngleAndWait(angle), @"Hinge did not reach %@ degrees", angle);
|
|
147
|
+
for (NSDictionary *screen in [FBScreen screensWithError:nil]) {
|
|
148
|
+
if ([screen[@"isMain"] boolValue] == (angle.intValue == 0)) {
|
|
149
|
+
FBConfiguration.sharedInstance.currentDisplayId = screen[@"displayId"];
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
for (NSNumber *duration in @[@0, @2]) {
|
|
154
|
+
[self launchApplication];
|
|
155
|
+
NSError *error = nil;
|
|
156
|
+
if (mode != 0) {
|
|
157
|
+
XCTAssertTrue([device fb_goToHomescreenWithError:&error]);
|
|
158
|
+
XCTAssertTrue([[[FBRunLoopSpinner new] timeout:5] spinUntilTrue:^BOOL{
|
|
159
|
+
XCUIApplicationState state = self.testedApplication.state;
|
|
160
|
+
return state == XCUIApplicationStateRunningBackground
|
|
161
|
+
|| state == XCUIApplicationStateRunningBackgroundSuspended;
|
|
162
|
+
}]);
|
|
163
|
+
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:duration.doubleValue]];
|
|
164
|
+
XCUIApplicationState state = self.testedApplication.state;
|
|
165
|
+
XCTAssertTrue(state == XCUIApplicationStateRunningBackground
|
|
166
|
+
|| state == XCUIApplicationStateRunningBackgroundSuspended,
|
|
167
|
+
@"Expected a background app before activation (angle %@, duration %@), got %lu",
|
|
168
|
+
angle, duration, (unsigned long)state);
|
|
169
|
+
if (mode == 1) {
|
|
170
|
+
[session activateApplicationWithBundleId:self.testedApplication.bundleID];
|
|
171
|
+
} else if (mode == 2) {
|
|
172
|
+
[session launchApplicationWithBundleId:self.testedApplication.bundleID
|
|
173
|
+
shouldWaitForQuiescence:nil arguments:nil environment:nil];
|
|
174
|
+
} else {
|
|
175
|
+
XCTAssertNil([FBSessionCommands activateBackgroundApplication:self.testedApplication
|
|
176
|
+
bundleID:self.testedApplication.bundleID
|
|
177
|
+
initialUrl:nil]);
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
XCTAssertTrue([self.testedApplication fb_deactivateWithDuration:duration.doubleValue error:&error]);
|
|
181
|
+
}
|
|
182
|
+
XCTAssertNil(error);
|
|
183
|
+
// Existence/foreground checks alone miss lost input. Do not add a
|
|
184
|
+
// delay or retry: this first tap must actually open the alerts page.
|
|
185
|
+
[self.testedApplication.buttons[@"Alerts"] tap];
|
|
186
|
+
XCTAssertTrue([self.testedApplication.buttons[FBShowAlertButtonName] waitForExistenceWithTimeout:2]);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
} @finally {
|
|
190
|
+
[session kill];
|
|
191
|
+
BOOL restored = nil == originalAngle || setAngleAndWait(originalAngle);
|
|
192
|
+
FBConfiguration.sharedInstance.currentDisplayId = originalDisplay;
|
|
193
|
+
XCTAssertTrue(restored, @"Hinge did not return to %@ degrees", originalAngle);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
86
197
|
- (void)testActiveApplication
|
|
87
198
|
{
|
|
88
199
|
XCUIApplication *systemApp = XCUIApplication.fb_systemApplication;
|
package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
#import <XCTest/XCTest.h>
|
|
10
|
+
#import <math.h>
|
|
10
11
|
|
|
11
12
|
#import "FBIntegrationTestCase.h"
|
|
12
13
|
#import "FBImageUtils.h"
|
|
@@ -15,6 +16,7 @@
|
|
|
15
16
|
#import "XCUIApplication.h"
|
|
16
17
|
#import "XCUIApplication+FBHelpers.h"
|
|
17
18
|
#import "XCUIDevice+FBHelpers.h"
|
|
19
|
+
#import "XCUIDevice+FBHinge.h"
|
|
18
20
|
#import "XCUIDevice+FBRotation.h"
|
|
19
21
|
#import "XCUIScreen.h"
|
|
20
22
|
|
|
@@ -104,6 +106,53 @@
|
|
|
104
106
|
FBAssertWaitTillBecomesTrue([XCUIApplication fb_activeApplication].icons[@"Safari"].exists);
|
|
105
107
|
}
|
|
106
108
|
|
|
109
|
+
- (void)testHomeButtonBackgroundsApplication
|
|
110
|
+
{
|
|
111
|
+
XCUIDevice *device = XCUIDevice.sharedDevice;
|
|
112
|
+
BOOL hasHinge = NO;
|
|
113
|
+
#if TARGET_OS_SIMULATOR
|
|
114
|
+
hasHinge = device.fb_canAttemptSimulatedHingeAngleInjection;
|
|
115
|
+
#endif
|
|
116
|
+
NSNumber *originalAngle = hasHinge ? [device fb_getSimulatedHingeAngle:nil] : nil;
|
|
117
|
+
if (hasHinge && nil == originalAngle) {
|
|
118
|
+
XCTFail(@"Cannot read the original hinge angle");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
BOOL (^setAngleAndWait)(NSNumber *) = ^BOOL(NSNumber *angle) {
|
|
122
|
+
return [device fb_setSimulatedHingeAngle:angle.doubleValue error:nil]
|
|
123
|
+
&& [[[FBRunLoopSpinner new] timeout:5] spinUntilTrue:^BOOL{
|
|
124
|
+
NSNumber *reading = [device fb_getSimulatedHingeAngle:nil];
|
|
125
|
+
return nil != reading && fabs(reading.doubleValue - angle.doubleValue) < 1;
|
|
126
|
+
}];
|
|
127
|
+
};
|
|
128
|
+
@try {
|
|
129
|
+
for (NSNumber *angle in (hasHinge ? @[@0, @180] : @[@0])) {
|
|
130
|
+
if (hasHinge) {
|
|
131
|
+
if (!setAngleAndWait(angle)) {
|
|
132
|
+
XCTFail(@"Hinge angle did not reach %@", angle);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
for (NSUInteger attempt = 0; attempt < 2; attempt++) {
|
|
137
|
+
[self.testedApplication activate];
|
|
138
|
+
XCTAssertEqual(self.testedApplication.state, XCUIApplicationStateRunningForeground);
|
|
139
|
+
NSError *error = nil;
|
|
140
|
+
XCTAssertTrue([device fb_pressButton:@"home" forDuration:nil error:&error]);
|
|
141
|
+
XCTAssertNil(error);
|
|
142
|
+
XCTAssertTrue([[[FBRunLoopSpinner new] timeout:5] spinUntilTrue:^BOOL{
|
|
143
|
+
return self.testedApplication.state == XCUIApplicationStateRunningBackground
|
|
144
|
+
|| self.testedApplication.state == XCUIApplicationStateRunningBackgroundSuspended;
|
|
145
|
+
}]);
|
|
146
|
+
XCTAssertTrue([XCUIApplication.fb_activeApplication.bundleID isEqualToString:@"com.apple.springboard"]);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
} @finally {
|
|
150
|
+
if (nil != originalAngle) {
|
|
151
|
+
XCTAssertTrue(setAngleAndWait(originalAngle));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
107
156
|
- (void)testLockUnlockScreen
|
|
108
157
|
{
|
|
109
158
|
XCTAssertFalse([[XCUIDevice sharedDevice] fb_isScreenLocked]);
|
|
@@ -116,6 +165,54 @@
|
|
|
116
165
|
XCTAssertNil(error);
|
|
117
166
|
}
|
|
118
167
|
|
|
168
|
+
- (void)testRepeatedLockUnlockAcrossHingePoses
|
|
169
|
+
{
|
|
170
|
+
XCTSkipIf(self.class.isRunningInCI, @"Repeated lock/unlock is unreliable on slow CI hosts");
|
|
171
|
+
XCUIDevice *device = XCUIDevice.sharedDevice;
|
|
172
|
+
BOOL hasHinge = NO;
|
|
173
|
+
#if TARGET_OS_SIMULATOR
|
|
174
|
+
hasHinge = device.fb_canAttemptSimulatedHingeAngleInjection;
|
|
175
|
+
#endif
|
|
176
|
+
NSNumber *originalAngle = hasHinge ? [device fb_getSimulatedHingeAngle:nil] : nil;
|
|
177
|
+
if (hasHinge) {
|
|
178
|
+
XCTAssertNotNil(originalAngle);
|
|
179
|
+
}
|
|
180
|
+
BOOL (^setAngleAndWait)(NSNumber *) = ^BOOL(NSNumber *angle) {
|
|
181
|
+
return [device fb_setSimulatedHingeAngle:angle.doubleValue error:nil]
|
|
182
|
+
&& [[[FBRunLoopSpinner new] timeout:5] spinUntilTrue:^BOOL{
|
|
183
|
+
NSNumber *reading = [device fb_getSimulatedHingeAngle:nil];
|
|
184
|
+
return nil != reading && fabs(reading.doubleValue - angle.doubleValue) < 1;
|
|
185
|
+
}];
|
|
186
|
+
};
|
|
187
|
+
@try {
|
|
188
|
+
for (NSNumber *angle in (hasHinge ? @[@0, @90, @180] : @[@0])) {
|
|
189
|
+
if (hasHinge) {
|
|
190
|
+
XCTAssertTrue(setAngleAndWait(angle));
|
|
191
|
+
}
|
|
192
|
+
for (NSUInteger attempt = 0; attempt < 3; attempt++) {
|
|
193
|
+
XCTAssertFalse(device.fb_isScreenLocked);
|
|
194
|
+
NSError *error = nil;
|
|
195
|
+
XCTAssertTrue([device fb_lockScreen:&error]);
|
|
196
|
+
XCTAssertNil(error);
|
|
197
|
+
XCTAssertTrue(device.fb_isScreenLocked);
|
|
198
|
+
// Repeating lock must not toggle the screen back to unlocked.
|
|
199
|
+
XCTAssertTrue([device fb_lockScreen:&error]);
|
|
200
|
+
XCTAssertTrue(device.fb_isScreenLocked);
|
|
201
|
+
XCTAssertTrue([device fb_unlockScreen:&error]);
|
|
202
|
+
XCTAssertNil(error);
|
|
203
|
+
XCTAssertFalse(device.fb_isScreenLocked);
|
|
204
|
+
XCTAssertTrue([device fb_unlockScreen:&error]);
|
|
205
|
+
XCTAssertFalse(device.fb_isScreenLocked);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
} @finally {
|
|
209
|
+
[device fb_unlockScreen:nil];
|
|
210
|
+
if (nil != originalAngle) {
|
|
211
|
+
XCTAssertTrue(setAngleAndWait(originalAngle));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
119
216
|
- (void)testUrlSchemeActivation
|
|
120
217
|
{
|
|
121
218
|
if (SYSTEM_VERSION_LESS_THAN(@"16.4")) {
|
package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/XCUIDeviceRotationTests.m
CHANGED
|
@@ -10,8 +10,13 @@
|
|
|
10
10
|
#import <UIKit/UIKit.h>
|
|
11
11
|
#import "FBIntegrationTestCase.h"
|
|
12
12
|
#import "XCUIDevice+FBRotation.h"
|
|
13
|
+
#import "XCUIDevice+FBHinge.h"
|
|
14
|
+
#import "FBConfiguration.h"
|
|
15
|
+
#import "FBScreen.h"
|
|
16
|
+
#import "FBSession.h"
|
|
13
17
|
|
|
14
18
|
@interface XCUIDeviceRotationTests : FBIntegrationTestCase
|
|
19
|
+
@property (nonatomic, strong) FBSession *session;
|
|
15
20
|
|
|
16
21
|
@end
|
|
17
22
|
|
|
@@ -21,11 +26,13 @@
|
|
|
21
26
|
{
|
|
22
27
|
[super setUp];
|
|
23
28
|
[self launchApplication];
|
|
29
|
+
self.session = [FBSession initWithApplication:self.testedApplication];
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
- (void)tearDown
|
|
27
33
|
{
|
|
28
34
|
[self resetOrientation];
|
|
35
|
+
[self.session kill];
|
|
29
36
|
[super tearDown];
|
|
30
37
|
}
|
|
31
38
|
|
|
@@ -102,4 +109,50 @@
|
|
|
102
109
|
XCTAssertEqual(currentRotation, [XCUIDevice sharedDevice].orientation, @"Device doesnt support tilt, should be at previous orientation");
|
|
103
110
|
}
|
|
104
111
|
|
|
112
|
+
- (void)testRotationOnSelectedDuoDisplay
|
|
113
|
+
{
|
|
114
|
+
#if TARGET_OS_SIMULATOR
|
|
115
|
+
XCUIDevice *device = XCUIDevice.sharedDevice;
|
|
116
|
+
XCTSkipIf(!device.fb_supportsHingeAngleReading || !device.fb_canAttemptSimulatedHingeAngleInjection,
|
|
117
|
+
@"Requires hinge angle reading and injection support");
|
|
118
|
+
NSNumber *originalDisplay = FBConfiguration.sharedInstance.currentDisplayId;
|
|
119
|
+
NSNumber *originalAngle = [device fb_getSimulatedHingeAngle:nil];
|
|
120
|
+
XCTAssertNotNil(originalAngle);
|
|
121
|
+
@try {
|
|
122
|
+
for (NSNumber *angle in @[@0, @90, @180]) {
|
|
123
|
+
XCTAssertTrue([device fb_setSimulatedHingeAngle:angle.doubleValue error:nil]);
|
|
124
|
+
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];
|
|
125
|
+
for (NSDictionary *screen in [FBScreen screensWithError:nil]) {
|
|
126
|
+
if ([screen[@"isMain"] boolValue] == (angle.intValue == 0)) {
|
|
127
|
+
FBConfiguration.sharedInstance.currentDisplayId = screen[@"displayId"];
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
[self.testedApplication activate];
|
|
131
|
+
NSArray *orientations = @[@(UIDeviceOrientationLandscapeLeft),
|
|
132
|
+
@(UIDeviceOrientationLandscapeRight),
|
|
133
|
+
@(UIDeviceOrientationPortrait)];
|
|
134
|
+
NSArray *labels = @[@"LandscapeRight", @"LandscapeLeft", @"Portrait"];
|
|
135
|
+
for (NSUInteger i = 0; i < orientations.count; i++) {
|
|
136
|
+
UIDeviceOrientation orientation = [orientations[i] integerValue];
|
|
137
|
+
XCTAssertTrue([device fb_setDeviceInterfaceOrientation:orientation]);
|
|
138
|
+
XCTAssertTrue([self.testedApplication.staticTexts[labels[i]] waitForExistenceWithTimeout:5]);
|
|
139
|
+
XCTAssertEqual(device.orientation, orientation);
|
|
140
|
+
}
|
|
141
|
+
BOOL rotated = [device fb_setDeviceRotation:@{@"x": @0, @"y": @0, @"z": @270}];
|
|
142
|
+
XCTAssertTrue(rotated);
|
|
143
|
+
XCTAssertTrue(self.testedApplication.staticTexts[@"LandscapeRight"].exists);
|
|
144
|
+
}
|
|
145
|
+
} @finally {
|
|
146
|
+
[device fb_setSimulatedHingeAngle:0 error:nil];
|
|
147
|
+
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];
|
|
148
|
+
FBConfiguration.sharedInstance.currentDisplayId = nil;
|
|
149
|
+
[device fb_setDeviceInterfaceOrientation:UIDeviceOrientationPortrait];
|
|
150
|
+
if (nil != originalAngle) {
|
|
151
|
+
[device fb_setSimulatedHingeAngle:originalAngle.doubleValue error:nil];
|
|
152
|
+
}
|
|
153
|
+
FBConfiguration.sharedInstance.currentDisplayId = originalDisplay;
|
|
154
|
+
}
|
|
155
|
+
#endif
|
|
156
|
+
}
|
|
157
|
+
|
|
105
158
|
@end
|
package/drivers/ios/WebDriverAgent/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
#import <XCTest/XCTest.h>
|
|
10
10
|
|
|
11
11
|
#import "FBIntegrationTestCase.h"
|
|
12
|
+
#import "FBConfiguration.h"
|
|
12
13
|
#import "FBElementUtils.h"
|
|
13
14
|
#import "FBExceptions.h"
|
|
14
15
|
#import "FBTestMacros.h"
|
|
@@ -558,3 +559,115 @@
|
|
|
558
559
|
}
|
|
559
560
|
|
|
560
561
|
@end
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
@interface XCUIElementFBFindTests_IdentifierSemantics : FBIntegrationTestCase
|
|
565
|
+
@end
|
|
566
|
+
|
|
567
|
+
@implementation XCUIElementFBFindTests_IdentifierSemantics
|
|
568
|
+
|
|
569
|
+
- (void)setUp
|
|
570
|
+
{
|
|
571
|
+
[super setUp];
|
|
572
|
+
self.testedApplication.launchArguments = @[@"--identifier-lookup-test"];
|
|
573
|
+
[self.testedApplication launch];
|
|
574
|
+
XCTAssertTrue([self.testedApplication.otherElements[@"IdentifierLookupFixture"] waitForExistenceWithTimeout:5]);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
- (void)tearDown
|
|
578
|
+
{
|
|
579
|
+
[self.testedApplication terminate];
|
|
580
|
+
[super tearDown];
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
- (void)testIdentifierTakesPrecedenceOverLabel
|
|
584
|
+
{
|
|
585
|
+
NSArray<XCUIElement *> *matches = [self.testedApplication fb_descendantsMatchingIdentifier:@"something"
|
|
586
|
+
shouldReturnAfterFirstMatch:NO];
|
|
587
|
+
XCTAssertEqual(matches.count, 4);
|
|
588
|
+
XCTAssertEqualObjects([matches valueForKey:@"label"], (@[@"other label", @"something", @"something", @"something"]));
|
|
589
|
+
XCTAssertEqual([self.testedApplication fb_descendantsMatchingIdentifier:@"different" shouldReturnAfterFirstMatch:NO].count, 1);
|
|
590
|
+
// A matching label must not override a different, nonempty identifier.
|
|
591
|
+
XCTAssertEqual([self.testedApplication fb_descendantsMatchingIdentifier:@"other label" shouldReturnAfterFirstMatch:NO].count, 0);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
- (void)testEmptyIdentifierDoesNotMatchEmptyAccessibilityId
|
|
595
|
+
{
|
|
596
|
+
// The fixture has an empty identifier with a nonempty label at index 2,
|
|
597
|
+
// and an empty identifier with an empty label at index 5.
|
|
598
|
+
XCUIElement *labelFallback = [self.testedApplication.staticTexts elementBoundByIndex:2];
|
|
599
|
+
XCUIElement *unnamed = [self.testedApplication.staticTexts elementBoundByIndex:5];
|
|
600
|
+
XCTAssertEqualObjects(labelFallback.identifier, @"");
|
|
601
|
+
XCTAssertEqualObjects(labelFallback.label, @"something");
|
|
602
|
+
XCTAssertEqualObjects(unnamed.identifier, @"");
|
|
603
|
+
XCTAssertEqualObjects(unnamed.label, @"");
|
|
604
|
+
|
|
605
|
+
// Regression guard for "identifier != nil AND identifier != ''": the old
|
|
606
|
+
// wdName lookup used the nonempty label, or nil when both fields were empty.
|
|
607
|
+
// Thus an empty query matched neither element. Checking only identifier != nil
|
|
608
|
+
// would instead let identifier == @"" match both, changing existing behavior.
|
|
609
|
+
BOOL previousFirstMatch = FBConfiguration.sharedInstance.useFirstMatch;
|
|
610
|
+
@try {
|
|
611
|
+
for (NSNumber *useFirstMatch in @[@NO, @YES]) {
|
|
612
|
+
FBConfiguration.sharedInstance.useFirstMatch = useFirstMatch.boolValue;
|
|
613
|
+
for (NSNumber *firstMatch in @[@NO, @YES]) {
|
|
614
|
+
XCTAssertEqual([self.testedApplication fb_descendantsMatchingIdentifier:@""
|
|
615
|
+
shouldReturnAfterFirstMatch:firstMatch.boolValue].count, 0,
|
|
616
|
+
@"An empty accessibility ID must not match empty identifiers, even when they are non-nil");
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
} @finally {
|
|
620
|
+
FBConfiguration.sharedInstance.useFirstMatch = previousFirstMatch;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
- (void)testMissingQuotedAndUnicodeIdentifiers
|
|
625
|
+
{
|
|
626
|
+
for (NSNumber *firstMatch in @[@NO, @YES]) {
|
|
627
|
+
XCTAssertEqual([self.testedApplication fb_descendantsMatchingIdentifier:@"missing-target" shouldReturnAfterFirstMatch:firstMatch.boolValue].count, 0);
|
|
628
|
+
XCTAssertEqual([self.testedApplication fb_descendantsMatchingIdentifier:@"quote'\"é" shouldReturnAfterFirstMatch:firstMatch.boolValue].count, 1);
|
|
629
|
+
XCTAssertEqual([self.testedApplication fb_descendantsMatchingIdentifier:@"日本語" shouldReturnAfterFirstMatch:firstMatch.boolValue].count, 1);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
- (void)testFirstMatchAndParentScopeWithBothBindings
|
|
634
|
+
{
|
|
635
|
+
BOOL previousBinding = FBConfiguration.sharedInstance.boundElementsByIndex;
|
|
636
|
+
@try {
|
|
637
|
+
for (NSNumber *indexed in @[@NO, @YES]) {
|
|
638
|
+
FBConfiguration.sharedInstance.boundElementsByIndex = indexed.boolValue;
|
|
639
|
+
// Use the element returned by WDA lookup, as the element-scoped endpoint does.
|
|
640
|
+
XCUIElement *parent = [self.testedApplication fb_descendantsMatchingIdentifier:@"IdentifierLookupFixture"
|
|
641
|
+
shouldReturnAfterFirstMatch:YES].firstObject;
|
|
642
|
+
XCTAssertNotNil(parent);
|
|
643
|
+
// The HTTP endpoint resolves the parent when registering its element ID.
|
|
644
|
+
XCTAssertNotNil(parent.fb_uid);
|
|
645
|
+
NSArray<XCUIElement *> *matches = [parent fb_descendantsMatchingIdentifier:@"something" shouldReturnAfterFirstMatch:NO];
|
|
646
|
+
NSArray<XCUIElement *> *first = [parent fb_descendantsMatchingIdentifier:@"something" shouldReturnAfterFirstMatch:YES];
|
|
647
|
+
XCTAssertEqual(matches.count, 4);
|
|
648
|
+
XCTAssertEqual(first.count, 1);
|
|
649
|
+
XCTAssertEqualObjects(first.firstObject.fb_uid, matches.firstObject.fb_uid);
|
|
650
|
+
NSArray<XCUIElement *> *selfMatches = [parent fb_descendantsMatchingIdentifier:@"IdentifierLookupFixture" shouldReturnAfterFirstMatch:NO];
|
|
651
|
+
XCTAssertEqual(selfMatches.count, 1);
|
|
652
|
+
XCTAssertEqualObjects(selfMatches.firstObject.fb_uid, parent.fb_uid);
|
|
653
|
+
}
|
|
654
|
+
} @finally {
|
|
655
|
+
FBConfiguration.sharedInstance.boundElementsByIndex = previousBinding;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
- (void)testIdentifierChangesAreObserved
|
|
660
|
+
{
|
|
661
|
+
NSArray<XCUIElement *> *before = [self.testedApplication fb_descendantsMatchingIdentifier:@"something" shouldReturnAfterFirstMatch:NO];
|
|
662
|
+
XCTAssertEqual(before.count, 4);
|
|
663
|
+
NSArray<NSString *> *beforeIds = [before valueForKey:@"fb_uid"];
|
|
664
|
+
[self.testedApplication.buttons[@"mutateIdentifier"] tap];
|
|
665
|
+
NSArray<XCUIElement *> *after = [self.testedApplication fb_descendantsMatchingIdentifier:@"something" shouldReturnAfterFirstMatch:NO];
|
|
666
|
+
NSArray<XCUIElement *> *changed = [self.testedApplication fb_descendantsMatchingIdentifier:@"changed" shouldReturnAfterFirstMatch:NO];
|
|
667
|
+
XCTAssertEqual(after.count, 3);
|
|
668
|
+
XCTAssertEqual(changed.count, 1);
|
|
669
|
+
XCTAssertEqualObjects([after valueForKey:@"fb_uid"], [beforeIds subarrayWithRange:NSMakeRange(1, 3)]);
|
|
670
|
+
XCTAssertEqualObjects(changed.firstObject.fb_uid, beforeIds.firstObject);
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
@end
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
#import <XCTest/XCTest.h>
|
|
10
|
+
#import "XCUIApplication+FBHelpers.h"
|
|
11
|
+
#import "XCUIDevice+FBHelpers.h"
|
|
10
12
|
|
|
11
13
|
#if TARGET_OS_TV
|
|
12
14
|
|
|
@@ -79,6 +81,25 @@
|
|
|
79
81
|
XCTAssertFalse(disabled.hasFocus);
|
|
80
82
|
}
|
|
81
83
|
|
|
84
|
+
- (void)testHomeAndInputAfterDeactivate
|
|
85
|
+
{
|
|
86
|
+
NSError *error = nil;
|
|
87
|
+
XCTAssertTrue([XCUIDevice.sharedDevice fb_goToHomescreenWithError:&error], @"%@", error);
|
|
88
|
+
XCTAssertNotEqual(self.app.state, XCUIApplicationStateRunningForeground);
|
|
89
|
+
XCTAssertEqual(XCUIApplication.fb_systemApplication.state, XCUIApplicationStateRunningForeground);
|
|
90
|
+
[self.app activate];
|
|
91
|
+
for (NSNumber *duration in @[@0, @2]) {
|
|
92
|
+
[self.app launch];
|
|
93
|
+
XCTAssertTrue([self.app fb_deactivateWithDuration:duration.doubleValue error:&error], @"%@", error);
|
|
94
|
+
XCTAssertEqual(self.app.state, XCUIApplicationStateRunningForeground);
|
|
95
|
+
XCTAssertTrue([self.app.buttons[@"cell_1_2"] fb_selectWithError:&error], @"%@", error);
|
|
96
|
+
XCTNSPredicateExpectation *updated = [[XCTNSPredicateExpectation alloc]
|
|
97
|
+
initWithPredicate:[NSPredicate predicateWithFormat:@"label == %@", @"cell_1_2"]
|
|
98
|
+
object:self.app.staticTexts[@"lastSelectedLabel"]];
|
|
99
|
+
[self waitForExpectations:@[updated] timeout:5];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
82
103
|
@end
|
|
83
104
|
|
|
84
105
|
#endif
|
|
@@ -34,4 +34,16 @@ final class WDAAppLifecycleIntegrationTests: WDAWatchInProcessTestCase {
|
|
|
34
34
|
app.activate()
|
|
35
35
|
XCTAssertEqual(app.state, .runningForeground)
|
|
36
36
|
}
|
|
37
|
+
func testHomeAndDeactivate() throws {
|
|
38
|
+
try XCUIDevice.shared.fb_goToHomescreen()
|
|
39
|
+
XCTAssertNotEqual(app.state, .runningForeground)
|
|
40
|
+
try XCUIDevice.shared.fb_goToHomescreen()
|
|
41
|
+
XCTAssertNotEqual(app.state, .runningForeground)
|
|
42
|
+
for duration in [0.0, 2.0] {
|
|
43
|
+
app.activate()
|
|
44
|
+
try app.fb_deactivate(withDuration: duration)
|
|
45
|
+
XCTAssertEqual(app.state, .runningForeground)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
37
49
|
}
|