Skip to content

Commit

Permalink
fix: Only check existence if firstMatch is applied (#638)
Browse files Browse the repository at this point in the history
  • Loading branch information
mykola-mokhnach authored Nov 25, 2022
1 parent 3ec5a06 commit 5394fe8
Show file tree
Hide file tree
Showing 17 changed files with 123 additions and 96 deletions.
6 changes: 3 additions & 3 deletions WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ - (nullable XCUIElement *)fb_alertElementFromSafariWithScrollView:(XCUIElement *
descendantsMatchingType:XCUIElementTypeOther]
matchingPredicate:dstViewMatchPredicate]
containingPredicate:dstViewContainPredicate1]
containingPredicate:dstViewContainPredicate2].fb_firstMatch;
containingPredicate:dstViewContainPredicate2].allElementsBoundByIndex.firstObject;
} else {
NSPredicate *webViewPredicate = [NSPredicate predicateWithFormat:@"elementType == %lu", XCUIElementTypeWebView];
// Find the first XCUIElementTypeOther which is the descendant of the scroll view
Expand All @@ -54,7 +54,7 @@ - (nullable XCUIElement *)fb_alertElementFromSafariWithScrollView:(XCUIElement *
descendantsMatchingType:XCUIElementTypeOther]
matchingPredicate:dstViewMatchPredicate]
containingPredicate:dstViewContainPredicate1]
containingPredicate:dstViewContainPredicate2].fb_firstMatch;
containingPredicate:dstViewContainPredicate2].allElementsBoundByIndex.firstObject;
}
if (nil == candidate) {
return nil;
Expand All @@ -80,7 +80,7 @@ - (XCUIElement *)fb_alertElement
NSPredicate *alertCollectorPredicate = [NSPredicate predicateWithFormat:@"elementType IN {%lu,%lu,%lu}",
XCUIElementTypeAlert, XCUIElementTypeSheet, XCUIElementTypeScrollView];
XCUIElement *alert = [[self descendantsMatchingType:XCUIElementTypeAny]
matchingPredicate:alertCollectorPredicate].fb_firstMatch;
matchingPredicate:alertCollectorPredicate].allElementsBoundByIndex.firstObject;
if (nil == alert) {
return nil;
}
Expand Down
2 changes: 1 addition & 1 deletion WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ - (NSString *)fb_xmlRepresentationWithOptions:(FBXMLGenerationOptions *)options
- (NSString *)fb_descriptionRepresentation
{
NSMutableArray<NSString *> *childrenDescriptions = [NSMutableArray array];
for (XCUIElement *child in [self.fb_query childrenMatchingType:XCUIElementTypeAny].allElementsBoundByAccessibilityElement) {
for (XCUIElement *child in [self.fb_query childrenMatchingType:XCUIElementTypeAny].allElementsBoundByIndex) {
[childrenDescriptions addObject:child.debugDescription];
}
// debugDescription property of XCUIApplication instance shows descendants addresses in memory
Expand Down
2 changes: 1 addition & 1 deletion WebDriverAgentLib/Categories/XCUIElement+FBResolve.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ - (XCUIElement *)fb_stableInstance
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id<FBXCElementSnapshot> snapshot, NSDictionary *bindings) {
return [[FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot] isEqualToString:uid];
}];
return [query matchingPredicate:predicate].fb_firstMatch ?: self;
return [query matchingPredicate:predicate].allElementsBoundByIndex.firstObject ?: self;
}

