Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add wdHittable property #756

Merged
merged 5 commits into from
Aug 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#import "XCUIElement+FBUtilities.h"
#import "FBElementUtils.h"
#import "XCTestPrivateSymbols.h"
#import "XCUIHitPointResult.h"

#define BROKEN_RECT CGRectMake(-1, -1, 0, 0)

Expand Down Expand Up @@ -226,6 +227,12 @@ - (NSUInteger)wdIndex
return 0;
}

- (BOOL)isWDHittable
{
XCUIHitPointResult *result = [self hitPoint:nil];
return nil == result ? NO : result.hittable;
}

- (NSDictionary *)wdRect
{
CGRect frame = self.wdFrame;
Expand Down
3 changes: 3 additions & 0 deletions WebDriverAgentLib/Routing/FBElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ NS_ASSUME_NONNULL_BEGIN
/*! Whether element is focused */
@property (nonatomic, readonly, getter = isWDFocused) BOOL wdFocused;

/*! Whether element is hittable */
@property (nonatomic, readonly, getter = isWDHittable) BOOL wdHittable;

/*! Element's index relatively to its parent. Starts from zero */
@property (nonatomic, readonly) NSUInteger wdIndex;

Expand Down
4 changes: 4 additions & 0 deletions WebDriverAgentLib/Utilities/FBMacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,7 @@

/*! Converts the given number of milliseconds into seconds */
#define FBMillisToSeconds(ms) ((ms) / 1000.0)

/*! Converts boolean value to its string representation */
#define FBBoolToString(b) ((b) ? @"true" : @"false")

31 changes: 27 additions & 4 deletions WebDriverAgentLib/Utilities/FBXPath.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#import "FBConfiguration.h"
#import "FBExceptions.h"
#import "FBLogger.h"
#import "FBMacros.h"
#import "FBXMLGenerationOptions.h"
#import "FBXCElementSnapshotWrapper+Helpers.h"
#import "NSString+FBXMLSafeString.h"
Expand Down Expand Up @@ -87,6 +88,10 @@ @interface FBIndexAttribute : FBElementAttribute

@end

@interface FBHittableAttribute : FBElementAttribute

@end

@interface FBInternalIndexAttribute : FBElementAttribute

@property (nonatomic, nonnull, readonly) NSString* indexValue;
Expand Down Expand Up @@ -273,6 +278,9 @@ + (int)xmlRepresentationWithRootElement:(id<FBElement>)root
NSMutableSet<Class> *includedAttributes;
if (nil == query) {
includedAttributes = [NSMutableSet setWithArray:FBElementAttribute.supportedAttributes];
// The hittable attribute is expensive to calculate for each snapshot item
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

// thus we only include it when requested by an xPath query
[includedAttributes removeObject:FBHittableAttribute.class];
if (nil != excludedAttributes) {
for (NSString *excludedAttributeName in excludedAttributes) {
for (Class supportedAttribute in FBElementAttribute.supportedAttributes) {
Expand Down Expand Up @@ -481,6 +489,7 @@ + (int)recordWithWriter:(xmlTextWriterPtr)writer forElement:(id<FBElement>)eleme
FBWidthAttribute.class,
FBHeightAttribute.class,
FBIndexAttribute.class,
FBHittableAttribute.class,
];
}

Expand Down Expand Up @@ -557,7 +566,7 @@ + (NSString *)name

+ (NSString *)valueForElement:(id<FBElement>)element
{
return element.wdEnabled ? @"true" : @"false";
return FBBoolToString(element.wdEnabled);
}

@end
Expand All @@ -571,7 +580,7 @@ + (NSString *)name

+ (NSString *)valueForElement:(id<FBElement>)element
{
return element.wdVisible ? @"true" : @"false";
return FBBoolToString(element.wdVisible);
}

@end
Expand All @@ -585,7 +594,7 @@ + (NSString *)name

+ (NSString *)valueForElement:(id<FBElement>)element
{
return element.wdAccessible ? @"true" : @"false";
return FBBoolToString(element.wdAccessible);
}

@end
Expand All @@ -601,7 +610,7 @@ + (NSString *)name

+ (NSString *)valueForElement:(id<FBElement>)element
{
return element.wdFocused ? @"true" : @"false";
return FBBoolToString(element.wdFocused);
}

@end
Expand Down Expand Up @@ -667,6 +676,20 @@ + (NSString *)valueForElement:(id<FBElement>)element

@end

@implementation FBHittableAttribute

+ (NSString *)name
{
return @"hittable";
}

+ (NSString *)valueForElement:(id<FBElement>)element
{
return FBBoolToString(element.wdHittable);
}

@end

@implementation FBInternalIndexAttribute

+ (NSString *)name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ - (void)testSwitchAttributes
XCTAssertNil(element.wdLabel);
XCTAssertEqualObjects(element.wdValue, @"1");
XCTAssertFalse(element.wdSelected);
XCTAssertTrue(element.wdHittable);
[element tap];
XCTAssertEqualObjects(element.wdValue, @"0");
XCTAssertFalse(element.wdSelected);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#import <XCTest/XCTest.h>

#import "FBIntegrationTestCase.h"
#import "FBMacros.h"
#import "FBTestMacros.h"
#import "FBXPath.h"
#import "FBXCodeCompatibility.h"
Expand Down Expand Up @@ -58,7 +59,7 @@ - (void)testSingleDescendantXMLRepresentation
NSString *xmlStr = [FBXPath xmlStringWithRootElement:wrappedSnapshot
options:nil];
XCTAssertNotNil(xmlStr);
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, wrappedSnapshot.wdEnabled ? @"true" : @"false", wrappedSnapshot.wdVisible ? @"true" : @"false", wrappedSnapshot.wdAccessible ? @"true" : @"false", [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex];
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdEnabled), FBBoolToString(wrappedSnapshot.wdVisible), FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex];
XCTAssertEqualObjects(xmlStr, expectedXml);
}

