diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.h b/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.h index 6f4666688..b67be4e72 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.h +++ b/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.h @@ -26,6 +26,7 @@ NS_ASSUME_NONNULL_BEGIN - Memory-friedly - `children` property is set to `nil` if not taken from XCUIApplication - `value` property is cut off to max 512 bytes + - Sometimes `frame` properties may be off. @return The recent snapshot of the element @throws FBStaleElementException if the element is not present in DOM and thus no snapshot could be made @@ -55,7 +56,9 @@ NS_ASSUME_NONNULL_BEGIN The maximum snapshot tree depth is set by `FBConfiguration.snapshotMaxDepth` Snapshot specifics: - - Less performant in comparison to the standard one + - Less performant in comparison to the custom one. Internally, it calls same APIs + that fb_customSnapshot does, although this one has some additional logic to ensure + the snapshot is valid. It also may make retries, which slows the call down significantly. - The `hittable` property calculation is aligned with the native calculation logic @return The recent snapshot of the element diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m b/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m index ca3023bfb..107167a93 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m @@ -8,6 +8,7 @@ #import "XCUIElement+FBWebDriverAttributes.h" +#import "FBConfiguration.h" #import "FBElementTypeTransformer.h" #import "FBElementHelpers.h" #import "FBLogger.h" @@ -34,6 +35,10 @@ @implementation XCUIElement (WebDriverAttributesForwarding) if ([name isEqualToString:FBStringify(XCUIElement, isWDHittable)]) { return [self fb_nativeSnapshot]; } + // https://github.com/appium/WebDriverAgent/issues/1085 + if (FBConfiguration.enforceCustomSnapshots) { + return [self fb_customSnapshot]; + } // https://github.com/appium/appium-xcuitest-driver/issues/2552 BOOL isValueRequest = [name isEqualToString:FBStringify(XCUIElement, wdValue)]; if ([self isKindOfClass:XCUIApplication.class] && !isValueRequest) { @@ -177,7 +182,7 @@ - (CGRect)wdNativeFrame characteristics of the element such as Button, Link, Image, etc. You can find the list of possible traits in the Apple documentation: https://developer.apple.com/documentation/uikit/uiaccessibilitytraits?language=objc - + @return A comma-separated string of accessibility traits, or an empty string if no traits are set */ - (NSString *)wdTraits diff --git a/WebDriverAgentLib/Commands/FBSessionCommands.m b/WebDriverAgentLib/Commands/FBSessionCommands.m index 1a9ddf417..cee0234ab 100644 --- a/WebDriverAgentLib/Commands/FBSessionCommands.m +++ b/WebDriverAgentLib/Commands/FBSessionCommands.m @@ -355,6 +355,7 @@ + (NSArray *)routes FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE: @([FBConfiguration includeHittableInPageSource]), FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE: @([FBConfiguration includeNativeFrameInPageSource]), FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE: @([FBConfiguration includeMinMaxValueInPageSource]), + FB_SETTING_ENFORCE_CUSTOM_SNAPSHOTS: @([FBConfiguration enforceCustomSnapshots]), FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE: @([FBConfiguration limitXpathContextScope]), #if !TARGET_OS_TV FB_SETTING_SCREENSHOT_ORIENTATION: [FBConfiguration humanReadableScreenshotOrientation], @@ -466,6 +467,9 @@ + (NSArray *)routes if (nil != [settings objectForKey:FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE]) { [FBConfiguration setIncludeMinMaxValueInPageSource:[[settings objectForKey:FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE] boolValue]]; } + if (nil != [settings objectForKey:FB_SETTING_ENFORCE_CUSTOM_SNAPSHOTS]) { + [FBConfiguration setEnforceCustomSnapshots:[[settings objectForKey:FB_SETTING_ENFORCE_CUSTOM_SNAPSHOTS] boolValue]]; + } if (nil != [settings objectForKey:FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE]) { [FBConfiguration setLimitXpathContextScope:[[settings objectForKey:FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE] boolValue]]; } @@ -542,7 +546,7 @@ + (NSString *)deviceNameByUserInterfaceIdiom:(UIUserInterfaceIdiom) userInterfac } // CarPlay, Mac, Vision UI or unknown are possible return @"Unknown"; - + } + (NSDictionary *)currentCapabilities diff --git a/WebDriverAgentLib/Utilities/FBConfiguration.h b/WebDriverAgentLib/Utilities/FBConfiguration.h index e6a7d4552..d121f6da9 100644 --- a/WebDriverAgentLib/Utilities/FBConfiguration.h +++ b/WebDriverAgentLib/Utilities/FBConfiguration.h @@ -376,6 +376,17 @@ typedef NS_ENUM(NSInteger, FBConfigurationKeyboardPreference) { + (void)setIncludeMinMaxValueInPageSource:(BOOL)enabled; + (BOOL)includeMinMaxValueInPageSource; +/** + * Whether to enforce the use of custom snapshots instead of standard snapshots. + * When enabled, fb_customSnapshot is always invoked instead of fb_standardSnapshot + * for XPath tree building and element attributes fetching. + * Disabled by default. + * + * @param enabled Either YES or NO + */ ++ (void)setEnforceCustomSnapshots:(BOOL)enabled; ++ (BOOL)enforceCustomSnapshots; + @end NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Utilities/FBConfiguration.m b/WebDriverAgentLib/Utilities/FBConfiguration.m index 8dfe31bf0..1110b1fd4 100644 --- a/WebDriverAgentLib/Utilities/FBConfiguration.m +++ b/WebDriverAgentLib/Utilities/FBConfiguration.m @@ -63,6 +63,7 @@ static BOOL FBShouldIncludeHittableInPageSource = NO; static BOOL FBShouldIncludeNativeFrameInPageSource = NO; static BOOL FBShouldIncludeMinMaxValueInPageSource = NO; +static BOOL FBShouldEnforceCustomSnapshots = NO; @implementation FBConfiguration @@ -153,7 +154,7 @@ + (NSInteger)mjpegServerPort if (self.mjpegServerPortFromArguments != NSNotFound) { return self.mjpegServerPortFromArguments; } - + if (NSProcessInfo.processInfo.environment[@"MJPEG_SERVER_PORT"] && [NSProcessInfo.processInfo.environment[@"MJPEG_SERVER_PORT"] length] > 0) { return [NSProcessInfo.processInfo.environment[@"MJPEG_SERVER_PORT"] integerValue]; @@ -235,7 +236,7 @@ + (NSUInteger)maxTypingFrequency if (nil == FBMaxTypingFrequency) { return [self defaultTypingFrequency]; } - return FBMaxTypingFrequency.integerValue <= 0 + return FBMaxTypingFrequency.integerValue <= 0 ? [self defaultTypingFrequency] : FBMaxTypingFrequency.integerValue; } @@ -686,4 +687,14 @@ + (BOOL)includeMinMaxValueInPageSource return FBShouldIncludeMinMaxValueInPageSource; } ++ (void)setEnforceCustomSnapshots:(BOOL)enabled +{ + FBShouldEnforceCustomSnapshots = enabled; +} + ++ (BOOL)enforceCustomSnapshots +{ + return FBShouldEnforceCustomSnapshots; +} + @end diff --git a/WebDriverAgentLib/Utilities/FBSettings.h b/WebDriverAgentLib/Utilities/FBSettings.h index b98a070b6..f995895b2 100644 --- a/WebDriverAgentLib/Utilities/FBSettings.h +++ b/WebDriverAgentLib/Utilities/FBSettings.h @@ -42,5 +42,6 @@ extern NSString* const FB_SETTING_AUTO_CLICK_ALERT_SELECTOR; extern NSString *const FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE; extern NSString *const FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE; extern NSString *const FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE; +extern NSString *const FB_SETTING_ENFORCE_CUSTOM_SNAPSHOTS; NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Utilities/FBSettings.m b/WebDriverAgentLib/Utilities/FBSettings.m index 17b8ab79d..5784ff950 100644 --- a/WebDriverAgentLib/Utilities/FBSettings.m +++ b/WebDriverAgentLib/Utilities/FBSettings.m @@ -38,3 +38,4 @@ NSString* const FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE = @"includeHittableInPageSource"; NSString* const FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE = @"includeNativeFrameInPageSource"; NSString* const FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE = @"includeMinMaxValueInPageSource"; +NSString* const FB_SETTING_ENFORCE_CUSTOM_SNAPSHOTS = @"enforceCustomSnapshots"; diff --git a/WebDriverAgentLib/Utilities/FBXPath.m b/WebDriverAgentLib/Utilities/FBXPath.m index 79e8f75f3..1e4ba4cc0 100644 --- a/WebDriverAgentLib/Utilities/FBXPath.m +++ b/WebDriverAgentLib/Utilities/FBXPath.m @@ -567,10 +567,12 @@ + (int)writeXmlWithRootElement:(id)root return (id)root; } + // https://github.com/appium/appium-xcuitest-driver/pull/2565 if (useNative) { return [(XCUIElement *)root fb_nativeSnapshot]; } - return [root isKindOfClass:XCUIApplication.class] + // https://github.com/appium/WebDriverAgent/issues/1085 + return [root isKindOfClass:XCUIApplication.class] && !FBConfiguration.enforceCustomSnapshots ? [(XCUIElement *)root fb_standardSnapshot] : [(XCUIElement *)root fb_customSnapshot]; }