@end
41 changes: 11 additions & 30 deletions WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ @implementation XCUIElement (FBUtilities)
if (0 == snapshots.count) {
return @[];
}
NSMutableArray<NSString *> *sortedIds = [NSMutableArray new];
NSMutableArray<NSString *> *matchedIds = [NSMutableArray new];
for (id<FBXCElementSnapshot> snapshot in snapshots) {
NSString *uid = [FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot];
if (nil != uid) {
[sortedIds addObject:uid];
[matchedIds addObject:uid];
}
}
NSMutableArray<XCUIElement *> *matchedElements = [NSMutableArray array];
Expand All @@ -146,11 +146,13 @@ @implementation XCUIElement (FBUtilities)
? [FBXCElementSnapshotWrapper wdUIDWithSnapshot:self.lastSnapshot]
: self.fb_uid;
}
if ([sortedIds containsObject:uid]) {
if (nil != uid && [matchedIds containsObject:uid]) {
XCUIElement *stableSelf = self.fb_stableInstance;
stableSelf.fb_isResolvedNatively = @NO;
if (1 == snapshots.count) {
return @[self];
return @[stableSelf];
}
[matchedElements addObject:self];
[matchedElements addObject:stableSelf];
}
XCUIElementType type = XCUIElementTypeAny;
NSArray<NSNumber *> *uniqueTypes = [snapshots valueForKeyPath:[NSString stringWithFormat:@"@distinctUnionOfObjects.%@", FBStringify(XCUIElement, elementType)]];
Expand All @@ -161,34 +163,13 @@ @implementation XCUIElement (FBUtilities)
? [self.fb_query childrenMatchingType:type]
: [self.fb_query descendantsMatchingType:type];
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id<FBXCElementSnapshot> snapshot, NSDictionary *bindings) {
return [sortedIds containsObject:[FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot] ?: @""];
return [matchedIds containsObject:[FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot] ?: @""];
}];
query = [query matchingPredicate:predicate];
if (1 == snapshots.count) {
XCUIElement *result = query.fb_firstMatch;
result.fb_isResolvedNatively = @NO;
return result ? @[result] : @[];
}
// Rely here on the fact, that XPath always returns query results in the same
// order they appear in the document, which means we don't need to resort the resulting
// array. Although, if it turns out this is still not the case then we could always
// uncomment the sorting procedure below:
// query = [query sorted:(id)^NSComparisonResult(XCElementSnapshot *a, XCElementSnapshot *b) {
// NSUInteger first = [sortedIds indexOfObject:a.wdUID];
// NSUInteger second = [sortedIds indexOfObject:b.wdUID];
// if (first < second) {
// return NSOrderedAscending;
// }
// if (first > second) {
// return NSOrderedDescending;
// }
// return NSOrderedSame;
// }];
NSArray<XCUIElement *> *result = query.fb_allMatches;
for (XCUIElement *el in result) {
[matchedElements addObjectsFromArray:[query matchingPredicate:predicate].allElementsBoundByIndex];
for (XCUIElement *el in matchedElements) {
el.fb_isResolvedNatively = @NO;
}
return result;
return matchedElements.copy;
}

