diff --git a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m index 84f697405..1c788cd54 100644 --- a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +++ b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m @@ -37,6 +37,7 @@ #import "XCUIElement+FBUtilities.h" #import "XCUIElement+FBWebDriverAttributes.h" #import "XCUIElementQuery.h" +#import "FBElementHelpers.h" static NSString* const FBUnknownBundleId = @"unknown"; @@ -45,6 +46,7 @@ static NSString* const FBExclusionAttributeVisible = @"visible"; static NSString* const FBExclusionAttributeAccessible = @"accessible"; static NSString* const FBExclusionAttributeFocused = @"focused"; +static NSString* const FBExclusionAttributePlaceholderValue = @"placeholderValue"; _Nullable id extractIssueProperty(id issue, NSString *propertyName) { @@ -201,28 +203,15 @@ + (NSDictionary *)dictionaryForElement:(id)snapshot info[@"label"] = FBValueOrNull(wrappedSnapshot.wdLabel); info[@"rect"] = wrappedSnapshot.wdRect; - NSDictionary *attributeBlocks = @{ - FBExclusionAttributeFrame: ^{ - return NSStringFromCGRect(wrappedSnapshot.wdFrame); - }, - FBExclusionAttributeEnabled: ^{ - return [@([wrappedSnapshot isWDEnabled]) stringValue]; - }, - FBExclusionAttributeVisible: ^{ - return [@([wrappedSnapshot isWDVisible]) stringValue]; - }, - FBExclusionAttributeAccessible: ^{ - return [@([wrappedSnapshot isWDAccessible]) stringValue]; - }, - FBExclusionAttributeFocused: ^{ - return [@([wrappedSnapshot isWDFocused]) stringValue]; - } - }; + NSDictionary *attributeBlocks = [self fb_attributeBlockMapForWrappedSnapshot:wrappedSnapshot]; + + NSSet *nonPrefixedKeys = [NSSet setWithObjects:FBExclusionAttributeFrame, + FBExclusionAttributePlaceholderValue, nil]; for (NSString *key in attributeBlocks) { if (excludedAttributes == nil || ![excludedAttributes containsObject:key]) { NSString *value = ((NSString * (^)(void))attributeBlocks[key])(); - if ([key isEqualToString:FBExclusionAttributeFrame]) { + if ([nonPrefixedKeys containsObject:key]) { info[key] = value; } else { info[[NSString stringWithFormat:@"is%@", [key capitalizedString]]] = value; @@ -248,6 +237,43 @@ + (NSDictionary *)dictionaryForElement:(id)snapshot return info; } +// Helper used by `dictionaryForElement:` to assemble attribute value blocks, +// including both common attributes and conditionally included ones like placeholderValue. ++ (NSDictionary *)fb_attributeBlockMapForWrappedSnapshot:(FBXCElementSnapshotWrapper *)wrappedSnapshot + +{ + // Base attributes common to every element + NSMutableDictionary *blocks = + [@{ + FBExclusionAttributeFrame: ^{ + return NSStringFromCGRect(wrappedSnapshot.wdFrame); + }, + FBExclusionAttributeEnabled: ^{ + return [@([wrappedSnapshot isWDEnabled]) stringValue]; + }, + FBExclusionAttributeVisible: ^{ + return [@([wrappedSnapshot isWDVisible]) stringValue]; + }, + FBExclusionAttributeAccessible: ^{ + return [@([wrappedSnapshot isWDAccessible]) stringValue]; + }, + FBExclusionAttributeFocused: ^{ + return [@([wrappedSnapshot isWDFocused]) stringValue]; + } + } mutableCopy]; + + XCUIElementType elementType = wrappedSnapshot.elementType; + + // Text-input placeholder (only for elements that support inner text) + if (FBDoesElementSupportInnerText(elementType)) { + blocks[FBExclusionAttributePlaceholderValue] = ^{ + return (NSString *)FBValueOrNull(wrappedSnapshot.wdPlaceholderValue); + }; + } + + return [blocks copy]; +} + + (NSDictionary *)accessibilityInfoForElement:(id)snapshot { FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:snapshot];