Expand All @@ -71,7 +72,7 @@ - (void)testSingleDescendantXMLRepresentationWithScope
NSString *xmlStr = [FBXPath xmlStringWithRootElement:wrappedSnapshot
options:options];
XCTAssertNotNil(xmlStr);
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@>\n <%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\"/>\n</%@>\n", scope, wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, wrappedSnapshot.wdEnabled ? @"true" : @"false", wrappedSnapshot.wdVisible ? @"true" : @"false", wrappedSnapshot.wdAccessible ? @"true" : @"false", [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex, scope];
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@>\n <%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\"/>\n</%@>\n", scope, wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdEnabled), FBBoolToString(wrappedSnapshot.wdVisible), FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex, scope];
XCTAssertEqualObjects(xmlStr, expectedXml);
}

Expand All @@ -84,7 +85,7 @@ - (void)testSingleDescendantXMLRepresentationWithoutAttributes
NSString *xmlStr = [FBXPath xmlStringWithRootElement:wrappedSnapshot
options:options];
XCTAssertNotNil(xmlStr);
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, wrappedSnapshot.wdAccessible ? @"true" : @"false", [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue]];
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue]];
XCTAssertEqualObjects(xmlStr, expectedXml);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ - (void)testSelfWithXPathQuery

- (void)testSingleDescendantWithXPathQuery
{
NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton"
NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@hittable='true']"
shouldReturnAfterFirstMatch:YES];
XCTAssertEqual(matchingSnapshots.count, 1);
XCUIElement *matchingSnapshot = [matchingSnapshots firstObject];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#import "FBXCAccessibilityElement.h"
#import "FBXCElementSnapshot.h"
#import "XCUIHitPointResult.h"

@implementation XCElementSnapshotDouble

Expand Down Expand Up @@ -87,6 +88,11 @@ - (NSDictionary *)additionalAttributes
return nil;
}

- (XCUIHitPointResult *)hitPoint:(NSError **)error
{
return [[XCUIHitPointResult alloc] initWithHitPoint:CGPointZero hittable:YES];
}

