Skip to content

Commit

Permalink
refactor!: Drop workarounds for legacy iOS versions (#696)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: The minimum supported xCode/iOS version is now 13/15.0
  • Loading branch information
mykola-mokhnach authored May 14, 2023
1 parent 9860a72 commit bb562b9
Show file tree
Hide file tree
Showing 9 changed files with 31 additions and 106 deletions.
29 changes: 9 additions & 20 deletions WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,15 @@ - (nullable XCUIElement *)fb_alertElementFromSafariWithScrollView:(XCUIElement *
}];
NSPredicate *dstViewContainPredicate1 = [NSPredicate predicateWithFormat:@"elementType == %lu", XCUIElementTypeTextView];
NSPredicate *dstViewContainPredicate2 = [NSPredicate predicateWithFormat:@"elementType == %lu", XCUIElementTypeButton];
XCUIElement *candidate = nil;
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) {
// Find the first XCUIElementTypeOther which is the grandchild of the web view
// and is horizontally aligned to the center of the screen
candidate = [[[[[[scrollView descendantsMatchingType:XCUIElementTypeAny]
matchingIdentifier:@"WebView"]
descendantsMatchingType:XCUIElementTypeOther]
matchingPredicate:dstViewMatchPredicate]
containingPredicate:dstViewContainPredicate1]
containingPredicate:dstViewContainPredicate2].allElementsBoundByIndex.firstObject;
} else {
NSPredicate *webViewPredicate = [NSPredicate predicateWithFormat:@"elementType == %lu", XCUIElementTypeWebView];
// Find the first XCUIElementTypeOther which is the descendant of the scroll view
// and is horizontally aligned to the center of the screen
candidate = [[[[[scrollView.fb_query containingPredicate:webViewPredicate]
descendantsMatchingType:XCUIElementTypeOther]
matchingPredicate:dstViewMatchPredicate]
containingPredicate:dstViewContainPredicate1]
containingPredicate:dstViewContainPredicate2].allElementsBoundByIndex.firstObject;
}
// Find the first XCUIElementTypeOther which is the grandchild of the web view
// and is horizontally aligned to the center of the screen
XCUIElement *candidate = [[[[[[scrollView descendantsMatchingType:XCUIElementTypeAny]
matchingIdentifier:@"WebView"]
descendantsMatchingType:XCUIElementTypeOther]
matchingPredicate:dstViewMatchPredicate]
containingPredicate:dstViewContainPredicate1]
containingPredicate:dstViewContainPredicate2].allElementsBoundByIndex.firstObject;

if (nil == candidate) {
return nil;
}
Expand Down
6 changes: 1 addition & 5 deletions WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,7 @@ - (BOOL)fb_unlockScreen:(NSError **)error
[self pressButton:XCUIDeviceButtonHome];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:FBHomeButtonCoolOffTime]];
#if !TARGET_OS_TV
if (SYSTEM_VERSION_LESS_THAN(@"10.0")) {
[[FBApplication fb_activeApplication] swipeRight];
} else {
[self pressButton:XCUIDeviceButtonHome];
}
[self pressButton:XCUIDeviceButtonHome];
#else
[self pressButton:XCUIDeviceButtonHome];
#endif
Expand Down
43 changes: 7 additions & 36 deletions WebDriverAgentLib/Categories/XCUIElement+FBTap.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,52 +9,23 @@

#import "XCUIElement+FBTap.h"

#import "FBMacros.h"
#import "XCUIApplication+FBTouchAction.h"
#import "XCUIElement+FBUtilities.h"


#if !TARGET_OS_TV
@implementation XCUIElement (FBTap)

- (BOOL)fb_tapWithError:(NSError **)error
{
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"13.0")) {
[self tap];
return YES;
}

NSArray<NSDictionary<NSString *, id> *> *tapGesture =
@[
@{@"action": @"tap",
@"options": @{@"element": self}
}
];
return [self.application fb_performAppiumTouchActions:tapGesture elementCache:nil error:error];
[self tap];
return YES;
}

