FBKeyboard.m 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /**
  2. * Copyright (c) 2015-present, Facebook, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. */
  9. #import "FBKeyboard.h"
  10. #import "FBApplication.h"
  11. #import "FBConfiguration.h"
  12. #import "FBXCTestDaemonsProxy.h"
  13. #import "FBErrorBuilder.h"
  14. #import "FBRunLoopSpinner.h"
  15. #import "FBMacros.h"
  16. #import "FBXCodeCompatibility.h"
  17. #import "XCUIElement+FBUtilities.h"
  18. #import "XCUIElement+FBIsVisible.h"
  19. #import "XCTestDriver.h"
  20. #import "FBLogger.h"
  21. #import "FBConfiguration.h"
  22. @implementation FBKeyboard
  23. + (BOOL)typeText:(NSString *)text error:(NSError **)error
  24. {
  25. return [self typeText:text frequency:[FBConfiguration maxTypingFrequency] error:error];
  26. }
  27. + (BOOL)typeText:(NSString *)text frequency:(NSUInteger)frequency error:(NSError **)error
  28. {
  29. __block BOOL didSucceed = NO;
  30. __block NSError *innerError;
  31. [FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){
  32. [[FBXCTestDaemonsProxy testRunnerProxy]
  33. _XCT_sendString:text
  34. maximumFrequency:frequency
  35. completion:^(NSError *typingError){
  36. didSucceed = (typingError == nil);
  37. innerError = typingError;
  38. completion();
  39. }];
  40. }];
  41. if (error) {
  42. *error = innerError;
  43. }
  44. return didSucceed;
  45. }
  46. + (BOOL)waitUntilVisibleForApplication:(XCUIApplication *)app timeout:(NSTimeInterval)timeout error:(NSError **)error
  47. {
  48. BOOL (^isKeyboardVisible)(void) = ^BOOL(void) {
  49. if (!app.keyboard.exists) {
  50. return NO;
  51. }
  52. NSPredicate *keySearchPredicate = [NSPredicate predicateWithBlock:^BOOL(id<FBXCElementSnapshot> snapshot,
  53. NSDictionary *bindings) {
  54. return snapshot.label.length > 0;
  55. }];
  56. XCUIElement *firstKey = [[app.keyboard descendantsMatchingType:XCUIElementTypeKey]
  57. matchingPredicate:keySearchPredicate].allElementsBoundByIndex.firstObject;
  58. return firstKey.exists && firstKey.hittable;
  59. };
  60. NSString* errMessage = @"The on-screen keyboard must be present to send keys";
  61. if (timeout <= 0) {
  62. if (!isKeyboardVisible()) {
  63. return [[[FBErrorBuilder builder] withDescription:errMessage] buildError:error];
  64. }
  65. return YES;
  66. }
  67. return
  68. [[[[FBRunLoopSpinner new]
  69. timeout:timeout]
  70. timeoutErrorMessage:errMessage]
  71. spinUntilTrue:isKeyboardVisible
  72. error:error];
  73. }
  74. @end