XCUIElement+FBIsVisible.m 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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 "XCUIElement+FBIsVisible.h"
  10. #import "FBElementUtils.h"
  11. #import "FBXCodeCompatibility.h"
  12. #import "FBXCElementSnapshotWrapper+Helpers.h"
  13. #import "XCUIElement+FBUtilities.h"
  14. #import "XCUIElement+FBVisibleFrame.h"
  15. #import "XCTestPrivateSymbols.h"
  16. NSNumber* _Nullable fetchSnapshotVisibility(id<FBXCElementSnapshot> snapshot)
  17. {
  18. return nil == snapshot.additionalAttributes ? nil : snapshot.additionalAttributes[FB_XCAXAIsVisibleAttribute];
  19. }
  20. @implementation XCUIElement (FBIsVisible)
  21. - (BOOL)fb_isVisible
  22. {
  23. @autoreleasepool {
  24. id<FBXCElementSnapshot> snapshot = [self fb_standardSnapshot];
  25. return [FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_isVisible;
  26. }
  27. }
  28. @end
  29. @implementation FBXCElementSnapshotWrapper (FBIsVisible)
  30. - (BOOL)fb_hasVisibleDescendants
  31. {
  32. for (id<FBXCElementSnapshot> descendant in (self._allDescendants ?: @[])) {
  33. if ([fetchSnapshotVisibility(descendant) boolValue]) {
  34. return YES;
  35. }
  36. }
  37. return NO;
  38. }
  39. - (BOOL)fb_isVisible
  40. {
  41. NSNumber *isVisible = fetchSnapshotVisibility(self);
  42. if (nil != isVisible) {
  43. return isVisible.boolValue;
  44. }
  45. // Fetching the attribute value is expensive.
  46. // Shortcircuit here to save time and assume if any of descendants
  47. // is already determined as visible then the container should be visible as well
  48. if ([self fb_hasVisibleDescendants]) {
  49. return YES;
  50. }
  51. NSError *error;
  52. NSNumber *attributeValue = [self fb_attributeValue:FB_XCAXAIsVisibleAttributeName
  53. error:&error];
  54. if (nil != attributeValue) {
  55. NSMutableDictionary *updatedValue = [NSMutableDictionary dictionaryWithDictionary:self.additionalAttributes ?: @{}];
  56. [updatedValue setObject:attributeValue forKey:FB_XCAXAIsVisibleAttribute];
  57. self.snapshot.additionalAttributes = updatedValue.copy;
  58. @autoreleasepool {
  59. return [attributeValue boolValue];
  60. }
  61. }
  62. NSLog(@"Cannot determine visiblity of %@ natively: %@. Defaulting to: %@",
  63. self.fb_description, error.description, @(NO));
  64. return NO;
  65. }
  66. @end