- (BOOL)fb_tapCoordinate:(CGPoint)relativeCoordinate error:(NSError **)error
{
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"13.0")) {
// Coordinates calculation issues have been fixed
// for different device orientations since Xcode 11
XCUICoordinate *startCoordinate = [self coordinateWithNormalizedOffset:CGVectorMake(0, 0)];
CGVector offset = CGVectorMake(relativeCoordinate.x, relativeCoordinate.y);
XCUICoordinate *dstCoordinate = [startCoordinate coordinateWithOffset:offset];
[dstCoordinate tap];
return YES;
}

NSArray<NSDictionary<NSString *, id> *> *tapGesture =
@[
@{@"action": @"tap",
@"options": @{@"element": self,
@"x": @(relativeCoordinate.x),
@"y": @(relativeCoordinate.y)
}
}
];
return [self.application fb_performAppiumTouchActions:tapGesture elementCache:nil error:error];
XCUICoordinate *startCoordinate = [self coordinateWithNormalizedOffset:CGVectorMake(0, 0)];
CGVector offset = CGVectorMake(relativeCoordinate.x, relativeCoordinate.y);
XCUICoordinate *dstCoordinate = [startCoordinate coordinateWithOffset:offset];
[dstCoordinate tap];
return YES;
}

@end
Expand Down
6 changes: 2 additions & 4 deletions WebDriverAgentLib/Commands/FBCustomCommands.m
Original file line number Diff line number Diff line change
Expand Up @@ -423,10 +423,8 @@ + (NSDictionary *)processArguments:(XCUIApplication *)app
#endif
}];

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) {
// https://developer.apple.com/documentation/foundation/nsprocessinfothermalstate
deviceInfo[@"thermalState"] = @(NSProcessInfo.processInfo.thermalState);
}
// https://developer.apple.com/documentation/foundation/nsprocessinfothermalstate
deviceInfo[@"thermalState"] = @(NSProcessInfo.processInfo.thermalState);

return FBResponseWithObject(deviceInfo);
}
Expand Down
34 changes: 8 additions & 26 deletions WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.m
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,8 @@ - (CGPoint)fixedHitPointWith:(CGPoint)hitPoint forSnapshot:(id<FBXCElementSnapsh
// There is no need to recalculate anything for portrait orientation
return hitPoint;
}
CGRect appFrame = self.application.frame;
if (@available(iOS 13.0, *)) {
// For Xcode11 it is always necessary to adjust the tap point coordinates
return FBInvertPointForApplication(hitPoint, appFrame.size, interfaceOrientation);
}
NSArray<id<FBXCElementSnapshot>> *ancestors = [FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_ancestors;
id<FBXCElementSnapshot> parentWindow = ancestors.count > 1 ? [ancestors objectAtIndex:ancestors.count - 2] : nil;
CGRect parentWindowFrame = nil == parentWindow ? snapshot.frame : parentWindow.frame;
if ((appFrame.size.height > appFrame.size.width && parentWindowFrame.size.height < parentWindowFrame.size.width) ||
(appFrame.size.height < appFrame.size.width && parentWindowFrame.size.height > parentWindowFrame.size.width)) {
/*
This is the indication of the fact that transformation is broken and coordinates should be
recalculated manually.
However, upside-down case cannot be covered this way, which is not important for Appium
*/
return FBInvertPointForApplication(hitPoint, appFrame.size, interfaceOrientation);
}
return hitPoint;
// For Xcode11+ it is always necessary to adjust the tap point coordinates
return FBInvertPointForApplication(hitPoint, self.application.frame.size, interfaceOrientation);
}

