forked from facebookarchive/WebDriverAgent
-
Notifications
You must be signed in to change notification settings - Fork 392
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add wrappers for native XCTest video recorder (#858)
- Loading branch information
1 parent
89880f5
commit 9728548
Showing
14 changed files
with
663 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/** | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
|
||
#import <Foundation/Foundation.h> | ||
|
||
#import <WebDriverAgentLib/FBCommandHandler.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface FBVideoCommands : NSObject <FBCommandHandler> | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/** | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
|
||
#import "FBVideoCommands.h" | ||
|
||
#import "FBRouteRequest.h" | ||
#import "FBScreenRecordingContainer.h" | ||
#import "FBScreenRecordingPromise.h" | ||
#import "FBScreenRecordingRequest.h" | ||
#import "FBSession.h" | ||
#import "FBXCTestDaemonsProxy.h" | ||
|
||
const NSUInteger DEFAULT_FPS = 24; | ||
const NSUInteger DEFAULT_CODEC = 0; | ||
|
||
@implementation FBVideoCommands | ||
|
||
+ (NSArray *)routes | ||
{ | ||
return | ||
@[ | ||
[[FBRoute POST:@"/wda/video/start"] respondWithTarget:self action:@selector(handleStartVideoRecording:)], | ||
[[FBRoute POST:@"/wda/video/stop"] respondWithTarget:self action:@selector(handleStopVideoRecording:)], | ||
[[FBRoute GET:@"/wda/video"] respondWithTarget:self action:@selector(handleGetVideoRecording:)], | ||
|
||
[[FBRoute POST:@"/wda/video/start"].withoutSession respondWithTarget:self action:@selector(handleStartVideoRecording:)], | ||
[[FBRoute POST:@"/wda/video/stop"].withoutSession respondWithTarget:self action:@selector(handleStopVideoRecording:)], | ||
[[FBRoute GET:@"/wda/video"].withoutSession respondWithTarget:self action:@selector(handleGetVideoRecording:)], | ||
]; | ||
} | ||
|
||
+ (id<FBResponsePayload>)handleStartVideoRecording:(FBRouteRequest *)request | ||
{ | ||
FBScreenRecordingPromise *activeScreenRecording = FBScreenRecordingContainer.sharedInstance.screenRecordingPromise; | ||
if (nil != activeScreenRecording) { | ||
return FBResponseWithObject([FBScreenRecordingContainer.sharedInstance toDictionary] ?: [NSNull null]); | ||
} | ||
|
||
NSNumber *fps = (NSNumber *)request.arguments[@"fps"] ?: @(DEFAULT_FPS); | ||
NSNumber *codec = (NSNumber *)request.arguments[@"codec"] ?: @(DEFAULT_CODEC); | ||
FBScreenRecordingRequest *recordingRequest = [[FBScreenRecordingRequest alloc] initWithFps:fps.integerValue | ||
codec:codec.longLongValue]; | ||
NSError *error; | ||
FBScreenRecordingPromise* promise = [FBXCTestDaemonsProxy startScreenRecordingWithRequest:recordingRequest | ||
error:&error]; | ||
if (nil == promise) { | ||
[FBScreenRecordingContainer.sharedInstance reset]; | ||
return FBResponseWithUnknownError(error); | ||
} | ||
[FBScreenRecordingContainer.sharedInstance storeScreenRecordingPromise:promise | ||
fps:fps.integerValue | ||
codec:codec.longLongValue]; | ||
return FBResponseWithObject([FBScreenRecordingContainer.sharedInstance toDictionary]); | ||
} | ||
|
||
+ (id<FBResponsePayload>)handleStopVideoRecording:(FBRouteRequest *)request | ||
{ | ||
FBScreenRecordingPromise *activeScreenRecording = FBScreenRecordingContainer.sharedInstance.screenRecordingPromise; | ||
if (nil == activeScreenRecording) { | ||
return FBResponseWithOK(); | ||
} | ||
|
||
NSUUID *recordingId = activeScreenRecording.identifier; | ||
NSDictionary *response = [FBScreenRecordingContainer.sharedInstance toDictionary]; | ||
NSError *error; | ||
if (![FBXCTestDaemonsProxy stopScreenRecordingWithUUID:recordingId error:&error]) { | ||
[FBScreenRecordingContainer.sharedInstance reset]; | ||
return FBResponseWithUnknownError(error); | ||
} | ||
[FBScreenRecordingContainer.sharedInstance reset]; | ||
return FBResponseWithObject(response); | ||
} | ||
|
||
+ (id<FBResponsePayload>)handleGetVideoRecording:(FBRouteRequest *)request | ||
{ | ||
return FBResponseWithObject([FBScreenRecordingContainer.sharedInstance toDictionary] ?: [NSNull null]); | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/** | ||
* | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
|
||
#import <Foundation/Foundation.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@class FBScreenRecordingPromise; | ||
|
||
@interface FBScreenRecordingContainer : NSObject | ||
|
||
/** The amount of video FPS */ | ||
@property (readonly, nonatomic) NSUInteger fps; | ||
/** Codec to use, where 0 is h264, 1 - HEVC */ | ||
@property (readonly, nonatomic) long long codec; | ||
/** Keep the currently active screen resording promise. Equals to nil if no active screen recordings are running */ | ||
@property (readonly, nonatomic, nullable) FBScreenRecordingPromise* screenRecordingPromise; | ||
/** The timestamp of the video startup as Unix float seconds */ | ||
@property (readonly, nonatomic, nullable) NSNumber *startedAt; | ||
|
||
/** | ||
@return singleton instance | ||
*/ | ||
+ (instancetype)sharedInstance; | ||
|
||
/** | ||
Keeps current screen recording promise | ||
@param screenRecordingPromise a promise to set | ||
@param fps FPS value | ||
@param codec Codec value | ||
*/ | ||
- (void)storeScreenRecordingPromise:(FBScreenRecordingPromise *)screenRecordingPromise | ||
fps:(NSUInteger)fps | ||
codec:(long long)codec; | ||
/** | ||
Resets the current screen recording promise | ||
*/ | ||
- (void)reset; | ||
|
||
/** | ||
Transforms the container content to a dictionary. | ||
@return May return nil if no screen recording is currently running | ||
*/ | ||
- (nullable NSDictionary *)toDictionary; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/** | ||
* | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
|
||
#import "FBScreenRecordingContainer.h" | ||
|
||
#import "FBScreenRecordingPromise.h" | ||
|
||
@interface FBScreenRecordingContainer () | ||
|
||
@property (readwrite) NSUInteger fps; | ||
@property (readwrite) long long codec; | ||
@property (readwrite) FBScreenRecordingPromise* screenRecordingPromise; | ||
@property (readwrite) NSNumber *startedAt; | ||
|
||
@end | ||
|
||
@implementation FBScreenRecordingContainer | ||
|
||
+ (instancetype)sharedInstance | ||
{ | ||
static FBScreenRecordingContainer *instance; | ||
static dispatch_once_t onceToken; | ||
dispatch_once(&onceToken, ^{ | ||
instance = [[self alloc] init]; | ||
}); | ||
return instance; | ||
} | ||
|
||
- (void)storeScreenRecordingPromise:(FBScreenRecordingPromise *)screenRecordingPromise | ||
fps:(NSUInteger)fps | ||
codec:(long long)codec; | ||
{ | ||
self.fps = fps; | ||
self.codec = codec; | ||
self.screenRecordingPromise = screenRecordingPromise; | ||
self.startedAt = @([NSDate.date timeIntervalSince1970]); | ||
} | ||
|
||
- (void)reset; | ||
{ | ||
self.fps = 0; | ||
self.codec = 0; | ||
if (nil != self.screenRecordingPromise) { | ||
[XCTContext runActivityNamed:@"Video Cleanup" block:^(id<XCTActivity> activity){ | ||
[activity addAttachment:(XCTAttachment *)self.screenRecordingPromise.nativePromise]; | ||
}]; | ||
self.screenRecordingPromise = nil; | ||
} | ||
self.startedAt = nil; | ||
} | ||
|
||
- (nullable NSDictionary *)toDictionary | ||
{ | ||
if (nil == self.screenRecordingPromise) { | ||
return nil; | ||
} | ||
|
||
return @{ | ||
@"fps": @(self.fps), | ||
@"codec": @(self.codec), | ||
@"uuid": [self.screenRecordingPromise identifier].UUIDString ?: [NSNull null], | ||
@"startedAt": self.startedAt ?: [NSNull null], | ||
}; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
|
||
#import <XCTest/XCTest.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface FBScreenRecordingPromise : NSObject | ||
|
||
/** Unique identiifier of the video recording, also used as the default file name */ | ||
@property (nonatomic, readonly) NSUUID *identifier; | ||
/** Native screen recording promise */ | ||
@property (nonatomic, readonly) id nativePromise; | ||
|
||
/** | ||
Creates a wrapper object for a native screen recording promise | ||
@param promise Native promise object to be wrapped | ||
*/ | ||
- (instancetype)initWithNativePromise:(id)promise; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/** | ||
* | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
|
||
#import "FBScreenRecordingPromise.h" | ||
|
||
@interface FBScreenRecordingPromise () | ||
@property (readwrite) id nativePromise; | ||
@end | ||
|
||
@implementation FBScreenRecordingPromise | ||
|
||
- (instancetype)initWithNativePromise:(id)promise | ||
{ | ||
if ((self = [super init])) { | ||
self.nativePromise = promise; | ||
} | ||
return self; | ||
} | ||
|
||
- (NSUUID *)identifier | ||
{ | ||
return (NSUUID *)[self.nativePromise valueForKey:@"_UUID"]; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
|
||
#import <XCTest/XCTest.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface FBScreenRecordingRequest : NSObject | ||
|
||
/** The amount of video FPS */ | ||
@property (readonly, nonatomic) NSUInteger fps; | ||
/** Codec to use, where 0 is h264, 1 - HEVC */ | ||
@property (readonly, nonatomic) long long codec; | ||
|
||
/** | ||
Creates a custom wrapper for a screen recording reqeust | ||
@param fps FPS value, see baove | ||
@param codec Codex value, see above | ||
*/ | ||
- (instancetype)initWithFps:(NSUInteger)fps codec:(long long)codec; | ||
|
||
/** | ||
Transforms the current wrapper instance to a native object, | ||
which is ready to be passed to XCTest APIs | ||
@param error If there was a failure converting the instance to a native object | ||
@returns Native object instance | ||
*/ | ||
- (nullable id)toNativeRequestWithError:(NSError **)error; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
Oops, something went wrong.