appium-webdriveragent 5.3.2 → 5.4.1
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/CHANGELOG.md +26 -0
- package/WebDriverAgentLib/Utilities/FBConfiguration.h +8 -4
- package/WebDriverAgentLib/Utilities/FBConfiguration.m +11 -1
- package/WebDriverAgentLib/Utilities/FBImageIOScaler.h +5 -5
- package/WebDriverAgentLib/Utilities/FBImageIOScaler.m +8 -5
- package/WebDriverAgentLib/Utilities/FBMjpegServer.m +2 -13
- package/WebDriverAgentLib/Utilities/FBScreenshot.h +8 -12
- package/WebDriverAgentLib/Utilities/FBScreenshot.m +59 -117
- package/WebDriverAgentLib/Utilities/FBUnattachedAppLauncher.m +3 -0
- package/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m +67 -51
- package/WebDriverAgentLib/Utilities/FBXCodeCompatibility.m +10 -6
- package/WebDriverAgentRunner/UITestingUITests.m +5 -0
- package/WebDriverAgentTests/IntegrationTests/FBImageIOScalerTests.m +0 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
## [5.4.1](https://github.com/appium/WebDriverAgent/compare/v5.4.0...v5.4.1) (2023-06-09)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Return default testmanagerd version if the info is not available ([#728](https://github.com/appium/WebDriverAgent/issues/728)) ([e6e2dbd](https://github.com/appium/WebDriverAgent/commit/e6e2dbd86fc0c48ae146905f0e69a6223360e856))
|
|
7
|
+
|
|
8
|
+
## [5.4.0](https://github.com/appium/WebDriverAgent/compare/v5.3.3...v5.4.0) (2023-06-09)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* Drop older screenshoting APIs ([#721](https://github.com/appium/WebDriverAgent/issues/721)) ([4a08d7a](https://github.com/appium/WebDriverAgent/commit/4a08d7a843af6b93b378b4e3dc10f123d2e56359))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* Streamline errors handling for async block calls ([#725](https://github.com/appium/WebDriverAgent/issues/725)) ([364b779](https://github.com/appium/WebDriverAgent/commit/364b7791393ffae9c048c5cac023e3e7d1813a14))
|
|
19
|
+
|
|
20
|
+
## [5.3.3](https://github.com/appium/WebDriverAgent/compare/v5.3.2...v5.3.3) (2023-06-08)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Miscellaneous Chores
|
|
24
|
+
|
|
25
|
+
* Disable automatic screen recording by default ([#726](https://github.com/appium/WebDriverAgent/issues/726)) ([a070223](https://github.com/appium/WebDriverAgent/commit/a070223e0ef43be8dd54d16ee3e3b96603ad5f3a))
|
|
26
|
+
|
|
1
27
|
## [5.3.2](https://github.com/appium/WebDriverAgent/compare/v5.3.1...v5.3.2) (2023-06-07)
|
|
2
28
|
|
|
3
29
|
|
|
@@ -49,10 +49,14 @@ extern NSString *const FBSnapshotMaxDepthKey;
|
|
|
49
49
|
|
|
50
50
|
/*! Disables XCTest automated screenshots taking */
|
|
51
51
|
+ (void)disableScreenshots;
|
|
52
|
-
|
|
53
52
|
/*! Enables XCTest automated screenshots taking */
|
|
54
53
|
+ (void)enableScreenshots;
|
|
55
54
|
|
|
55
|
+
/*! Disables XCTest automated videos taking (iOS 17+) */
|
|
56
|
+
+ (void)disableScreenRecordings;
|
|
57
|
+
/*! Enables XCTest automated videos taking (iOS 17+) */
|
|
58
|
+
+ (void)enableScreenRecordings;
|
|
59
|
+
|
|
56
60
|
/* The maximum typing frequency for all typing activities */
|
|
57
61
|
+ (void)setMaxTypingFrequency:(NSUInteger)value;
|
|
58
62
|
+ (NSUInteger)maxTypingFrequency;
|
|
@@ -89,9 +93,9 @@ extern NSString *const FBSnapshotMaxDepthKey;
|
|
|
89
93
|
+ (void)setMjpegServerFramerate:(NSUInteger)framerate;
|
|
90
94
|
|
|
91
95
|
/**
|
|
92
|
-
The quality of
|
|
93
|
-
The highest quality value is 0 (lossless PNG). The lowest quality is 2 (highly compressed JPEG).
|
|
94
|
-
The default quality value is
|
|
96
|
+
The quality of display screenshots. The higher quality you set is the bigger screenshot size is.
|
|
97
|
+
The highest quality value is 0 (lossless PNG) or 3 (lossless HEIC). The lowest quality is 2 (highly compressed JPEG).
|
|
98
|
+
The default quality value is 3 (lossless HEIC).
|
|
95
99
|
See https://developer.apple.com/documentation/xctest/xctimagequality?language=objc
|
|
96
100
|
*/
|
|
97
101
|
+ (NSUInteger)screenshotQuality;
|
|
@@ -94,6 +94,16 @@ static UIInterfaceOrientation FBScreenshotOrientation;
|
|
|
94
94
|
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"DisableScreenshots"];
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
+ (void)disableScreenRecordings
|
|
98
|
+
{
|
|
99
|
+
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"DisableDiagnosticScreenRecordings"];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
+ (void)enableScreenRecordings
|
|
103
|
+
{
|
|
104
|
+
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"DisableDiagnosticScreenRecordings"];
|
|
105
|
+
}
|
|
106
|
+
|
|
97
107
|
+ (NSRange)bindingPortRange
|
|
98
108
|
{
|
|
99
109
|
// 'WebDriverAgent --port 8080' can be passed via the arguments to the process
|
|
@@ -443,7 +453,7 @@ static UIInterfaceOrientation FBScreenshotOrientation;
|
|
|
443
453
|
FBShouldUseCompactResponses = YES;
|
|
444
454
|
FBElementResponseAttributes = @"type,label";
|
|
445
455
|
FBMaxTypingFrequency = 60;
|
|
446
|
-
FBScreenshotQuality =
|
|
456
|
+
FBScreenshotQuality = 3;
|
|
447
457
|
FBCustomSnapshotTimeout = 15.;
|
|
448
458
|
FBShouldUseFirstMatch = NO;
|
|
449
459
|
FBShouldBoundElementsByIndex = NO;
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
#import <Foundation/Foundation.h>
|
|
11
11
|
#import <CoreGraphics/CoreGraphics.h>
|
|
12
12
|
|
|
13
|
+
@class UTType;
|
|
14
|
+
|
|
13
15
|
NS_ASSUME_NONNULL_BEGIN
|
|
14
16
|
|
|
15
17
|
// Those values define the allowed ranges for the scaling factor and compression quality settings
|
|
@@ -25,14 +27,12 @@ extern const CGFloat FBMaxCompressionQuality;
|
|
|
25
27
|
queue it will be replaced with the new one
|
|
26
28
|
|
|
27
29
|
@param image The image to scale down
|
|
28
|
-
@param uti Either kUTTypePNG or kUTTypeJPEG
|
|
29
30
|
@param completionHandler called after successfully scaling down an image
|
|
30
31
|
@param scalingFactor the scaling factor in range 0.01..1.0. A value of 1.0 won't perform scaling at all
|
|
31
32
|
@param compressionQuality the compression quality in range 0.0..1.0 (0.0 for max. compression and 1.0 for lossless compression)
|
|
32
|
-
Only applicable for
|
|
33
|
+
Only applicable for UTTypeJPEG
|
|
33
34
|
*/
|
|
34
35
|
- (void)submitImage:(NSData *)image
|
|
35
|
-
uti:(NSString *)uti
|
|
36
36
|
scalingFactor:(CGFloat)scalingFactor
|
|
37
37
|
compressionQuality:(CGFloat)compressionQuality
|
|
38
38
|
completionHandler:(void (^)(NSData *))completionHandler;
|
|
@@ -41,7 +41,7 @@ extern const CGFloat FBMaxCompressionQuality;
|
|
|
41
41
|
Scales and crops the source image
|
|
42
42
|
|
|
43
43
|
@param image The source image data
|
|
44
|
-
@param uti Either
|
|
44
|
+
@param uti Either UTTypePNG or UTTypeJPEG
|
|
45
45
|
@param rect The cropping rectange for the screenshot. The value is expected to be non-scaled one
|
|
46
46
|
since it happens after scaling/orientation change.
|
|
47
47
|
CGRectNull could be used to take a screenshot of the full screen.
|
|
@@ -52,7 +52,7 @@ extern const CGFloat FBMaxCompressionQuality;
|
|
|
52
52
|
@returns Processed image data compressed according to the given UTI or nil in case of a failure
|
|
53
53
|
*/
|
|
54
54
|
- (nullable NSData *)scaledImageWithImage:(NSData *)image
|
|
55
|
-
uti:(
|
|
55
|
+
uti:(UTType *)uti
|
|
56
56
|
rect:(CGRect)rect
|
|
57
57
|
scalingFactor:(CGFloat)scalingFactor
|
|
58
58
|
compressionQuality:(CGFloat)compressionQuality
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
#import <ImageIO/ImageIO.h>
|
|
13
13
|
#import <UIKit/UIKit.h>
|
|
14
|
-
|
|
14
|
+
@import UniformTypeIdentifiers;
|
|
15
15
|
|
|
16
16
|
#import "FBConfiguration.h"
|
|
17
17
|
#import "FBErrorBuilder.h"
|
|
@@ -43,7 +43,6 @@ const CGFloat FBMaxCompressionQuality = 1.0f;
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
- (void)submitImage:(NSData *)image
|
|
46
|
-
uti:(NSString *)uti
|
|
47
46
|
scalingFactor:(CGFloat)scalingFactor
|
|
48
47
|
compressionQuality:(CGFloat)compressionQuality
|
|
49
48
|
completionHandler:(void (^)(NSData *))completionHandler
|
|
@@ -118,7 +117,7 @@ const CGFloat FBMaxCompressionQuality = 1.0f;
|
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
- (nullable NSData *)scaledImageWithImage:(NSData *)image
|
|
121
|
-
uti:(
|
|
120
|
+
uti:(UTType *)uti
|
|
122
121
|
rect:(CGRect)rect
|
|
123
122
|
scalingFactor:(CGFloat)scalingFactor
|
|
124
123
|
compressionQuality:(CGFloat)compressionQuality
|
|
@@ -154,7 +153,7 @@ const CGFloat FBMaxCompressionQuality = 1.0f;
|
|
|
154
153
|
UIGraphicsEndImageContext();
|
|
155
154
|
}
|
|
156
155
|
|
|
157
|
-
return [uti
|
|
156
|
+
return [uti conformsToType:UTTypePNG]
|
|
158
157
|
? UIImagePNGRepresentation(resultImage)
|
|
159
158
|
: UIImageJPEGRepresentation(resultImage, compressionQuality);
|
|
160
159
|
}
|
|
@@ -163,7 +162,11 @@ const CGFloat FBMaxCompressionQuality = 1.0f;
|
|
|
163
162
|
compressionQuality:(CGFloat)compressionQuality
|
|
164
163
|
{
|
|
165
164
|
NSMutableData *newImageData = [NSMutableData data];
|
|
166
|
-
CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData(
|
|
165
|
+
CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData(
|
|
166
|
+
(__bridge CFMutableDataRef) newImageData,
|
|
167
|
+
(__bridge CFStringRef) UTTypeJPEG.identifier,
|
|
168
|
+
1,
|
|
169
|
+
NULL);
|
|
167
170
|
CFDictionaryRef compressionOptions = (__bridge CFDictionaryRef)@{
|
|
168
171
|
(const NSString *)kCGImageDestinationLossyCompressionQuality: @(compressionQuality)
|
|
169
172
|
};
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
#import "FBMjpegServer.h"
|
|
11
11
|
|
|
12
12
|
#import <mach/mach_time.h>
|
|
13
|
-
|
|
13
|
+
@import UniformTypeIdentifiers;
|
|
14
14
|
|
|
15
15
|
#import "GCDAsyncSocket.h"
|
|
16
16
|
#import "FBApplication.h"
|
|
@@ -72,11 +72,6 @@ static const char *QUEUE_NAME = "JPEG Screenshots Provider Queue";
|
|
|
72
72
|
|
|
73
73
|
- (void)streamScreenshot
|
|
74
74
|
{
|
|
75
|
-
if (![self.class canStreamScreenshots]) {
|
|
76
|
-
[FBLogger log:@"MJPEG server cannot start because the current iOS version is not supported"];
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
75
|
NSUInteger framerate = FBConfiguration.mjpegServerFramerate;
|
|
81
76
|
uint64_t timerInterval = (uint64_t)(1.0 / ((0 == framerate || framerate > MAX_FPS) ? MAX_FPS : framerate) * NSEC_PER_SEC);
|
|
82
77
|
uint64_t timeStarted = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW);
|
|
@@ -96,7 +91,7 @@ static const char *QUEUE_NAME = "JPEG Screenshots Provider Queue";
|
|
|
96
91
|
NSError *error;
|
|
97
92
|
NSData *screenshotData = [FBScreenshot takeInOriginalResolutionWithScreenID:self.mainScreenID
|
|
98
93
|
compressionQuality:screenshotCompressionQuality
|
|
99
|
-
uti:
|
|
94
|
+
uti:UTTypeJPEG
|
|
100
95
|
timeout:FRAME_TIMEOUT
|
|
101
96
|
error:&error];
|
|
102
97
|
if (nil == screenshotData) {
|
|
@@ -107,7 +102,6 @@ static const char *QUEUE_NAME = "JPEG Screenshots Provider Queue";
|
|
|
107
102
|
|
|
108
103
|
if (usesScaling) {
|
|
109
104
|
[self.imageScaler submitImage:screenshotData
|
|
110
|
-
uti:(__bridge id)kUTTypeJPEG
|
|
111
105
|
scalingFactor:scalingFactor
|
|
112
106
|
compressionQuality:compressionQuality
|
|
113
107
|
completionHandler:^(NSData * _Nonnull scaled) {
|
|
@@ -132,11 +126,6 @@ static const char *QUEUE_NAME = "JPEG Screenshots Provider Queue";
|
|
|
132
126
|
}
|
|
133
127
|
}
|
|
134
128
|
|
|
135
|
-
+ (BOOL)canStreamScreenshots
|
|
136
|
-
{
|
|
137
|
-
return [FBScreenshot isNewScreenshotAPISupported];
|
|
138
|
-
}
|
|
139
|
-
|
|
140
129
|
- (void)didClientConnect:(GCDAsyncSocket *)newClient
|
|
141
130
|
{
|
|
142
131
|
[FBLogger logFmt:@"Got screenshots broadcast client connection at %@:%d", newClient.connectedHost, newClient.connectedPort];
|
|
@@ -8,22 +8,18 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
#import <XCTest/XCTest.h>
|
|
11
|
+
@class UTType;
|
|
11
12
|
|
|
12
13
|
NS_ASSUME_NONNULL_BEGIN
|
|
13
14
|
|
|
14
15
|
@interface FBScreenshot : NSObject
|
|
15
16
|
|
|
16
|
-
/**
|
|
17
|
-
Returns YES if the current OS SDK supports advanced screenshoting APIs (added since Xcode SDK 10)
|
|
18
|
-
*/
|
|
19
|
-
+ (BOOL)isNewScreenshotAPISupported;
|
|
20
|
-
|
|
21
17
|
/**
|
|
22
18
|
Retrieves non-scaled screenshot of the whole screen
|
|
23
19
|
|
|
24
|
-
@param quality The number in range 0-
|
|
20
|
+
@param quality The number in range 0-3, where 0 is PNG (lossless), 3 is HEIC (lossless), 1- low quality JPEG and 2 - high quality JPEG
|
|
25
21
|
@param error If there is an error, upon return contains an NSError object that describes the problem.
|
|
26
|
-
@return Device screenshot as PNG-
|
|
22
|
+
@return Device screenshot as PNG-encoded data or nil in case of failure
|
|
27
23
|
*/
|
|
28
24
|
+ (nullable NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality
|
|
29
25
|
error:(NSError **)error;
|
|
@@ -31,11 +27,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
31
27
|
/**
|
|
32
28
|
Retrieves non-scaled screenshot of the particular screen rectangle
|
|
33
29
|
|
|
34
|
-
@param quality The number in range 0-
|
|
30
|
+
@param quality The number in range 0-3, where 0 is PNG (lossless), 3 is HEIC (lossless), 1- low quality JPEG and 2 - high quality JPEG
|
|
35
31
|
@param rect The bounding rectange for the screenshot. The value is expected be non-scaled one.
|
|
36
32
|
CGRectNull could be used to take a screenshot of the full screen.
|
|
37
33
|
@param error If there is an error, upon return contains an NSError object that describes the problem.
|
|
38
|
-
@return Device screenshot as PNG-
|
|
34
|
+
@return Device screenshot as PNG-encoded data or nil in case of failure
|
|
39
35
|
*/
|
|
40
36
|
+ (nullable NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality
|
|
41
37
|
rect:(CGRect)rect
|
|
@@ -46,14 +42,14 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
46
42
|
|
|
47
43
|
@param screenID The screen identifier to take the screenshot from
|
|
48
44
|
@param compressionQuality Normalized screenshot quality value in range 0..1, where 1 is the best quality
|
|
49
|
-
@param uti
|
|
45
|
+
@param uti UTType... constant, which defines the type of the returned screenshot image
|
|
50
46
|
@param timeout how much time to allow for the screenshot to be taken
|
|
51
47
|
@param error If there is an error, upon return contains an NSError object that describes the problem.
|
|
52
|
-
@return Device screenshot as PNG- or JPG-encoded data or nil in case of failure
|
|
48
|
+
@return Device screenshot as PNG-, HEIC- or JPG-encoded data or nil in case of failure
|
|
53
49
|
*/
|
|
54
50
|
+ (nullable NSData *)takeInOriginalResolutionWithScreenID:(long long)screenID
|
|
55
51
|
compressionQuality:(CGFloat)compressionQuality
|
|
56
|
-
uti:(
|
|
52
|
+
uti:(UTType *)uti
|
|
57
53
|
timeout:(NSTimeInterval)timeout
|
|
58
54
|
error:(NSError **)error;
|
|
59
55
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
#import "FBScreenshot.h"
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
@import UniformTypeIdentifiers;
|
|
13
13
|
|
|
14
14
|
#import "FBConfiguration.h"
|
|
15
15
|
#import "FBErrorBuilder.h"
|
|
@@ -33,16 +33,6 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
|
|
|
33
33
|
|
|
34
34
|
@implementation FBScreenshot
|
|
35
35
|
|
|
36
|
-
+ (BOOL)isNewScreenshotAPISupported
|
|
37
|
-
{
|
|
38
|
-
static dispatch_once_t newScreenshotAPISupported;
|
|
39
|
-
static BOOL result;
|
|
40
|
-
dispatch_once(&newScreenshotAPISupported, ^{
|
|
41
|
-
result = [(NSObject *)[FBXCTestDaemonsProxy testRunnerProxy] respondsToSelector:@selector(_XCT_requestScreenshotOfScreenWithID:withRect:uti:compressionQuality:withReply:)];
|
|
42
|
-
});
|
|
43
|
-
return result;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
36
|
+ (CGFloat)compressionQualityWithQuality:(NSUInteger)quality
|
|
47
37
|
{
|
|
48
38
|
switch (quality) {
|
|
@@ -55,14 +45,16 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
|
|
|
55
45
|
}
|
|
56
46
|
}
|
|
57
47
|
|
|
58
|
-
+ (
|
|
48
|
+
+ (UTType *)imageUtiWithQuality:(NSUInteger)quality
|
|
59
49
|
{
|
|
60
50
|
switch (quality) {
|
|
61
51
|
case 1:
|
|
62
52
|
case 2:
|
|
63
|
-
return
|
|
53
|
+
return UTTypeJPEG;
|
|
54
|
+
case 3:
|
|
55
|
+
return UTTypeHEIC;
|
|
64
56
|
default:
|
|
65
|
-
return
|
|
57
|
+
return UTTypePNG;
|
|
66
58
|
}
|
|
67
59
|
}
|
|
68
60
|
|
|
@@ -70,64 +62,28 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
|
|
|
70
62
|
rect:(CGRect)rect
|
|
71
63
|
error:(NSError **)error
|
|
72
64
|
{
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
error:error];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
[[[FBErrorBuilder builder]
|
|
84
|
-
withDescription:@"Screenshots of limited areas are only available for newer OS versions"]
|
|
85
|
-
buildError:error];
|
|
86
|
-
return nil;
|
|
65
|
+
XCUIScreen *mainScreen = XCUIScreen.mainScreen;
|
|
66
|
+
return [self.class takeWithScreenID:mainScreen.displayID
|
|
67
|
+
scale:SCREENSHOT_SCALE
|
|
68
|
+
compressionQuality:[self.class compressionQualityWithQuality:quality]
|
|
69
|
+
rect:rect
|
|
70
|
+
sourceUTI:[self.class imageUtiWithQuality:quality]
|
|
71
|
+
error:error];
|
|
87
72
|
}
|
|
88
73
|
|
|
89
74
|
+ (NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality
|
|
90
75
|
error:(NSError **)error
|
|
91
76
|
{
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
scale:SCREENSHOT_SCALE
|
|
96
|
-
compressionQuality:[self.class compressionQualityWithQuality:FBConfiguration.screenshotQuality]
|
|
97
|
-
rect:CGRectNull
|
|
98
|
-
sourceUTI:[self.class imageUtiWithQuality:FBConfiguration.screenshotQuality]
|
|
99
|
-
error:error];
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
id<XCTestManager_ManagerInterface> proxy = [FBXCTestDaemonsProxy testRunnerProxy];
|
|
103
|
-
__block NSData *screenshotData = nil;
|
|
104
|
-
__block NSError *innerError = nil;
|
|
105
|
-
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
|
|
106
|
-
[proxy _XCT_requestScreenshotWithReply:^(NSData *data, NSError *screenshotError) {
|
|
107
|
-
if (nil == screenshotError) {
|
|
108
|
-
screenshotData = data;
|
|
109
|
-
} else {
|
|
110
|
-
innerError = screenshotError;
|
|
111
|
-
}
|
|
112
|
-
dispatch_semaphore_signal(sem);
|
|
113
|
-
}];
|
|
114
|
-
if (nil != innerError && error) {
|
|
115
|
-
*error = innerError;
|
|
116
|
-
}
|
|
117
|
-
int64_t timeoutNs = (int64_t)(SCREENSHOT_TIMEOUT * NSEC_PER_SEC);
|
|
118
|
-
if (0 != dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, timeoutNs))) {
|
|
119
|
-
[[[FBErrorBuilder builder]
|
|
120
|
-
withDescription:[NSString stringWithFormat:@"Cannot take a screenshot within %@ timeout", formatTimeInterval(SCREENSHOT_TIMEOUT)]]
|
|
121
|
-
buildError:error];
|
|
122
|
-
};
|
|
123
|
-
return screenshotData;
|
|
77
|
+
return [self.class takeInOriginalResolutionWithQuality:quality
|
|
78
|
+
rect:CGRectNull
|
|
79
|
+
error:error];
|
|
124
80
|
}
|
|
125
81
|
|
|
126
82
|
+ (NSData *)takeWithScreenID:(long long)screenID
|
|
127
83
|
scale:(CGFloat)scale
|
|
128
84
|
compressionQuality:(CGFloat)compressionQuality
|
|
129
85
|
rect:(CGRect)rect
|
|
130
|
-
sourceUTI:(
|
|
86
|
+
sourceUTI:(UTType *)uti
|
|
131
87
|
error:(NSError **)error
|
|
132
88
|
{
|
|
133
89
|
NSData *screenshotData = [self.class takeInOriginalResolutionWithScreenID:screenID
|
|
@@ -139,7 +95,7 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
|
|
|
139
95
|
return nil;
|
|
140
96
|
}
|
|
141
97
|
return [[[FBImageIOScaler alloc] init] scaledImageWithImage:screenshotData
|
|
142
|
-
uti:
|
|
98
|
+
uti:UTTypePNG
|
|
143
99
|
rect:rect
|
|
144
100
|
scalingFactor:1.0 / scale
|
|
145
101
|
compressionQuality:FBMaxCompressionQuality
|
|
@@ -148,7 +104,7 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
|
|
|
148
104
|
|
|
149
105
|
+ (NSData *)takeInOriginalResolutionWithScreenID:(long long)screenID
|
|
150
106
|
compressionQuality:(CGFloat)compressionQuality
|
|
151
|
-
uti:(
|
|
107
|
+
uti:(UTType *)uti
|
|
152
108
|
timeout:(NSTimeInterval)timeout
|
|
153
109
|
error:(NSError **)error
|
|
154
110
|
{
|
|
@@ -156,38 +112,23 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
|
|
|
156
112
|
__block NSData *screenshotData = nil;
|
|
157
113
|
__block NSError *innerError = nil;
|
|
158
114
|
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
return nil;
|
|
167
|
-
}
|
|
168
|
-
[proxy _XCT_requestScreenshot:screnshotRequest
|
|
169
|
-
withReply:^(id image, NSError *err) {
|
|
170
|
-
if (nil != err) {
|
|
171
|
-
innerError = err;
|
|
172
|
-
} else {
|
|
173
|
-
screenshotData = [image data];
|
|
174
|
-
}
|
|
175
|
-
dispatch_semaphore_signal(sem);
|
|
176
|
-
}];
|
|
177
|
-
} else {
|
|
178
|
-
[proxy _XCT_requestScreenshotOfScreenWithID:screenID
|
|
179
|
-
withRect:CGRectNull
|
|
180
|
-
uti:uti
|
|
181
|
-
compressionQuality:compressionQuality
|
|
182
|
-
withReply:^(NSData *data, NSError *err) {
|
|
183
|
-
if (nil != err) {
|
|
184
|
-
innerError = err;
|
|
185
|
-
} else {
|
|
186
|
-
screenshotData = data;
|
|
187
|
-
}
|
|
188
|
-
dispatch_semaphore_signal(sem);
|
|
189
|
-
}];
|
|
115
|
+
id screnshotRequest = [self.class screenshotRequestWithScreenID:screenID
|
|
116
|
+
rect:CGRectNull
|
|
117
|
+
uti:uti
|
|
118
|
+
compressionQuality:compressionQuality
|
|
119
|
+
error:error];
|
|
120
|
+
if (nil == screnshotRequest) {
|
|
121
|
+
return nil;
|
|
190
122
|
}
|
|
123
|
+
[proxy _XCT_requestScreenshot:screnshotRequest
|
|
124
|
+
withReply:^(id image, NSError *err) {
|
|
125
|
+
if (nil != err) {
|
|
126
|
+
innerError = err;
|
|
127
|
+
} else {
|
|
128
|
+
screenshotData = [image data];
|
|
129
|
+
}
|
|
130
|
+
dispatch_semaphore_signal(sem);
|
|
131
|
+
}];
|
|
191
132
|
int64_t timeoutNs = (int64_t)(timeout * NSEC_PER_SEC);
|
|
192
133
|
if (0 != dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, timeoutNs))) {
|
|
193
134
|
NSString *timeoutMsg = [NSString stringWithFormat:@"Cannot take a screenshot within %@ timeout", formatTimeInterval(SCREENSHOT_TIMEOUT)];
|
|
@@ -205,26 +146,7 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
|
|
|
205
146
|
return screenshotData;
|
|
206
147
|
}
|
|
207
148
|
|
|
208
|
-
+ (
|
|
209
|
-
{
|
|
210
|
-
static dispatch_once_t shouldUseSRApi;
|
|
211
|
-
static BOOL result;
|
|
212
|
-
dispatch_once(&shouldUseSRApi, ^{
|
|
213
|
-
if ([proxy respondsToSelector:@selector(_XCT_requestScreenshot:withReply:)]) {
|
|
214
|
-
#if TARGET_OS_SIMULATOR
|
|
215
|
-
// Required to support simulators running iOS 14.4 and below with Xcode 12.5 and above due to unsupported API on the simulator side.
|
|
216
|
-
result = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.5");
|
|
217
|
-
#else
|
|
218
|
-
result = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0");
|
|
219
|
-
#endif
|
|
220
|
-
} else {
|
|
221
|
-
result = NO;
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
return result;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
+ (nullable id)imageEncodingWithUniformTypeIdentifier:(NSString *)uti
|
|
149
|
+
+ (nullable id)imageEncodingWithUniformTypeIdentifier:(UTType *)uti
|
|
228
150
|
compressionQuality:(CGFloat)compressionQuality
|
|
229
151
|
error:(NSError **)error
|
|
230
152
|
{
|
|
@@ -235,6 +157,26 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
|
|
|
235
157
|
buildError:error];
|
|
236
158
|
return nil;
|
|
237
159
|
}
|
|
160
|
+
|
|
161
|
+
if ([uti conformsToType:UTTypeHEIC]) {
|
|
162
|
+
static BOOL isHeicSuppported = NO;
|
|
163
|
+
static dispatch_once_t onceToken;
|
|
164
|
+
dispatch_once(&onceToken, ^{
|
|
165
|
+
SEL selector = NSSelectorFromString(@"supportsHEICImageEncoding");
|
|
166
|
+
NSMethodSignature *signature = [imageEncodingClass methodSignatureForSelector:selector];
|
|
167
|
+
if (nil != signature) {
|
|
168
|
+
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
|
169
|
+
[invocation setSelector:selector];
|
|
170
|
+
[invocation invokeWithTarget:imageEncodingClass];
|
|
171
|
+
[invocation getReturnValue:&isHeicSuppported];
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
if (!isHeicSuppported) {
|
|
175
|
+
[FBLogger logFmt:@"The device under test does not support HEIC image encoding. Falling back to PNG"];
|
|
176
|
+
uti = UTTypePNG;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
238
180
|
id imageEncodingAllocated = [imageEncodingClass alloc];
|
|
239
181
|
SEL imageEncodingConstructorSelector = NSSelectorFromString(@"initWithUniformTypeIdentifier:compressionQuality:");
|
|
240
182
|
if (![imageEncodingAllocated respondsToSelector:imageEncodingConstructorSelector]) {
|
|
@@ -246,7 +188,8 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
|
|
|
246
188
|
NSMethodSignature *imageEncodingContructorSignature = [imageEncodingAllocated methodSignatureForSelector:imageEncodingConstructorSelector];
|
|
247
189
|
NSInvocation *imageEncodingInitInvocation = [NSInvocation invocationWithMethodSignature:imageEncodingContructorSignature];
|
|
248
190
|
[imageEncodingInitInvocation setSelector:imageEncodingConstructorSelector];
|
|
249
|
-
|
|
191
|
+
NSString *utiIdentifier = uti.identifier;
|
|
192
|
+
[imageEncodingInitInvocation setArgument:&utiIdentifier atIndex:2];
|
|
250
193
|
[imageEncodingInitInvocation setArgument:&compressionQuality atIndex:3];
|
|
251
194
|
[imageEncodingInitInvocation invokeWithTarget:imageEncodingAllocated];
|
|
252
195
|
id __unsafe_unretained imageEncoding;
|
|
@@ -256,11 +199,10 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
|
|
|
256
199
|
|
|
257
200
|
+ (nullable id)screenshotRequestWithScreenID:(long long)screenID
|
|
258
201
|
rect:(struct CGRect)rect
|
|
259
|
-
uti:(
|
|
202
|
+
uti:(UTType *)uti
|
|
260
203
|
compressionQuality:(CGFloat)compressionQuality
|
|
261
204
|
error:(NSError **)error
|
|
262
205
|
{
|
|
263
|
-
// TODO: Use native accessors after we drop the support of Xcode 12.4 and below
|
|
264
206
|
id imageEncoding = [self.class imageEncodingWithUniformTypeIdentifier:uti
|
|
265
207
|
compressionQuality:compressionQuality
|
|
266
208
|
error:error];
|
|
@@ -100,13 +100,12 @@ static void swizzledLaunchApp(id self, SEL _cmd, NSString *path, NSString *bundl
|
|
|
100
100
|
|
|
101
101
|
+ (BOOL)synthesizeEventWithRecord:(XCSynthesizedEventRecord *)record error:(NSError *__autoreleasing*)error
|
|
102
102
|
{
|
|
103
|
-
__block
|
|
103
|
+
__block NSError *innerError = nil;
|
|
104
104
|
[FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){
|
|
105
105
|
void (^errorHandler)(NSError *) = ^(NSError *invokeError) {
|
|
106
|
-
if (
|
|
107
|
-
|
|
106
|
+
if (nil != invokeError) {
|
|
107
|
+
innerError = invokeError;
|
|
108
108
|
}
|
|
109
|
-
didSucceed = (invokeError == nil);
|
|
110
109
|
completion();
|
|
111
110
|
};
|
|
112
111
|
|
|
@@ -117,31 +116,40 @@ static void swizzledLaunchApp(id self, SEL _cmd, NSString *path, NSString *bundl
|
|
|
117
116
|
handlerBlock(record, invokeError);
|
|
118
117
|
}];
|
|
119
118
|
}];
|
|
120
|
-
|
|
119
|
+
if (nil != innerError) {
|
|
120
|
+
if (error) {
|
|
121
|
+
*error = innerError;
|
|
122
|
+
}
|
|
123
|
+
return NO;
|
|
124
|
+
}
|
|
125
|
+
return YES;
|
|
121
126
|
}
|
|
122
127
|
|
|
123
128
|
+ (BOOL)openURL:(NSURL *)url usingApplication:(NSString *)bundleId error:(NSError *__autoreleasing*)error
|
|
124
129
|
{
|
|
125
130
|
XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession];
|
|
126
131
|
if (![session respondsToSelector:@selector(openURL:usingApplication:completion:)]) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
buildError:error];
|
|
131
|
-
}
|
|
132
|
+
[[[FBErrorBuilder builder]
|
|
133
|
+
withDescriptionFormat:@"The current Xcode SDK does not support opening of URLs with given application"]
|
|
134
|
+
buildError:error];
|
|
132
135
|
return NO;
|
|
133
136
|
}
|
|
134
137
|
|
|
138
|
+
__block NSError *innerError = nil;
|
|
135
139
|
__block BOOL didSucceed = NO;
|
|
136
140
|
[FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){
|
|
137
141
|
[session openURL:url usingApplication:bundleId completion:^(bool result, NSError *invokeError) {
|
|
138
|
-
if (
|
|
139
|
-
|
|
142
|
+
if (nil != invokeError) {
|
|
143
|
+
innerError = invokeError;
|
|
144
|
+
} else {
|
|
145
|
+
didSucceed = result;
|
|
140
146
|
}
|
|
141
|
-
didSucceed = invokeError == nil && result;
|
|
142
147
|
completion();
|
|
143
148
|
}];
|
|
144
149
|
}];
|
|
150
|
+
if (nil != innerError && error) {
|
|
151
|
+
*error = innerError;
|
|
152
|
+
}
|
|
145
153
|
return didSucceed;
|
|
146
154
|
}
|
|
147
155
|
|
|
@@ -149,24 +157,27 @@ static void swizzledLaunchApp(id self, SEL _cmd, NSString *path, NSString *bundl
|
|
|
149
157
|
{
|
|
150
158
|
XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession];
|
|
151
159
|
if (![session respondsToSelector:@selector(openDefaultApplicationForURL:completion:)]) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
buildError:error];
|
|
156
|
-
}
|
|
160
|
+
[[[FBErrorBuilder builder]
|
|
161
|
+
withDescriptionFormat:@"The current Xcode SDK does not support opening of URLs. Consider upgrading to Xcode 14.3+/iOS 16.4+"]
|
|
162
|
+
buildError:error];
|
|
157
163
|
return NO;
|
|
158
164
|
}
|
|
159
165
|
|
|
166
|
+
__block NSError *innerError = nil;
|
|
160
167
|
__block BOOL didSucceed = NO;
|
|
161
168
|
[FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){
|
|
162
169
|
[session openDefaultApplicationForURL:url completion:^(bool result, NSError *invokeError) {
|
|
163
|
-
if (
|
|
164
|
-
|
|
170
|
+
if (nil != invokeError) {
|
|
171
|
+
innerError = invokeError;
|
|
172
|
+
} else {
|
|
173
|
+
didSucceed = result;
|
|
165
174
|
}
|
|
166
|
-
didSucceed = invokeError == nil && result;
|
|
167
175
|
completion();
|
|
168
176
|
}];
|
|
169
177
|
}];
|
|
178
|
+
if (nil != innerError && error) {
|
|
179
|
+
*error = innerError;
|
|
180
|
+
}
|
|
170
181
|
return didSucceed;
|
|
171
182
|
}
|
|
172
183
|
|
|
@@ -175,32 +186,33 @@ static void swizzledLaunchApp(id self, SEL _cmd, NSString *path, NSString *bundl
|
|
|
175
186
|
{
|
|
176
187
|
XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession];
|
|
177
188
|
if (![session respondsToSelector:@selector(setSimulatedLocation:completion:)]) {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
buildError:error];
|
|
182
|
-
}
|
|
189
|
+
[[[FBErrorBuilder builder]
|
|
190
|
+
withDescriptionFormat:@"The current Xcode SDK does not support location simulation. Consider upgrading to Xcode 14.3+/iOS 16.4+"]
|
|
191
|
+
buildError:error];
|
|
183
192
|
return NO;
|
|
184
193
|
}
|
|
185
194
|
if (![session supportsLocationSimulation]) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
buildError:error];
|
|
190
|
-
}
|
|
195
|
+
[[[FBErrorBuilder builder]
|
|
196
|
+
withDescriptionFormat:@"Your device does not support location simulation"]
|
|
197
|
+
buildError:error];
|
|
191
198
|
return NO;
|
|
192
199
|
}
|
|
193
200
|
|
|
201
|
+
__block NSError *innerError = nil;
|
|
194
202
|
__block BOOL didSucceed = NO;
|
|
195
203
|
[FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){
|
|
196
204
|
[session setSimulatedLocation:location completion:^(bool result, NSError *invokeError) {
|
|
197
|
-
if (
|
|
198
|
-
|
|
205
|
+
if (nil != invokeError) {
|
|
206
|
+
innerError = invokeError;
|
|
207
|
+
} else {
|
|
208
|
+
didSucceed = result;
|
|
199
209
|
}
|
|
200
|
-
didSucceed = invokeError == nil && result;
|
|
201
210
|
completion();
|
|
202
211
|
}];
|
|
203
212
|
}];
|
|
213
|
+
if (nil != innerError && error) {
|
|
214
|
+
*error = innerError;
|
|
215
|
+
}
|
|
204
216
|
return didSucceed;
|
|
205
217
|
}
|
|
206
218
|
|
|
@@ -208,34 +220,33 @@ static void swizzledLaunchApp(id self, SEL _cmd, NSString *path, NSString *bundl
|
|
|
208
220
|
{
|
|
209
221
|
XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession];
|
|
210
222
|
if (![session respondsToSelector:@selector(getSimulatedLocationWithReply:)]) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
buildError:error];
|
|
215
|
-
}
|
|
223
|
+
[[[FBErrorBuilder builder]
|
|
224
|
+
withDescriptionFormat:@"The current Xcode SDK does not support location simulation. Consider upgrading to Xcode 14.3+/iOS 16.4+"]
|
|
225
|
+
buildError:error];
|
|
216
226
|
return nil;
|
|
217
227
|
}
|
|
218
228
|
if (![session supportsLocationSimulation]) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
buildError:error];
|
|
223
|
-
}
|
|
229
|
+
[[[FBErrorBuilder builder]
|
|
230
|
+
withDescriptionFormat:@"Your device does not support location simulation"]
|
|
231
|
+
buildError:error];
|
|
224
232
|
return nil;
|
|
225
233
|
}
|
|
226
234
|
|
|
235
|
+
__block NSError *innerError = nil;
|
|
227
236
|
__block CLLocation *location = nil;
|
|
228
237
|
[FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){
|
|
229
238
|
[session getSimulatedLocationWithReply:^(CLLocation *reply, NSError *invokeError) {
|
|
230
|
-
if (
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
if (nil == invokeError) {
|
|
239
|
+
if (nil != invokeError) {
|
|
240
|
+
innerError = invokeError;
|
|
241
|
+
} else {
|
|
234
242
|
location = reply;
|
|
235
243
|
}
|
|
236
244
|
completion();
|
|
237
245
|
}];
|
|
238
246
|
}];
|
|
247
|
+
if (nil != innerError && error) {
|
|
248
|
+
*error = innerError;
|
|
249
|
+
}
|
|
239
250
|
return location;
|
|
240
251
|
}
|
|
241
252
|
|
|
@@ -259,16 +270,21 @@ static void swizzledLaunchApp(id self, SEL _cmd, NSString *path, NSString *bundl
|
|
|
259
270
|
return NO;
|
|
260
271
|
}
|
|
261
272
|
|
|
273
|
+
__block NSError *innerError = nil;
|
|
262
274
|
__block BOOL didSucceed = NO;
|
|
263
275
|
[FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){
|
|
264
276
|
[session clearSimulatedLocationWithReply:^(bool result, NSError *invokeError) {
|
|
265
|
-
if (
|
|
266
|
-
|
|
277
|
+
if (nil != invokeError) {
|
|
278
|
+
innerError = invokeError;
|
|
279
|
+
} else {
|
|
280
|
+
didSucceed = result;
|
|
267
281
|
}
|
|
268
|
-
didSucceed = invokeError == nil && result;
|
|
269
282
|
completion();
|
|
270
283
|
}];
|
|
271
284
|
}];
|
|
285
|
+
if (nil != innerError && error) {
|
|
286
|
+
*error = innerError;
|
|
287
|
+
}
|
|
272
288
|
return didSucceed;
|
|
273
289
|
}
|
|
274
290
|
#endif
|
|
@@ -123,12 +123,16 @@ NSInteger FBTestmanagerdVersion(void)
|
|
|
123
123
|
static NSInteger testmanagerdVersion;
|
|
124
124
|
dispatch_once(&getTestmanagerdVersion, ^{
|
|
125
125
|
id<XCTestManager_ManagerInterface> proxy = [FBXCTestDaemonsProxy testRunnerProxy];
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
if ([(NSObject *)proxy respondsToSelector:@selector(_XCT_exchangeProtocolVersion:reply:)]) {
|
|
127
|
+
[FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){
|
|
128
|
+
[proxy _XCT_exchangeProtocolVersion:testmanagerdVersion reply:^(unsigned long long code) {
|
|
129
|
+
testmanagerdVersion = (NSInteger) code;
|
|
130
|
+
completion();
|
|
131
|
+
}];
|
|
132
|
+
}];
|
|
133
|
+
} else {
|
|
134
|
+
testmanagerdVersion = 0xFFFF;
|
|
135
|
+
}
|
|
132
136
|
});
|
|
133
137
|
return testmanagerdVersion;
|
|
134
138
|
}
|
|
@@ -26,6 +26,11 @@
|
|
|
26
26
|
[FBConfiguration disableRemoteQueryEvaluation];
|
|
27
27
|
[FBConfiguration configureDefaultKeyboardPreferences];
|
|
28
28
|
[FBConfiguration disableApplicationUIInterruptionsHandling];
|
|
29
|
+
if (NSProcessInfo.processInfo.environment[@"ENABLE_AUTOMATIC_SCREEN_RECORDINGS"]) {
|
|
30
|
+
[FBConfiguration enableScreenRecordings];
|
|
31
|
+
} else {
|
|
32
|
+
[FBConfiguration disableScreenRecordings];
|
|
33
|
+
}
|
|
29
34
|
if (NSProcessInfo.processInfo.environment[@"ENABLE_AUTOMATIC_SCREENSHOTS"]) {
|
|
30
35
|
[FBConfiguration enableScreenshots];
|
|
31
36
|
} else {
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
#import <XCTest/XCTest.h>
|
|
11
|
-
#import <MobileCoreServices/MobileCoreServices.h>
|
|
12
11
|
|
|
13
12
|
#import "FBImageIOScaler.h"
|
|
14
13
|
#import "FBIntegrationTestCase.h"
|
|
@@ -55,7 +54,6 @@
|
|
|
55
54
|
id expScaled = [self expectationWithDescription:@"Receive scaled image"];
|
|
56
55
|
|
|
57
56
|
[scaler submitImage:self.originalImage
|
|
58
|
-
uti:(__bridge id)kUTTypeJPEG
|
|
59
57
|
scalingFactor:scalingFactor
|
|
60
58
|
compressionQuality:1.0
|
|
61
59
|
completionHandler:^(NSData *scaled) {
|