- (NSArray *)children
{
return @[];
Expand Down
2 changes: 2 additions & 0 deletions WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
@property (nonatomic, readwrite) NSUInteger wdIndex;
@property (nonatomic, readwrite, getter=isWDVisible) BOOL wdVisible;
@property (nonatomic, readwrite, getter=isWDAccessible) BOOL wdAccessible;
@property (nonatomic, readwrite, getter = isWDFocused) BOOL wdFocused;
@property (nonatomic, readwrite, getter = isWDHittable) BOOL wdHittable;
@property (copy, nonnull) NSArray *children;
@property (nonatomic, readwrite, assign) XCUIElementType elementType;
@property (nonatomic, readwrite, getter=isWDAccessibilityContainer) BOOL wdAccessibilityContainer;
Expand Down
2 changes: 2 additions & 0 deletions WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ - (id)init
self.wdAccessible = YES;
self.wdEnabled = YES;
self.wdSelected = YES;
self.wdFocused = YES;
self.wdHittable = YES;
self.wdIndex = 0;
#if TARGET_OS_TV
self.wdFocused = YES;
Expand Down
11 changes: 6 additions & 5 deletions WebDriverAgentTests/UnitTests/FBXPathTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#import <XCTest/XCTest.h>

#import "FBMacros.h"
#import "FBXPath.h"
#import "FBXPath-Private.h"
#import "XCUIElementDouble.h"
Expand Down Expand Up @@ -63,7 +64,7 @@ - (void)testDefaultXPathPresentation
xpathQuery:nil
excludingAttributes:nil];
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" value=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" private_indexPath=\"top\"/>\n",
element.wdType, element.wdType, element.wdValue, element.wdName, element.wdLabel, element.wdEnabled ? @"true" : @"false", element.wdVisible ? @"true" : @"false", element.wdAccessible ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex];
element.wdType, element.wdType, element.wdValue, element.wdName, element.wdLabel, FBBoolToString(element.wdEnabled), FBBoolToString(element.wdVisible), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex];
XCTAssertTrue([resultXml isEqualToString: expectedXml]);
}

Expand All @@ -75,7 +76,7 @@ - (void)testtXPathPresentationWithSomeAttributesExcluded
xpathQuery:nil
excludingAttributes:@[@"type", @"visible", @"value", @"index"]];
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ name=\"%@\" label=\"%@\" enabled=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" private_indexPath=\"top\"/>\n",
element.wdType, element.wdName, element.wdLabel, element.wdEnabled ? @"true" : @"false", element.wdAccessible ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"]];
element.wdType, element.wdName, element.wdLabel, FBBoolToString(element.wdEnabled), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"]];
XCTAssertEqualObjects(resultXml, expectedXml);
}

Expand All @@ -88,9 +89,9 @@ - (void)testXPathPresentationBasedOnQueryMatchingAllAttributes
NSString *resultXml = [self xmlStringWithElement:element
xpathQuery:[NSString stringWithFormat:@"//%@[@*]", element.wdType]
excludingAttributes:@[@"visible"]];
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" value=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" private_indexPath=\"top\"/>\n",
element.wdType, element.wdType, @"йоло&lt;&gt;&amp;&quot;", element.wdName, @"a&#10;b", element.wdEnabled ? @"true" : @"false", element.wdVisible ? @"true" : @"false", element.wdAccessible ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex];
XCTAssertTrue([resultXml isEqualToString:expectedXml]);
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" value=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" hittable=\"%@\" private_indexPath=\"top\"/>\n",
element.wdType, element.wdType, @"йоло&lt;&gt;&amp;&quot;", element.wdName, @"a&#10;b", FBBoolToString(element.wdEnabled), FBBoolToString(element.wdVisible), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex, FBBoolToString(element.wdHittable)];
XCTAssertEqualObjects(expectedXml, resultXml);
}

- (void)testXPathPresentationBasedOnQueryMatchingSomeAttributes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
@property (nonatomic, readwrite, getter=isWDVisible) BOOL wdVisible;
@property (nonatomic, readwrite, getter=isWDAccessible) BOOL wdAccessible;
@property (nonatomic, readwrite, getter=isWDFocused) BOOL wdFocused;
@property (nonatomic, readwrite, getter = isWDHittable) BOOL wdHittable;
@property (copy, nonnull) NSArray *children;
@property (nonatomic, readwrite, assign) XCUIElementType elementType;
@property (nonatomic, readwrite, getter=isWDAccessibilityContainer) BOOL wdAccessibilityContainer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ - (id)init
self.wdAccessible = YES;
self.wdEnabled = YES;
self.wdSelected = YES;
self.wdHittable = YES;
self.wdIndex = 0;
#if TARGET_OS_TV
self.wdFocused = YES;
Expand Down