appium-webdriveragent 16.14.1 → 16.15.0

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.
@@ -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 =
@@ -148,4 +148,49 @@
148
148
  XCTAssertTrue(endOffset.dx == -1 && endOffset.dy == -1);
149
149
  }
150
150
 
151
+ - (void)testDisplayCoordinateOffsets
152
+ {
153
+ CGSize mainSize = CGSizeMake(402, 874);
154
+ CGSize innerSize = CGSizeMake(669, 951);
155
+ NSArray<NSNumber *> *orientations = @[
156
+ @(UIInterfaceOrientationPortrait),
157
+ @(UIInterfaceOrientationLandscapeLeft),
158
+ @(UIInterfaceOrientationLandscapeRight),
159
+ @(UIInterfaceOrientationPortraitUpsideDown),
160
+ ];
161
+ NSArray<NSValue *> *expected = @[
162
+ [NSValue valueWithCGPoint:CGPointZero],
163
+ [NSValue valueWithCGPoint:CGPointMake(0, 77)],
164
+ [NSValue valueWithCGPoint:CGPointMake(267, 0)],
165
+ [NSValue valueWithCGPoint:CGPointMake(267, 77)],
166
+ ];
167
+ for (NSUInteger i = 0; i < orientations.count; i++) {
168
+ UIInterfaceOrientation orientation = orientations[i].integerValue;
169
+ CGVector offset = FBDisplayCoordinateOffset(mainSize, innerSize, orientation);
170
+ XCTAssertEqual(offset.dx, expected[i].CGPointValue.x);
171
+ XCTAssertEqual(offset.dy, expected[i].CGPointValue.y);
172
+ CGVector sameDisplay = FBDisplayCoordinateOffset(mainSize, mainSize, orientation);
173
+ XCTAssertEqual(sameDisplay.dx, 0);
174
+ XCTAssertEqual(sameDisplay.dy, 0);
175
+ CGVector reverse = FBDisplayCoordinateOffset(innerSize, mainSize, orientation);
176
+ XCTAssertEqual(reverse.dx, -expected[i].CGPointValue.x);
177
+ XCTAssertEqual(reverse.dy, -expected[i].CGPointValue.y);
178
+ }
179
+ }
180
+
181
+ - (void)testPortraitVisibleFrameRotation
182
+ {
183
+ CGSize size = CGSizeMake(669, 951);
184
+ CGRect clipped = CGRectMake(200, 100, 300, 400);
185
+ XCTAssertTrue(CGRectEqualToRect(FBRectFromPortraitCoordinates(clipped, size, UIInterfaceOrientationPortrait), clipped));
186
+ XCTAssertTrue(CGRectEqualToRect(FBRectFromPortraitCoordinates(clipped, size, UIInterfaceOrientationLandscapeLeft), CGRectMake(451, 200, 400, 300)));
187
+ XCTAssertTrue(CGRectEqualToRect(FBRectFromPortraitCoordinates(clipped, size, UIInterfaceOrientationLandscapeRight), CGRectMake(100, 169, 400, 300)));
188
+ XCTAssertTrue(CGRectEqualToRect(FBRectFromPortraitCoordinates(clipped, size, UIInterfaceOrientationPortraitUpsideDown), CGRectMake(169, 451, 300, 400)));
189
+ // Observed on Duo's inner landscape display: keep the clipping in the same
190
+ // coordinate space as the element's reported frame.
191
+ XCTAssertTrue(CGRectEqualToRect(FBRectFromPortraitCoordinates(CGRectMake(236, 104, 379, 827), size, UIInterfaceOrientationLandscapeLeft), CGRectMake(20, 236, 827, 379)));
192
+ XCTAssertTrue(CGRectIsEmpty(FBRectFromPortraitCoordinates(CGRectZero, size, UIInterfaceOrientationLandscapeLeft)));
193
+ XCTAssertTrue(CGRectIsNull(FBRectFromPortraitCoordinates(CGRectNull, size, UIInterfaceOrientationLandscapeLeft)));
194
+ }
195
+
151
196
  @end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-webdriveragent",
3
- "version": "16.14.1",
3
+ "version": "16.15.0",
4
4
  "description": "Package bundling WebDriverAgent",
5
5
  "keywords": [
6
6
  "Appium",