- (nullable NSValue *)hitpointWithElement:(nullable XCUIElement *)element positionOffset:(nullable NSValue *)positionOffset error:(NSError **)error
Expand All @@ -74,14 +58,12 @@ - (nullable NSValue *)hitpointWithElement:(nullable XCUIElement *)element positi
if (nil == element) {
// Only absolute offset is defined
hitPoint = [positionOffset CGPointValue];
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) {
/*
Since iOS 10.0 XCTest has a bug when it always returns portrait coordinates for UI elements
even if the device is not in portait mode. That is why we need to recalculate them manually
based on the current orientation value
*/
hitPoint = FBInvertPointForApplication(hitPoint, self.application.frame.size, self.application.interfaceOrientation);
}
/*
Since iOS 10.0 XCTest has a bug when it always returns portrait coordinates for UI elements
even if the device is not in portait mode. That is why we need to recalculate them manually
based on the current orientation value
*/
hitPoint = FBInvertPointForApplication(hitPoint, self.application.frame.size, self.application.interfaceOrientation);
} else {
// The offset relative to the element is defined

Expand Down
3 changes: 1 addition & 2 deletions WebDriverAgentLib/Utilities/FBKeyboard.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ + (BOOL)waitUntilVisibleForApplication:(XCUIApplication *)app timeout:(NSTimeInt
}];
XCUIElement *firstKey = [[app.keyboard descendantsMatchingType:XCUIElementTypeKey]
matchingPredicate:keySearchPredicate].allElementsBoundByIndex.firstObject;
return firstKey.exists
&& (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"13.0") ? firstKey.hittable : firstKey.fb_isVisible);
return firstKey.exists && firstKey.hittable;
};
NSString* errMessage = @"The on-screen keyboard must be present to send keys";
if (timeout <= 0) {
Expand Down
11 changes: 2 additions & 9 deletions WebDriverAgentLib/Utilities/FBScreen.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,10 @@ + (double)scale

+ (CGSize)statusBarSizeForApplication:(XCUIApplication *)application
{
XCUIApplication *app = application;
BOOL expectVisibleBar = YES;

XCUIApplication *app = FBApplication.fb_systemApplication;
// Since iOS 13 the status bar is no longer part of the application, it’s part of the SpringBoard
if (@available(iOS 13.0, *)) {
app = FBApplication.fb_systemApplication;
expectVisibleBar = NO;
}

XCUIElement *mainStatusBar = app.statusBars.allElementsBoundByIndex.firstObject;
if (!mainStatusBar || (expectVisibleBar && !mainStatusBar.fb_isVisible)) {
if (nil == mainStatusBar) {
return CGSizeZero;
}
CGSize result = mainStatusBar.frame.size;
Expand Down
1 change: 0 additions & 1 deletion WebDriverAgentLib/Utilities/FBScreenshot.m
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ + (nullable id)imageEncodingWithUniformTypeIdentifier:(NSString *)uti
compressionQuality:(CGFloat)compressionQuality
error:(NSError **)error
{
// TODO: Use native accessors after we drop the support of Xcode 12.4 and below
Class imageEncodingClass = NSClassFromString(@"XCTImageEncoding");
if (nil == imageEncodingClass) {
[[[FBErrorBuilder builder]
Expand Down
4 changes: 1 addition & 3 deletions WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,7 @@ - (nullable NSValue *)positionWithError:(NSError **)error
}
CGPoint recentPosition = self.previousItem.atPosition;
CGPoint offsetRelativeToRecentPosition = (nil == x && nil == y) ? CGPointMake(0.0, 0.0) : CGPointMake(x.floatValue, y.floatValue);
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) {
offsetRelativeToRecentPosition = FBInvertOffsetForOrientation(offsetRelativeToRecentPosition, self.application.interfaceOrientation);
}
offsetRelativeToRecentPosition = FBInvertOffsetForOrientation(offsetRelativeToRecentPosition, self.application.interfaceOrientation);
return [NSValue valueWithCGPoint:CGPointMake(recentPosition.x + offsetRelativeToRecentPosition.x, recentPosition.y + offsetRelativeToRecentPosition.y)];
}

Expand Down

0 comments on commit bb562b9

Please sign in to comment.