Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add a possibility to trigger IO HID events #494

Merged
merged 1 commit into from
Apr 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion PrivateHeaders/XCTest/XCUIDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
@property (readonly) id accessibilityInterface; // implements XCUIAccessibilityInterface
@property (readonly) id eventSynthesizer; // implements XCUIEventSynthesizing
@property(readonly) id screenDataSource; // @synthesize screenDataSource=_screenDataSource;

- (_Bool)performDeviceEvent:(id)arg1 error:(id *)arg2;

- (void)pressLockButton;
- (void)holdHomeButtonForDuration:(double)arg1;
- (void)_silentPressButton:(long long)arg1;
// Removed in Xcode 10.2
- (void)_dispatchEventWithPage:(unsigned int)arg1 usage:(unsigned int)arg2 duration:(double)arg3;

@end
22 changes: 22 additions & 0 deletions WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,28 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (BOOL)fb_activateSiriVoiceRecognitionWithText:(NSString *)text error:(NSError **)error;

/**
Eumlated triggering of the given low-level IOHID device event. The constants for possible events are defined
in https://unix.superglobalmegacorp.com/xnu/newsrc/iokit/IOKit/hidsystem/IOHIDUsageTables.h.html
Popular constants:
- kHIDPage_Consumer = 0x0C
- kHIDUsage_Csmr_VolumeIncrement = 0xE9 (Volume Up)
- kHIDUsage_Csmr_VolumeDecrement = 0xEA (Volume Down)
- kHIDUsage_Csmr_Menu = 0x40 (Home)
- kHIDUsage_Csmr_Power = 0x30 (Power)
- kHIDUsage_Csmr_Snapshot = 0x65 (Power + Home)

@param page The event page identifier
@param usage The event usage indentifier (usages are defined per-page)
@param duration The event duration in float seconds (XCTest uses 0.005 for a single press event)
@param error If there is an error, upon return contains an NSError object that describes the problem.
@return YES the event has successfully been triggered
*/
- (BOOL)fb_performIOHIDEventWithPage:(unsigned int)page
usage:(unsigned int)usage
duration:(NSTimeInterval)duration
error:(NSError **)error;

@end

NS_ASSUME_NONNULL_END
12 changes: 12 additions & 0 deletions WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#import "FBScreenshot.h"
#import "FBXCodeCompatibility.h"
#import "XCUIDevice.h"
#import "XCDeviceEvent.h"

static const NSTimeInterval FBHomeButtonCoolOffTime = 1.;
static const NSTimeInterval FBScreenLockTimeout = 5.;
Expand Down Expand Up @@ -282,4 +283,15 @@ - (BOOL)fb_pressButton:(NSString *)buttonName error:(NSError **)error
}
#endif

- (BOOL)fb_performIOHIDEventWithPage:(unsigned int)page
usage:(unsigned int)usage
duration:(NSTimeInterval)duration
error:(NSError **)error
{
XCDeviceEvent *event = [XCDeviceEvent deviceEventWithPage:page
usage:usage
duration:duration];
return [self performDeviceEvent:event error:error];
}

@end
17 changes: 17 additions & 0 deletions WebDriverAgentLib/Commands/FBCustomCommands.m
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ + (NSArray *)routes
[[FBRoute GET:@"/wda/batteryInfo"] respondWithTarget:self action:@selector(handleGetBatteryInfo:)],
#endif
[[FBRoute POST:@"/wda/pressButton"] respondWithTarget:self action:@selector(handlePressButtonCommand:)],
[[FBRoute POST:@"/wda/performIoHidEvent"] respondWithTarget:self action:@selector(handlePeformIOHIDEvent:)],
[[FBRoute POST:@"/wda/expectNotification"] respondWithTarget:self action:@selector(handleExpectNotification:)],
[[FBRoute POST:@"/wda/siri/activate"] respondWithTarget:self action:@selector(handleActivateSiri:)],
[[FBRoute POST:@"/wda/apps/launchUnattached"].withoutSession respondWithTarget:self action:@selector(handleLaunchUnattachedApp:)],
Expand Down Expand Up @@ -257,6 +258,22 @@ + (NSDictionary *)processArguments:(XCUIApplication *)app
return FBResponseWithOK();
}

+ (id <FBResponsePayload>)handlePeformIOHIDEvent:(FBRouteRequest *)request
{
NSNumber *page = request.arguments[@"page"];
NSNumber *usage = request.arguments[@"usage"];
NSNumber *duration = request.arguments[@"duration"];
NSError *error;
if (![XCUIDevice.sharedDevice fb_performIOHIDEventWithPage:page.unsignedIntValue
usage:usage.unsignedIntValue
duration:duration.doubleValue
error:&error]) {
return FBResponseWithStatus([FBCommandStatus unknownErrorWithMessage:error.description
traceback:nil]);
}
return FBResponseWithOK();
}

+ (id <FBResponsePayload>)handleLaunchUnattachedApp:(FBRouteRequest *)request
{
NSString *bundle = (NSString *)request.arguments[@"bundleId"];
Expand Down
12 changes: 12 additions & 0 deletions WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,16 @@ - (void)testPressingSupportedButton
XCTAssertNil(error);
}

- (void)testLongPressHomeButton
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

{
NSError *error;
// kHIDPage_Consumer = 0x0C
// kHIDUsage_Csmr_Menu = 0x40
XCTAssertTrue([XCUIDevice.sharedDevice fb_performIOHIDEventWithPage:0x0C
usage:0x40
duration:1.0
error:&error]);
XCTAssertNil(error);
}

@end