- (void)fb_waitUntilStable
Expand Down
14 changes: 9 additions & 5 deletions WebDriverAgentLib/Commands/FBElementCommands.m
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,11 @@ + (NSArray *)routes
// what ios-driver did and sadly, we must copy them.
NSString *const name = request.arguments[@"name"];
if (name) {
XCUIElement *childElement = [[[[element.fb_query descendantsMatchingType:XCUIElementTypeAny] matchingIdentifier:name] allElementsBoundByAccessibilityElement] lastObject];
XCUIElement *childElement = [[[[element.fb_query descendantsMatchingType:XCUIElementTypeAny]
matchingIdentifier:name] allElementsBoundByIndex] lastObject];
if (!childElement) {
return FBResponseWithStatus([FBCommandStatus noSuchElementErrorWithMessage:[NSString stringWithFormat:@"'%@' identifier didn't match any elements", name] traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]);
return FBResponseWithStatus([FBCommandStatus noSuchElementErrorWithMessage:[NSString stringWithFormat:@"'%@' identifier didn't match any elements", name]
traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]);
}
return [self.class handleScrollElementToVisible:childElement withRequest:request];
}
Expand All @@ -413,9 +415,11 @@ + (NSArray *)routes
if (predicateString) {
NSPredicate *formattedPredicate = [NSPredicate fb_snapshotBlockPredicateWithPredicate:[NSPredicate
predicateWithFormat:predicateString]];
XCUIElement *childElement = [[[[element.fb_query descendantsMatchingType:XCUIElementTypeAny] matchingPredicate:formattedPredicate] allElementsBoundByAccessibilityElement] lastObject];
XCUIElement *childElement = [[[[element.fb_query descendantsMatchingType:XCUIElementTypeAny]
matchingPredicate:formattedPredicate] allElementsBoundByIndex] lastObject];
if (!childElement) {
return FBResponseWithStatus([FBCommandStatus noSuchElementErrorWithMessage:[NSString stringWithFormat:@"'%@' predicate didn't match any elements", predicateString] traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]);
return FBResponseWithStatus([FBCommandStatus noSuchElementErrorWithMessage:[NSString stringWithFormat:@"'%@' predicate didn't match any elements", predicateString]
traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]);
}
return [self.class handleScrollElementToVisible:childElement withRequest:request];
}
Expand Down Expand Up @@ -675,7 +679,7 @@ + (XCUICoordinate *)gestureCoordinateWithCoordinate:(CGPoint)coordinate
*/
XCUIElement *element = application;
if (isSDKVersionGreaterThanOrEqualTo(@"11.0")) {
XCUIElement *window = application.windows.fb_firstMatch;
XCUIElement *window = application.windows.allElementsBoundByIndex.firstObject;
if (window) {
element = window;
id<FBXCElementSnapshot> snapshot = element.fb_cachedSnapshot ?: element.fb_takeSnapshot;
Expand Down
2 changes: 1 addition & 1 deletion WebDriverAgentLib/FBAlert.m
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ - (BOOL)clickAlertButton:(NSString *)label error:(NSError **)error

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"label == %@", label];
XCUIElement *requestedButton = [[self.alertElement descendantsMatchingType:XCUIElementTypeButton]
matchingPredicate:predicate].fb_firstMatch;
matchingPredicate:predicate].allElementsBoundByIndex.firstObject;
if (!requestedButton) {
return [[[FBErrorBuilder builder]
withDescriptionFormat:@"Failed to find button with label '%@' for alert: %@", label, self.alertElement]
Expand Down
2 changes: 1 addition & 1 deletion WebDriverAgentLib/Utilities/FBScreen.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ + (CGSize)statusBarSizeForApplication:(XCUIApplication *)application
expectVisibleBar = NO;
}

XCUIElement *mainStatusBar = app.statusBars.fb_firstMatch;
XCUIElement *mainStatusBar = app.statusBars.allElementsBoundByIndex.firstObject;
if (!mainStatusBar || (expectVisibleBar && !mainStatusBar.fb_isVisible)) {
return CGSizeZero;
}
Expand Down
9 changes: 5 additions & 4 deletions WebDriverAgentLib/Utilities/FBXCodeCompatibility.m
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,11 @@ - (XCElementSnapshot *)fb_uniqueSnapshotWithError:(NSError **)error

- (XCUIElement *)fb_firstMatch
{
XCUIElement* match = FBConfiguration.useFirstMatch
? self.firstMatch
: self.fb_allMatches.firstObject;
return [match exists] ? match : nil;
if (FBConfiguration.useFirstMatch) {
XCUIElement* match = self.firstMatch;
return [match exists] ? match : nil;
}
return self.fb_allMatches.firstObject;
}

- (NSArray<XCUIElement *> *)fb_allMatches
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ - (void)setUp
[self launchApplication];
[self goToAttributesPage];
});
self.pickerWheel = self.testedApplication.pickerWheels.fb_firstMatch;
self.pickerWheel = self.testedApplication.pickerWheels.allElementsBoundByIndex.firstObject;
}

