appium-webdriveragent 3.5.0 → 3.8.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.
Binary file
@@ -12,11 +12,12 @@
12
12
  @property (readonly) id accessibilityInterface; // implements XCUIAccessibilityInterface
13
13
  @property (readonly) id eventSynthesizer; // implements XCUIEventSynthesizing
14
14
  @property(readonly) id screenDataSource; // @synthesize screenDataSource=_screenDataSource;
15
-
15
+ - (_Bool)performDeviceEvent:(id)arg1 error:(id *)arg2;
16
16
 
17
17
  - (void)pressLockButton;
18
18
  - (void)holdHomeButtonForDuration:(double)arg1;
19
19
  - (void)_silentPressButton:(long long)arg1;
20
+ // Removed in Xcode 10.2
20
21
  - (void)_dispatchEventWithPage:(unsigned int)arg1 usage:(unsigned int)arg2 duration:(double)arg3;
21
22
 
22
23
  @end
@@ -128,6 +128,7 @@ static NSString* const FBUnknownBundleId = @"unknown";
128
128
  info[@"frame"] = NSStringFromCGRect(snapshot.wdFrame);
129
129
  info[@"isEnabled"] = [@([snapshot isWDEnabled]) stringValue];
130
130
  info[@"isVisible"] = [@([snapshot isWDVisible]) stringValue];
131
+ info[@"isAccessible"] = [@([snapshot isWDAccessible]) stringValue];
131
132
  #if TARGET_OS_TV
132
133
  info[@"isFocused"] = [@([snapshot isWDFocused]) stringValue];
133
134
  #endif
@@ -91,6 +91,28 @@ NS_ASSUME_NONNULL_BEGIN
91
91
  */
92
92
  - (BOOL)fb_activateSiriVoiceRecognitionWithText:(NSString *)text error:(NSError **)error;
93
93
 
94
+ /**
95
+ Eumlated triggering of the given low-level IOHID device event. The constants for possible events are defined
96
+ in https://unix.superglobalmegacorp.com/xnu/newsrc/iokit/IOKit/hidsystem/IOHIDUsageTables.h.html
97
+ Popular constants:
98
+ - kHIDPage_Consumer = 0x0C
99
+ - kHIDUsage_Csmr_VolumeIncrement = 0xE9 (Volume Up)
100
+ - kHIDUsage_Csmr_VolumeDecrement = 0xEA (Volume Down)
101
+ - kHIDUsage_Csmr_Menu = 0x40 (Home)
102
+ - kHIDUsage_Csmr_Power = 0x30 (Power)
103
+ - kHIDUsage_Csmr_Snapshot = 0x65 (Power + Home)
104
+
105
+ @param page The event page identifier
106
+ @param usage The event usage indentifier (usages are defined per-page)
107
+ @param duration The event duration in float seconds (XCTest uses 0.005 for a single press event)
108
+ @param error If there is an error, upon return contains an NSError object that describes the problem.
109
+ @return YES the event has successfully been triggered
110
+ */
111
+ - (BOOL)fb_performIOHIDEventWithPage:(unsigned int)page
112
+ usage:(unsigned int)usage
113
+ duration:(NSTimeInterval)duration
114
+ error:(NSError **)error;
115
+
94
116
  @end
95
117
 
96
118
  NS_ASSUME_NONNULL_END
@@ -21,6 +21,7 @@
21
21
  #import "FBScreenshot.h"
22
22
  #import "FBXCodeCompatibility.h"
23
23
  #import "XCUIDevice.h"
24
+ #import "XCDeviceEvent.h"
24
25
 
25
26
  static const NSTimeInterval FBHomeButtonCoolOffTime = 1.;
26
27
  static const NSTimeInterval FBScreenLockTimeout = 5.;
@@ -98,7 +99,8 @@ static bool fb_isLocked;
98
99
 
99
100
  - (NSData *)fb_screenshotWithError:(NSError*__autoreleasing*)error
100
101
  {
101
- return [FBScreenshot takeWithQuality:FBConfiguration.screenshotQuality error:error];
102
+ return [FBScreenshot takeInOriginalResolutionWithQuality:FBConfiguration.screenshotQuality
103
+ error:error];
102
104
  }
103
105
 
104
106
  - (BOOL)fb_fingerTouchShouldMatch:(BOOL)shouldMatch
@@ -281,4 +283,15 @@ static bool fb_isLocked;
281
283
  }
