Skip to content

Commit 1009a9b

Browse files
fix: Use native snapshots if hittable attribute is requested in xPath
1 parent 99c5247 commit 1009a9b

4 files changed

Lines changed: 36 additions & 8 deletions

File tree

WebDriverAgentLib/Utilities/FBXPath.m

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ + (nullable NSString *)xmlStringWithRootElement:(id<FBElement>)root
146146
}
147147

148148
if (rc >= 0) {
149-
rc = [self xmlRepresentationWithRootElement:[self snapshotWithRoot:root]
149+
[self waitUntilStableWithElement:root];
150+
rc = [self xmlRepresentationWithRootElement:[self snapshotWithRoot:root useNative:NO]
150151
writer:writer
151152
elementStore:nil
152153
query:nil
@@ -196,17 +197,23 @@ + (nullable NSString *)xmlStringWithRootElement:(id<FBElement>)root
196197
int rc = xmlTextWriterStartDocument(writer, NULL, _UTF8Encoding, NULL);
197198
id<FBXCElementSnapshot> lookupScopeSnapshot = nil;
198199
id<FBXCElementSnapshot> contextRootSnapshot = nil;
200+
BOOL useNativeSnapshot = nil == xpathQuery
201+
? NO
202+
: [[self.class elementAttributesWithXPathQuery:xpathQuery] containsObject:FBHittableAttribute.class];
199203
if (rc < 0) {
200204
[FBLogger logFmt:@"Failed to invoke libxml2>xmlTextWriterStartDocument. Error code: %d", rc];
201205
} else {
206+
[self waitUntilStableWithElement:root];
202207
if (FBConfiguration.limitXpathContextScope) {
203-
lookupScopeSnapshot = [self snapshotWithRoot:root];
208+
lookupScopeSnapshot = [self snapshotWithRoot:root useNative:useNativeSnapshot];
204209
} else {
205210
if ([root isKindOfClass:XCUIElement.class]) {
206-
lookupScopeSnapshot = [self snapshotWithRoot:[(XCUIElement *)root application]];
211+
lookupScopeSnapshot = [self snapshotWithRoot:[(XCUIElement *)root application]
212+
useNative:useNativeSnapshot];
207213
contextRootSnapshot = [root isKindOfClass:XCUIApplication.class]
208214
? nil
209-
: ([(XCUIElement *)root lastSnapshot] ?: [(XCUIElement *)root fb_customSnapshot]);
215+
: ([(XCUIElement *)root lastSnapshot] ?: [self snapshotWithRoot:(XCUIElement *)root
216+
useNative:useNativeSnapshot]);
210217
} else {
211218
lookupScopeSnapshot = (id<FBXCElementSnapshot>)root;
212219
contextRootSnapshot = nil == lookupScopeSnapshot.parent ? nil : (id<FBXCElementSnapshot>)root;
@@ -483,19 +490,29 @@ + (int)writeXmlWithRootElement:(id<FBXCElementSnapshot>)root
483490
}
484491

485492
+ (id<FBXCElementSnapshot>)snapshotWithRoot:(id<FBElement>)root
493+
useNative:(BOOL)useNative
486494
{
487495
if (![root isKindOfClass:XCUIElement.class]) {
488496
return (id<FBXCElementSnapshot>)root;
489497
}
490498

491-
// If the app is not idle state while we retrieve the visiblity state
492-
// then the snapshot retrieval operation might freeze and time out
493-
[[(XCUIElement *)root application] fb_waitUntilStableWithTimeout:FBConfiguration.animationCoolOffTimeout];
499+
if (useNative) {
500+
return [(XCUIElement *)root fb_nativeSnapshot];
501+
}
494502
return [root isKindOfClass:XCUIApplication.class]
495503
? [(XCUIElement *)root fb_standardSnapshot]
496504
: [(XCUIElement *)root fb_customSnapshot];
497505
}
498506

507+
+ (void)waitUntilStableWithElement:(id<FBElement>)root
508+
{
509+
if ([root isKindOfClass:XCUIElement.class]) {
510+
// If the app is not idle state while we retrieve the visiblity state
511+
// then the snapshot retrieval operation might freeze and time out
512+
[[(XCUIElement *)root application] fb_waitUntilStableWithTimeout:FBConfiguration.animationCoolOffTimeout];
513+
}
514+
}
515+
499516
@end
500517

501518

WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,4 +461,13 @@ - (void)testInvisibleDescendantWithXPathQuery
461461
XCTAssertFalse(matchingSnapshots.lastObject.fb_isVisible);
462462
}
463463

464+
- (void)testNonHittableDescendantWithXPathQuery
465+
{
466+
NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeStaticText[@hittable='false']"
467+
shouldReturnAfterFirstMatch:NO];
468+
XCTAssertGreaterThan(matchingSnapshots.count, 1);
469+
XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeStaticText);
470+
XCTAssertFalse(matchingSnapshots.lastObject.fb_isVisible);
471+
}
472+
464473
@end

WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
@property (nonatomic, strong, readwrite, nullable) NSString *wdValue;
2929
@property (nonatomic, readwrite, getter=isWDEnabled) BOOL wdEnabled;
3030
@property (nonatomic, readwrite, getter=isWDSelected) BOOL wdSelected;
31+
@property (nonatomic, readwrite, assign) CGRect wdNativeFrame;
3132
@property (nonatomic, readwrite) NSUInteger wdIndex;
3233
@property (nonatomic, readwrite, getter=isWDVisible) BOOL wdVisible;
3334
@property (nonatomic, readwrite, getter=isWDAccessible) BOOL wdAccessible;

WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.m

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ - (id)init
1919
{
2020
self = [super init];
2121
if (self) {
22-
self.wdFrame = CGRectMake(0, 0, 0, 0);
22+
self.wdFrame = CGRectZero;
23+
self.wdNativeFrame = CGRectZero;
2324
self.wdName = @"testName";
2425
self.wdLabel = @"testLabel";
2526
self.wdValue = @"magicValue";

0 commit comments

Comments
 (0)