/** * 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 "FBCustomCommands.h" #import #import "FBApplication.h" #import "FBConfiguration.h" #import "FBExceptionHandler.h" #import "FBKeyboard.h" #import "FBResponsePayload.h" #import "FBRoute.h" #import "FBRouteRequest.h" #import "FBRunLoopSpinner.h" #import "FBSession.h" #import "FBXCodeCompatibility.h" #import "FBSpringboardApplication.h" #import "XCUIApplication+FBHelpers.h" #import "XCUIDevice+FBHelpers.h" #import "XCUIElement.h" #import "XCUIElement+FBIsVisible.h" #import "XCUIElementQuery.h" @implementation FBCustomCommands + (NSArray *)routes { return @[ [[FBRoute POST:@"/timeouts"] respondWithTarget:self action:@selector(handleTimeouts:)], [[FBRoute POST:@"/wda/homescreen"].withoutSession respondWithTarget:self action:@selector(handleHomescreenCommand:)], [[FBRoute POST:@"/wda/deactivateApp"] respondWithTarget:self action:@selector(handleDeactivateAppCommand:)], [[FBRoute POST:@"/wda/keyboard/dismiss"] respondWithTarget:self action:@selector(handleDismissKeyboardCommand:)], [[FBRoute GET:@"/wda/elementCache/size"] respondWithTarget:self action:@selector(handleGetElementCacheSizeCommand:)], [[FBRoute POST:@"/wda/elementCache/clear"] respondWithTarget:self action:@selector(handleClearElementCacheCommand:)], ]; } #pragma mark - Commands + (id)handleHomescreenCommand:(FBRouteRequest *)request { NSError *error; if (![[XCUIDevice sharedDevice] fb_goToHomescreenWithError:&error]) { return FBResponseWithError(error); } return FBResponseWithOK(); } + (id)handleDeactivateAppCommand:(FBRouteRequest *)request { NSNumber *requestedDuration = request.arguments[@"duration"]; NSTimeInterval duration = (requestedDuration ? requestedDuration.doubleValue : 3.); NSError *error; if (![request.session.application fb_deactivateWithDuration:duration error:&error]) { return FBResponseWithError(error); } return FBResponseWithOK(); } + (id)handleTimeouts:(FBRouteRequest *)request { // This method is intentionally not supported. return FBResponseWithOK(); } + (id)handleDismissKeyboardCommand:(FBRouteRequest *)request { [request.session.application dismissKeyboard]; NSError *error; NSString *errorDescription = @"The keyboard cannot be dismissed. Try to dismiss it in the way supported by your application under test."; if ([UIDevice.currentDevice userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { errorDescription = @"The keyboard on iPhone cannot be dismissed because of a known XCTest issue. Try to dismiss it in the way supported by your application under test."; } BOOL isKeyboardNotPresent = [[[[FBRunLoopSpinner new] timeout:5] timeoutErrorMessage:errorDescription] spinUntilTrue:^BOOL{ XCUIElement *foundKeyboard = [[FBApplication fb_activeApplication].query descendantsMatchingType:XCUIElementTypeKeyboard].fb_firstMatch; return !(foundKeyboard && foundKeyboard.fb_isVisible); } error:&error]; if (!isKeyboardNotPresent) { return FBResponseWithError(error); } return FBResponseWithOK(); } + (id)handleGetElementCacheSizeCommand:(FBRouteRequest *)request { NSNumber *count = [NSNumber numberWithUnsignedInteger:[request.session.elementCache count]]; return FBResponseWithObject(count); } + (id)handleClearElementCacheCommand:(FBRouteRequest *)request { FBElementCache *elementCache = request.session.elementCache; [elementCache clear]; return FBResponseWithOK(); } @end