282
284
  #endif
283
285
 
286
+ - (BOOL)fb_performIOHIDEventWithPage:(unsigned int)page
287
+ usage:(unsigned int)usage
288
+ duration:(NSTimeInterval)duration
289
+ error:(NSError **)error
290
+ {
291
+ XCDeviceEvent *event = [XCDeviceEvent deviceEventWithPage:page
292
+ usage:usage
293
+ duration:duration];
294
+ return [self performDeviceEvent:event error:error];
295
+ }
296
+
284
297
  @end
@@ -34,6 +34,7 @@
34
34
  #import "XCUIElementQuery.h"
35
35
  #import "XCUIElementQuery+FBHelpers.h"
36
36
  #import "XCUIElement+FBUID.h"
37
+ #import "XCUIScreen.h"
37
38
 
38
39
  #define DEFAULT_AX_TIMEOUT 60.
39
40
 
@@ -241,9 +242,15 @@
241
242
  }
242
243
  }
243
244
  #endif
244
- return [FBScreenshot takeWithQuality:FBConfiguration.screenshotQuality
245
- rect:elementRect
246
- error:error];
245
+
246
+ // adjust element rect for the actual screen scale
247
+ XCUIScreen *mainScreen = XCUIScreen.mainScreen;
248
+ elementRect = CGRectMake(elementRect.origin.x * mainScreen.scale, elementRect.origin.y * mainScreen.scale,
249
+ elementRect.size.width * mainScreen.scale, elementRect.size.height * mainScreen.scale);
250
+
251
+ return [FBScreenshot takeInOriginalResolutionWithQuality:FBConfiguration.screenshotQuality
252
+ rect:elementRect
253
+ error:error];
247
254
  }
248
255
 
249
256
  @end
@@ -56,6 +56,7 @@
56
56
  [[FBRoute GET:@"/wda/batteryInfo"] respondWithTarget:self action:@selector(handleGetBatteryInfo:)],
57
57
  #endif
58
58
  [[FBRoute POST:@"/wda/pressButton"] respondWithTarget:self action:@selector(handlePressButtonCommand:)],
59
+ [[FBRoute POST:@"/wda/performIoHidEvent"] respondWithTarget:self action:@selector(handlePeformIOHIDEvent:)],
59
60
  [[FBRoute POST:@"/wda/expectNotification"] respondWithTarget:self action:@selector(handleExpectNotification:)],
60
61
  [[FBRoute POST:@"/wda/siri/activate"] respondWithTarget:self action:@selector(handleActivateSiri:)],
61
62
  [[FBRoute POST:@"/wda/apps/launchUnattached"].withoutSession respondWithTarget:self action:@selector(handleLaunchUnattachedApp:)],
@@ -257,6 +258,22 @@
257
258
  return FBResponseWithOK();
258
259
  }
259
260
 
261
+ + (id <FBResponsePayload>)handlePeformIOHIDEvent:(FBRouteRequest *)request
262
+ {
263
+ NSNumber *page = request.arguments[@"page"];
264
+ NSNumber *usage = request.arguments[@"usage"];
265
+ NSNumber *duration = request.arguments[@"duration"];
266
+ NSError *error;
267
+ if (![XCUIDevice.sharedDevice fb_performIOHIDEventWithPage:page.unsignedIntValue
268
+ usage:usage.unsignedIntValue
269
+ duration:duration.doubleValue
270
+ error:&error]) {
271
+ return FBResponseWithStatus([FBCommandStatus unknownErrorWithMessage:error.description
272
+ traceback:nil]);
273
+ }
274
+ return FBResponseWithOK();
275
+ }
276
+
260
277
  + (id <FBResponsePayload>)handleLaunchUnattachedApp:(FBRouteRequest *)request