- (void)tearDown
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ - (void)testContainerAccessibilityAttributes
- (void)testIgnoredAccessibilityAttributes
{
// Images are neither accessibility elements nor contain them, so both checks should fail
XCUIElement *imageElement = self.testedApplication.images.fb_firstMatch;
XCUIElement *imageElement = self.testedApplication.images.allElementsBoundByIndex.firstObject;
XCTAssertTrue(imageElement.exists);
XCTAssertFalse(imageElement.fb_isAccessibilityElement);
XCTAssertFalse(imageElement.isWDAccessibilityContainer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ - (void)testSpringBoardIcons
XCTAssertTrue(self.springboard.icons[@"Reminders"].fb_isVisible);

// Check Icons on second screen screen
XCTAssertFalse(self.springboard.icons[@"IntegrationApp"].query.fb_firstMatch.fb_isVisible);
XCTAssertFalse(self.springboard.icons[@"IntegrationApp"].firstMatch.fb_isVisible);
}

- (void)testSpringBoardSubfolder
Expand All @@ -59,7 +59,7 @@ - (void)disabled_testIconsFromSearchDashboard
XCTAssertFalse(self.springboard.icons[@"Reminders"].fb_isVisible);
XCTAssertFalse([[[self.springboard descendantsMatchingType:XCUIElementTypeIcon]
matchingIdentifier:@"IntegrationApp"]
fb_firstMatch].fb_isVisible);
firstMatch].fb_isVisible);
}

- (void)testTableViewCells
Expand All @@ -72,8 +72,8 @@ - (void)testTableViewCells
[self launchApplication];
[self goToScrollPageWithCells:YES];
for (int i = 0 ; i < 10 ; i++) {
FBAssertWaitTillBecomesTrue(self.testedApplication.cells.allElementsBoundByAccessibilityElement[i].fb_isVisible);
FBAssertWaitTillBecomesTrue(self.testedApplication.staticTexts.allElementsBoundByAccessibilityElement[i].fb_isVisible);
FBAssertWaitTillBecomesTrue(self.testedApplication.cells.allElementsBoundByIndex[i].fb_isVisible);
FBAssertWaitTillBecomesTrue(self.testedApplication.staticTexts.allElementsBoundByIndex[i].fb_isVisible);
}
}

Expand Down
2 changes: 1 addition & 1 deletion WebDriverAgentTests/IntegrationTests/FBPasteboardTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ - (void)testSetPasteboard
if (![pastItemsQuery.firstMatch waitForExistenceWithTimeout:2.0]) {
XCTFail(@"No matched element named 'Paste'");
}
XCUIElement *pasteItem = pastItemsQuery.fb_firstMatch;
XCUIElement *pasteItem = pastItemsQuery.firstMatch;
XCTAssertNotNil(pasteItem);
[pasteItem tap];
FBAssertWaitTillBecomesTrue([textField.value isEqualToString:text]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ - (void)setUp

- (void)testSelectNextPickerValue
{
XCUIElement *element = self.testedApplication.pickerWheels.fb_firstMatch;
XCUIElement *element = self.testedApplication.pickerWheels.allElementsBoundByIndex.firstObject;
XCTAssertTrue(element.exists);
XCTAssertEqualObjects(element.wdType, @"XCUIElementTypePickerWheel");
NSError *error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ - (void)setUp
[self launchApplication];
[self goToAttributesPage];
});
self.pickerWheel = self.testedApplication.pickerWheels.fb_firstMatch;
self.pickerWheel = self.testedApplication.pickerWheels.allElementsBoundByIndex.firstObject;
}

- (void)tearDown
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ - (void)setUp

- (id<FBXCElementSnapshot>)destinationSnapshot
{
XCUIElement *matchingElement = self.testedView.buttons.fb_firstMatch;
XCUIElement *matchingElement = self.testedView.buttons.allElementsBoundByIndex.firstObject;
FBAssertWaitTillBecomesTrue(nil != matchingElement.fb_takeSnapshot);

id<FBXCElementSnapshot> snapshot = matchingElement.fb_takeSnapshot;
Expand Down
Loading

0 comments on commit 5394fe8

Please sign in to comment.