261
278
  {
262
279
  NSString *bundle = (NSString *)request.arguments[@"bundleId"];
@@ -97,6 +97,16 @@
97
97
  if (requirements[@"shouldUseSingletonTestManager"]) {
98
98
  [FBConfiguration setShouldUseSingletonTestManager:[requirements[@"shouldUseSingletonTestManager"] boolValue]];
99
99
  }
100
+ if (requirements[@"disableAutomaticScreenshots"]) {
101
+ if ([requirements[@"disableAutomaticScreenshots"] boolValue]) {
102
+ [FBConfiguration disableScreenshots];
103
+ } else {
104
+ [FBConfiguration enableScreenshots];
105
+ }
106
+ }
107
+ if (requirements[@"shouldTerminateApp"]) {
108
+ [FBConfiguration setShouldTerminateApp:[requirements[@"shouldTerminateApp"] boolValue]];
109
+ }
100
110
  NSNumber *delay = requirements[@"eventloopIdleDelaySec"];
101
111
  if ([delay doubleValue] > 0.0) {
102
112
  [XCUIApplicationProcessDelay setEventLoopHasIdledDelay:[delay doubleValue]];
@@ -131,7 +131,7 @@ static FBSession *_activeSession = nil;
131
131
  self.alertsMonitor = nil;
132
132
  }
133
133
 
134
- if (self.testedApplicationBundleId) {
134
+ if (self.testedApplicationBundleId && [FBConfiguration shouldTerminateApp]) {
135
135
  [[self.applications objectForKey:self.testedApplicationBundleId] terminate];
136
136
  }
137
137
  _activeSession = nil;
@@ -30,6 +30,10 @@ extern NSString *const FBSnapshotMaxDepthKey;
30
30
  + (void)setShouldUseCompactResponses:(BOOL)value;
31
31
  + (BOOL)shouldUseCompactResponses;
32
32
 
33
+ /*! If set to YES (which is the default), the app will be terminated at the end of the session, if a bundleId was specified */
34
+ + (void)setShouldTerminateApp:(BOOL)value;
35
+ + (BOOL)shouldTerminateApp;
36
+
33
37
  /*! If shouldUseCompactResponses == NO, is the comma-separated list of fields to return with each element. Defaults to "type,label". */
34
38
  + (void)setElementResponseAttributes:(NSString *)value;
35
39
  + (NSString *)elementResponseAttributes;
@@ -43,9 +47,12 @@ extern NSString *const FBSnapshotMaxDepthKey;
43
47
  /*! Disables attribute key path analysis, which will cause XCTest on Xcode 9.x to ignore some elements */
44
48
  + (void)disableAttributeKeyPathAnalysis;
45
49
 
46
- /*! Disables XCTest from automated screenshots taking */
50
+ /*! Disables XCTest automated screenshots taking */
47
51
  + (void)disableScreenshots;
48
52
 
53
+ /*! Enables XCTest automated screenshots taking */
54
+ + (void)enableScreenshots;
55
+
49
56
  /* The maximum typing frequency for all typing activities */
50
57
  + (void)setMaxTypingFrequency:(NSUInteger)value;
51
58
  + (NSUInteger)maxTypingFrequency;
@@ -31,6 +31,7 @@ static NSString *const axSettingsClassName = @"AXSettings";
31
31
  static BOOL FBShouldUseTestManagerForVisibilityDetection = NO;
32
32
  static BOOL FBShouldUseSingletonTestManager = YES;
33
33
  static BOOL FBShouldUseCompactResponses = YES;
34
+ static BOOL FBShouldTerminateApp = YES;
34
35
  static NSString *FBElementResponseAttributes = @"type,label";
35
36
  static NSUInteger FBMaxTypingFrequency = 60;
36
37
  static NSUInteger FBMjpegServerScreenshotQuality = 25;
@@ -89,6 +90,11 @@ static UIInterfaceOrientation FBScreenshotOrientation = UIInterfaceOrientationUn
89
90
  [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"DisableScreenshots"];
90
91
  }
91
92
 
93
+ + (void)enableScreenshots
94
+ {
95
+ [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"DisableScreenshots"];
96
+ }
97
+
92
98
  + (NSRange)bindingPortRange
93
99
  {
94
100
  // 'WebDriverAgent --port 8080' can be passed via the arguments to the process
@@ -153,6 +159,16 @@ static UIInterfaceOrientation FBScreenshotOrientation = UIInterfaceOrientationUn
153
159
  return FBShouldUseCompactResponses;
154
160
  }
155
161
 
162
+ + (void)setShouldTerminateApp:(BOOL)value
163
+ {
164
+ FBShouldTerminateApp = value;
165
+ }
166
+
167
+ + (BOOL)shouldTerminateApp
168
+ {
169
+ return FBShouldTerminateApp;
170
+ }
171
+
156
172
  + (void)setElementResponseAttributes:(NSString *)value
157
173
  {
158
174
  FBElementResponseAttributes = value;
@@ -42,7 +42,9 @@ extern const CGFloat FBMaxCompressionQuality;
42
42
 
43
43
  @param image The source image data
44
44
  @param uti Either kUTTypePNG or kUTTypeJPEG
45
- @param rect The cropping rectangle. Could be CGRectNull to avoid cropping
45
+ @param rect The cropping rectange for the screenshot. The value is expected to be non-scaled one
46
+ since it happens after scaling/orientation change.
47
+ CGRectNull could be used to take a screenshot of the full screen.
46
48
  @param scalingFactor Scaling factor in range 0.01..1.0. A value of 1.0 won't perform scaling at all
47
49
  @param compressionQuality the compression quality in range 0.0..1.0 (0.0 for max. compression and 1.0 for lossless compression).
48
50
  Only works if UTI is set to kUTTypeJPEG
@@ -19,26 +19,27 @@ NS_ASSUME_NONNULL_BEGIN
19
19
  + (BOOL)isNewScreenshotAPISupported;
20
20
 
21
21
  /**
22
- Retrieves scaled screenshot of the whole screen
22
+ Retrieves non-scaled screenshot of the whole screen
23
23
 
24
24
  @param quality The number in range 0-2, where 2 (JPG) is the lowest and 0 (PNG) is the highest quality.
25
25
  @param error If there is an error, upon return contains an NSError object that describes the problem.
26
26
  @return Device screenshot as PNG- or JPG-encoded data or nil in case of failure
27
27
  */
28
- + (nullable NSData *)takeWithQuality:(NSUInteger)quality
29
- error:(NSError **)error;
28
+ + (nullable NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality
29
+ error:(NSError **)error;
30
30
 
31
31
  /**
32
- Retrieves scaled screenshot of the particular screen rectangle
32
+ Retrieves non-scaled screenshot of the particular screen rectangle
33
33
 
34
34
  @param quality The number in range 0-2, where 2 (JPG) is the lowest and 0 (PNG) is the highest quality.
35
- @param rect The bounding rectange for the screenshot. CGRectNull could be used to take a screenshot of the full screen
35
+ @param rect The bounding rectange for the screenshot. The value is expected be non-scaled one.
36
+ CGRectNull could be used to take a screenshot of the full screen.
36
37
  @param error If there is an error, upon return contains an NSError object that describes the problem.
37
38
  @return Device screenshot as PNG- or JPG-encoded data or nil in case of failure
38
39
  */
39
- + (nullable NSData *)takeWithQuality:(NSUInteger)quality
40
- rect:(CGRect)rect
41
- error:(NSError **)error;
40
+ + (nullable NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality
41
+ rect:(CGRect)rect
42
+ error:(NSError **)error;
42
43
 
43
44
  /**
44
45
  Retrieves non-scaled screenshot of the whole screen
@@ -21,6 +21,7 @@
21
21
  #import "XCUIScreen.h"
22
22
 
23
23
  static const NSTimeInterval SCREENSHOT_TIMEOUT = 20.;
24
+ static const CGFloat SCREENSHOT_SCALE = 1.0; // Screenshot API should keep the original screen scale
24
25
  static const CGFloat HIGH_QUALITY = 0.8;
25
26
  static const CGFloat LOW_QUALITY = 0.25;
26
27
 
@@ -64,14 +65,14 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
64
65
  }
65
66
  }
66
67
 
67
- + (NSData *)takeWithQuality:(NSUInteger)quality
68
- rect:(CGRect)rect
69
- error:(NSError **)error
68
+ + (NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality
69
+ rect:(CGRect)rect
70
+ error:(NSError **)error
70
71
  {
71
72
  if ([self.class isNewScreenshotAPISupported]) {
72
73
  XCUIScreen *mainScreen = XCUIScreen.mainScreen;
73
74
  return [self.class takeWithScreenID:mainScreen.displayID
74
- scale:mainScreen.scale
75
+ scale:SCREENSHOT_SCALE
75
76
  compressionQuality:[self.class compressionQualityWithQuality:FBConfiguration.screenshotQuality]
76
77
  rect:rect
77
78
  sourceUTI:[self.class imageUtiWithQuality:FBConfiguration.screenshotQuality]
@@ -84,13 +85,13 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
84
85
  return nil;
85
86
  }
86
87
 
87
- + (NSData *)takeWithQuality:(NSUInteger)quality
88
- error:(NSError **)error
88
+ + (NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality
89
+ error:(NSError **)error
89
90
  {
90
91
  if ([self.class isNewScreenshotAPISupported]) {
91
92
  XCUIScreen *mainScreen = XCUIScreen.mainScreen;
92
93
  return [self.class takeWithScreenID:mainScreen.displayID
93
- scale:mainScreen.scale
94
+ scale:SCREENSHOT_SCALE
94
95
  compressionQuality:[self.class compressionQualityWithQuality:FBConfiguration.screenshotQuality]
95
96
  rect:CGRectNull
96
97
  sourceUTI:[self.class imageUtiWithQuality:FBConfiguration.screenshotQuality]
@@ -58,6 +58,10 @@
58
58
 
59
59
  @end
60
60
 
61
+ @interface FBAccessibleAttribute : FBElementAttribute
62
+
63
+ @end
64
+
61
65
  @interface FBDimensionAttribute : FBElementAttribute
62
66
 
63
67
  @end
@@ -460,6 +464,7 @@ static NSString *const FBAbstractMethodInvocationException = @"AbstractMethodInv
460
464
  FBLabelAttribute.class,
461
465
  FBEnabledAttribute.class,
462
466
  FBVisibleAttribute.class,
467
+ FBAccessibleAttribute.class,
463
468
  #if TARGET_OS_TV
464
469
  FBFocusedAttribute.class,
465
470
  #endif
@@ -563,6 +568,20 @@ static NSString *const FBAbstractMethodInvocationException = @"AbstractMethodInv
563
568
 
564
569
  @end
565
570
 
571
+ @implementation FBAccessibleAttribute
572
+
573
+ + (NSString *)name
574
+ {
575
+ return @"accessible";
576
+ }
577
+
578
+ + (NSString *)valueForElement:(id<FBElement>)element
579
+ {
580
+ return element.wdAccessible ? @"true" : @"false";
581
+ }
582
+
583
+ @end
584
+
566
585
  #if TARGET_OS_TV
567
586
 
568
587
  @implementation FBFocusedAttribute
@@ -25,7 +25,11 @@
25
25
  [FBDebugLogDelegateDecorator decorateXCTestLogger];
26
26
  [FBConfiguration disableRemoteQueryEvaluation];
27
27
  [FBConfiguration configureDefaultKeyboardPreferences];
28
- [FBConfiguration disableScreenshots];
28
+ if (NSProcessInfo.processInfo.environment[@"ENABLE_AUTOMATIC_SCREENSHOTS"]) {
29
+ [FBConfiguration enableScreenshots];
30
+ } else {
31
+ [FBConfiguration disableScreenshots];
32
+ }
29
33
  [super setUp];
30
34
  }
31
35
 
Binary file
@@ -12,6 +12,7 @@
12
12
  #import "FBIntegrationTestCase.h"
13
13
  #import "XCUIDevice+FBRotation.h"
14
14
  #import "XCUIElement+FBUtilities.h"
15
+ #import "XCUIScreen.h"
15
16
 
16
17
  @interface FBElementScreenshotTests : FBIntegrationTestCase
17
18
  @end
@@ -48,6 +49,15 @@
48
49
  UIImage *image = [UIImage imageWithData:screenshotData];
49
50
  XCTAssertNotNil(image);
50
51
  XCTAssertTrue(image.size.width > image.size.height);
52
+
53
+ XCUIScreen *mainScreen = XCUIScreen.mainScreen;
54
+ UIImage *buttonScreenshot = button.screenshot.image;
55
+ XCTAssertEqualWithAccuracy(buttonScreenshot.size.height * mainScreen.scale,
56
+ image.size.height,
57
+ FLT_EPSILON);
58
+ XCTAssertEqualWithAccuracy(buttonScreenshot.size.width * mainScreen.scale,
59
+ image.size.width,
60
+ FLT_EPSILON);
51
61
  }
52
62
 
53
63
  @end
@@ -54,7 +54,7 @@
54
54
  XCElementSnapshot *snapshot = self.destinationSnapshot;
55
55
  NSString *xmlStr = [FBXPath xmlStringWithRootElement:snapshot excludingAttributes:nil];
56
56
  XCTAssertNotNil(xmlStr);
57
- NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\"/>\n", snapshot.wdType, snapshot.wdType, snapshot.wdName, snapshot.wdLabel, snapshot.wdEnabled ? @"true" : @"false", snapshot.wdVisible ? @"true" : @"false", [snapshot.wdRect[@"x"] stringValue], [snapshot.wdRect[@"y"] stringValue], [snapshot.wdRect[@"width"] stringValue], [snapshot.wdRect[@"height"] stringValue], snapshot.wdIndex];
57
+ NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\"/>\n", snapshot.wdType, snapshot.wdType, snapshot.wdName, snapshot.wdLabel, snapshot.wdEnabled ? @"true" : @"false", snapshot.wdVisible ? @"true" : @"false", snapshot.wdAccessible ? @"true" : @"false", [snapshot.wdRect[@"x"] stringValue], [snapshot.wdRect[@"y"] stringValue], [snapshot.wdRect[@"width"] stringValue], [snapshot.wdRect[@"height"] stringValue], snapshot.wdIndex];
58
58
  XCTAssertEqualObjects(xmlStr, expectedXml);
59
59
  }
60
60
 
@@ -63,7 +63,7 @@
63
63
  XCElementSnapshot *snapshot = self.destinationSnapshot;
64
64
  NSString *xmlStr = [FBXPath xmlStringWithRootElement:snapshot excludingAttributes:@[@"visible", @"enabled", @"index", @"blabla"]];
65
65
  XCTAssertNotNil(xmlStr);
66
- NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\"/>\n", snapshot.wdType, snapshot.wdType, snapshot.wdName, snapshot.wdLabel, [snapshot.wdRect[@"x"] stringValue], [snapshot.wdRect[@"y"] stringValue], [snapshot.wdRect[@"width"] stringValue], [snapshot.wdRect[@"height"] stringValue]];
66
+ NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\"/>\n", snapshot.wdType, snapshot.wdType, snapshot.wdName, snapshot.wdLabel, snapshot.wdAccessible ? @"true" : @"false", [snapshot.wdRect[@"x"] stringValue], [snapshot.wdRect[@"y"] stringValue], [snapshot.wdRect[@"width"] stringValue], [snapshot.wdRect[@"height"] stringValue]];
67
67
  XCTAssertEqualObjects(xmlStr, expectedXml);
68
68
  }
69
69
 
@@ -16,6 +16,7 @@
16
16
  #import "FBTestMacros.h"
17
17
  #import "XCUIDevice+FBHelpers.h"
18
18
  #import "XCUIDevice+FBRotation.h"
19
+ #import "XCUIScreen.h"
19
20
 
20
21
  @interface XCUIDeviceHelperTests : FBIntegrationTestCase
21
22
  @end
@@ -33,11 +34,24 @@
33
34
 
34
35
  - (void)testScreenshot
35
36
  {
37
+ [[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:UIDeviceOrientationPortrait];
36
38
  NSError *error = nil;
37
39
  NSData *screenshotData = [[XCUIDevice sharedDevice] fb_screenshotWithError:&error];
38
- XCTAssertNotNil([UIImage imageWithData:screenshotData]);
40
+ XCTAssertNotNil(screenshotData);
39
41
  XCTAssertNil(error);
40
42
  XCTAssertTrue(FBIsPngImage(screenshotData));
43
+
44
+ UIImage *screenshot = [UIImage imageWithData:screenshotData];
45
+ XCTAssertNotNil(screenshot);
46
+
47
+ XCUIScreen *mainScreen = XCUIScreen.mainScreen;
48
+ UIImage *screenshotExact = ((XCUIScreenshot *)mainScreen.screenshot).image;
49
+ XCTAssertEqualWithAccuracy(screenshotExact.size.height * mainScreen.scale,
50
+ screenshot.size.height,
51
+ FLT_EPSILON);
52
+ XCTAssertEqualWithAccuracy(screenshotExact.size.width * mainScreen.scale,
53
+ screenshot.size.width,
54
+ FLT_EPSILON);
41
55
  }
42
56
 
43
57
  - (void)testLandscapeScreenshot
@@ -48,9 +62,19 @@
48
62
  XCTAssertNotNil(screenshotData);
49
63
  XCTAssertTrue(FBIsPngImage(screenshotData));
50
64
  XCTAssertNil(error);
51
- UIImage *image = [UIImage imageWithData:screenshotData];
52
- XCTAssertNotNil(image);
53
- XCTAssertTrue(image.size.width > image.size.height);
65
+
66
+ UIImage *screenshot = [UIImage imageWithData:screenshotData];
67
+ XCTAssertNotNil(screenshot);
68
+ XCTAssertTrue(screenshot.size.width > screenshot.size.height);
69
+
70
+ XCUIScreen *mainScreen = XCUIScreen.mainScreen;
71
+ UIImage *screenshotExact = ((XCUIScreenshot *)mainScreen.screenshot).image;
72
+ XCTAssertEqualWithAccuracy(screenshotExact.size.height * mainScreen.scale,
73
+ screenshot.size.height,
74
+ FLT_EPSILON);
75
+ XCTAssertEqualWithAccuracy(screenshotExact.size.width * mainScreen.scale,
76
+ screenshot.size.width,
77
+ FLT_EPSILON);
54
78
  }
55
79
 
56
80
  - (void)testWifiAddress
@@ -106,4 +130,16 @@
106
130
  XCTAssertNil(error);
107
131
  }
108
132
 
133
+ - (void)testLongPressHomeButton
134
+ {
135
+ NSError *error;
136
+ // kHIDPage_Consumer = 0x0C
137
+ // kHIDUsage_Csmr_Menu = 0x40
138
+ XCTAssertTrue([XCUIDevice.sharedDevice fb_performIOHIDEventWithPage:0x0C
139
+ usage:0x40
140
+ duration:1.0
141
+ error:&error]);
142
+ XCTAssertNil(error);
143
+ }
144
+
109
145
  @end
@@ -51,8 +51,8 @@
51
51
  NSString *resultXml = [self xmlStringWithElement:element
52
52
  xpathQuery:nil
53
53
  excludingAttributes:nil];
54
- NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" value=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" private_indexPath=\"top\"/>\n",
55
- element.wdType, element.wdType, element.wdValue, element.wdName, element.wdLabel, element.wdEnabled ? @"true" : @"false", element.wdVisible ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex];
54
+ NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" value=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" private_indexPath=\"top\"/>\n",
55
+ element.wdType, element.wdType, element.wdValue, element.wdName, element.wdLabel, element.wdEnabled ? @"true" : @"false", element.wdVisible ? @"true" : @"false", element.wdAccessible ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex];
56
56
  XCTAssertTrue([resultXml isEqualToString: expectedXml]);
57
57
  }
58
58
 
@@ -62,8 +62,8 @@
62
62
  NSString *resultXml = [self xmlStringWithElement:element
63
63
  xpathQuery:nil
64
64
  excludingAttributes:@[@"type", @"visible", @"value", @"index"]];
65
- NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ name=\"%@\" label=\"%@\" enabled=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" private_indexPath=\"top\"/>\n",
66
- element.wdType, element.wdName, element.wdLabel, element.wdEnabled ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"]];
65
+ NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ name=\"%@\" label=\"%@\" enabled=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" private_indexPath=\"top\"/>\n",
66
+ element.wdType, element.wdName, element.wdLabel, element.wdEnabled ? @"true" : @"false", element.wdAccessible ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"]];
67
67
  XCTAssertEqualObjects(resultXml, expectedXml);
68
68
  }
69
69
 
@@ -73,8 +73,8 @@
73
73
  NSString *resultXml = [self xmlStringWithElement:element
74
74
  xpathQuery:[NSString stringWithFormat:@"//%@[@*]", element.wdType]
75
75
  excludingAttributes:@[@"visible"]];
76
- NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" value=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" private_indexPath=\"top\"/>\n",
77
- element.wdType, element.wdType, element.wdValue, element.wdName, element.wdLabel, element.wdEnabled ? @"true" : @"false", element.wdVisible ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex];
76
+ NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" value=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" private_indexPath=\"top\"/>\n",
77
+ element.wdType, element.wdType, element.wdValue, element.wdName, element.wdLabel, element.wdEnabled ? @"true" : @"false", element.wdVisible ? @"true" : @"false", element.wdAccessible ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex];
78
78
  XCTAssertTrue([resultXml isEqualToString: expectedXml]);
79
79
  }
80
80
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-webdriveragent",
3
- "version": "3.5.0",
3
+ "version": "3.8.0",
4
4
  "description": "Package bundling WebDriverAgent",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
@@ -54,7 +54,7 @@
54
54
  "ios-uicatalog": "^3.5.0",
55
55
  "mocha": "^8.0.1",
56
56
  "pre-commit": "^1.2.2",
57
- "sinon": "^9.0.2",
57
+ "sinon": "^10.0.0",
58
58
  "wd": "^1.11.4"
59
59
  },
60
60
  "dependencies": {