diff --git a/PrivateHeaders/XCTest/XCUIApplication.h b/PrivateHeaders/XCTest/XCUIApplication.h index be785fbcd..8234f392c 100644 --- a/PrivateHeaders/XCTest/XCUIApplication.h +++ b/PrivateHeaders/XCTest/XCUIApplication.h @@ -53,7 +53,7 @@ - (id)application; - (id)description; - (id)lastSnapshot; -- (id)query; +- (XCUIElementQuery *)query; - (void)clearQuery; - (void)resolveHandleUIInterruption:(BOOL)arg1; - (id)initPrivateWithPath:(id)arg1 bundleID:(id)arg2; diff --git a/WebDriverAgent.xcodeproj/project.pbxproj b/WebDriverAgent.xcodeproj/project.pbxproj index b526275e7..8a607ba25 100644 --- a/WebDriverAgent.xcodeproj/project.pbxproj +++ b/WebDriverAgent.xcodeproj/project.pbxproj @@ -318,6 +318,9 @@ EE9B76AA1CF7A43900275851 /* FBMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9B76A51CF7A43900275851 /* FBMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; EEBBD48B1D47746D00656A81 /* XCUIElement+FBFind.h in Headers */ = {isa = PBXBuildFile; fileRef = EEBBD4891D47746D00656A81 /* XCUIElement+FBFind.h */; settings = {ATTRIBUTES = (Public, ); }; }; EEBBD48C1D47746D00656A81 /* XCUIElement+FBFind.m in Sources */ = {isa = PBXBuildFile; fileRef = EEBBD48A1D47746D00656A81 /* XCUIElement+FBFind.m */; }; + EEC9EED620064FAA00BC0D5B /* XCUICoordinate+FBFix.h in Headers */ = {isa = PBXBuildFile; fileRef = EEC9EED420064FAA00BC0D5B /* XCUICoordinate+FBFix.h */; }; + EEC9EED720064FAA00BC0D5B /* XCUICoordinate+FBFix.m in Sources */ = {isa = PBXBuildFile; fileRef = EEC9EED520064FAA00BC0D5B /* XCUICoordinate+FBFix.m */; }; + EEC9EED920077D8E00BC0D5B /* XCUICoordinateFix.m in Sources */ = {isa = PBXBuildFile; fileRef = EEC9EED820077D8E00BC0D5B /* XCUICoordinateFix.m */; }; EEDFE1211D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = EEDFE11F1D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.h */; settings = {ATTRIBUTES = (Public, ); }; }; EEDFE1221D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDFE1201D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.m */; }; EEE16E971D33A25500172525 /* FBConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EEE16E961D33A25500172525 /* FBConfigurationTests.m */; }; @@ -743,6 +746,9 @@ EEC088E71CB56DA400B65968 /* FBExceptionHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBExceptionHandler.m; sourceTree = ""; }; EEC088EA1CB5706D00B65968 /* FBSpringboardApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSpringboardApplication.h; path = WebDriverAgentLib/FBSpringboardApplication.h; sourceTree = SOURCE_ROOT; }; EEC088EB1CB5706D00B65968 /* FBSpringboardApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSpringboardApplication.m; path = WebDriverAgentLib/FBSpringboardApplication.m; sourceTree = SOURCE_ROOT; }; + EEC9EED420064FAA00BC0D5B /* XCUICoordinate+FBFix.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XCUICoordinate+FBFix.h"; sourceTree = ""; }; + EEC9EED520064FAA00BC0D5B /* XCUICoordinate+FBFix.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "XCUICoordinate+FBFix.m"; sourceTree = ""; }; + EEC9EED820077D8E00BC0D5B /* XCUICoordinateFix.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XCUICoordinateFix.m; sourceTree = ""; }; EEDBEBBA1CB2681900A790A2 /* WebDriverAgent.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = WebDriverAgent.bundle; sourceTree = ""; }; EEDFE11F1D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "XCUIDevice+FBHealthCheck.h"; sourceTree = ""; }; EEDFE1201D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "XCUIDevice+FBHealthCheck.m"; sourceTree = ""; }; @@ -936,6 +942,8 @@ EE006EAF1EBA1AA9006900A4 /* XCElementSnapshot+FBHitPoint.m */, AD6C269A1CF2494200F8B5FF /* XCUIApplication+FBHelpers.h */, AD6C269B1CF2494200F8B5FF /* XCUIApplication+FBHelpers.m */, + EEC9EED420064FAA00BC0D5B /* XCUICoordinate+FBFix.h */, + EEC9EED520064FAA00BC0D5B /* XCUICoordinate+FBFix.m */, 71BD20711F86116100B36EC2 /* XCUIApplication+FBTouchAction.h */, 71BD20721F86116100B36EC2 /* XCUIApplication+FBTouchAction.m */, EEDFE11F1D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.h */, @@ -960,10 +968,10 @@ EE9AB74C1CAEDF0C008C271F /* XCUIElement+FBTap.m */, AD76723B1D6B7CC000610457 /* XCUIElement+FBTyping.h */, AD76723C1D6B7CC000610457 /* XCUIElement+FBTyping.m */, - EEE3763F1D59F81400ED88DD /* XCUIElement+FBUtilities.h */, - EEE376401D59F81400ED88DD /* XCUIElement+FBUtilities.m */, 71B49EC51ED1A58100D51AD6 /* XCUIElement+FBUID.h */, 71B49EC61ED1A58100D51AD6 /* XCUIElement+FBUID.m */, + EEE3763F1D59F81400ED88DD /* XCUIElement+FBUtilities.h */, + EEE376401D59F81400ED88DD /* XCUIElement+FBUtilities.m */, EEE376471D59FAE900ED88DD /* XCUIElement+FBWebDriverAttributes.h */, EEE376481D59FAE900ED88DD /* XCUIElement+FBWebDriverAttributes.m */, ); @@ -1159,25 +1167,26 @@ isa = PBXGroup; children = ( ADBC39951D07840300327304 /* Doubles */, - EEE16E961D33A25500172525 /* FBConfigurationTests.m */, 71A7EAFB1E229302001DA4F2 /* FBClassChainTests.m */, + EEE16E961D33A25500172525 /* FBConfigurationTests.m */, ADBC39931D0782CD00327304 /* FBElementCacheTests.m */, - 719FF5B81DAD21F5008E0099 /* FBElementUtilitiesTests.m */, EE3F8CFF1D08B05F006F02CE /* FBElementTypeTransformerTests.m */, + 719FF5B81DAD21F5008E0099 /* FBElementUtilitiesTests.m */, EE6A892C1D0B2AF40083E92B /* FBErrorBuilderTests.m */, + EE18883C1DA663EB00307AA8 /* FBMathUtilsTests.m */, EE9B76571CF7987300275851 /* FBRouteTests.m */, EE3F8CFD1D08AA17006F02CE /* FBRunLoopSpinnerTests.m */, ADEF63AE1D09DEBE0070A7E3 /* FBRuntimeUtilsTests.m */, + 714801D01FA9D9FA00DC5997 /* FBSDKVersionTests.m */, EE6A89251D0B19E60083E92B /* FBSessionTests.m */, + 716E0BD01E917F260087A825 /* FBXMLSafeStringTests.m */, + ADEF63AC1D09DCCF0070A7E3 /* FBXPathCreatorTests.m */, 712A0C841DA3E459007D02E5 /* FBXPathTests.m */, + EE9B76581CF7987300275851 /* Info.plist */, 7139145B1DF01A12005896C2 /* NSExpressionFBFormatTests.m */, 71A224E71DE326C500844D55 /* NSPredicateFBFormatTests.m */, - 714801D01FA9D9FA00DC5997 /* FBSDKVersionTests.m */, - ADEF63AC1D09DCCF0070A7E3 /* FBXPathCreatorTests.m */, - EE18883C1DA663EB00307AA8 /* FBMathUtilsTests.m */, + EEC9EED820077D8E00BC0D5B /* XCUICoordinateFix.m */, 713914591DF01989005896C2 /* XCUIElementHelpersTests.m */, - 716E0BD01E917F260087A825 /* FBXMLSafeStringTests.m */, - EE9B76581CF7987300275851 /* Info.plist */, ); path = UnitTests; sourceTree = ""; @@ -1422,6 +1431,7 @@ EE35AD721E3B77D600A02D78 /* XCUIElementHitPointCoordinate.h in Headers */, EE35AD3F1E3B77D600A02D78 /* XCTDarwinNotificationExpectation.h in Headers */, EE35AD5F1E3B77D600A02D78 /* XCTRunnerAutomationSession.h in Headers */, + EEC9EED620064FAA00BC0D5B /* XCUICoordinate+FBFix.h in Headers */, EE35AD371E3B77D600A02D78 /* XCSourceCodeTreeNodeEnumerator.h in Headers */, EE158AB01CBD456F00A3E3F0 /* XCUIElement+FBIsVisible.h in Headers */, EE158AF11CBD456F00A3E3F0 /* FBXPathCreator.h in Headers */, @@ -1848,6 +1858,7 @@ 716E0BCF1E917E810087A825 /* NSString+FBXMLSafeString.m in Sources */, EE158ACD1CBD456F00A3E3F0 /* FBUnknownCommands.m in Sources */, EE158AC51CBD456F00A3E3F0 /* FBOrientationCommands.m in Sources */, + EEC9EED720064FAA00BC0D5B /* XCUICoordinate+FBFix.m in Sources */, EE158AEB1CBD456F00A3E3F0 /* FBRuntimeUtils.m in Sources */, EEE376461D59F81400ED88DD /* XCUIElement+FBUtilities.m in Sources */, EE9B76A91CF7A43900275851 /* FBLogger.m in Sources */, @@ -1938,6 +1949,7 @@ ADBC39981D07842800327304 /* XCUIElementDouble.m in Sources */, 7139145A1DF01989005896C2 /* XCUIElementHelpersTests.m in Sources */, EE6A89261D0B19E60083E92B /* FBSessionTests.m in Sources */, + EEC9EED920077D8E00BC0D5B /* XCUICoordinateFix.m in Sources */, 71A7EAFC1E229302001DA4F2 /* FBClassChainTests.m in Sources */, EE18883D1DA663EB00307AA8 /* FBMathUtilsTests.m in Sources */, ); diff --git a/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.h b/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.h new file mode 100644 index 000000000..55742a95c --- /dev/null +++ b/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.h @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +@interface XCUICoordinate (FBFix) + +- (CGPoint)fb_screenPoint; + +@end diff --git a/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.m b/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.m new file mode 100644 index 000000000..6b6aa62c3 --- /dev/null +++ b/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.m @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "XCUICoordinate+FBFix.h" + +#import "XCUICoordinate.h" +#import "XCUIElement+FBUtilities.h" +#import "XCElementSnapshot+FBHitPoint.h" + +@implementation XCUICoordinate (FBFix) + +- (CGPoint)fb_screenPoint +{ + CGPoint referencePoint = CGPointMake(0, 0); + if (self.element) { + CGRect frame = self.element.frame; + referencePoint = CGPointMake( + CGRectGetMinX(frame) + CGRectGetWidth(frame) * self.normalizedOffset.dx, + CGRectGetMinY(frame) + CGRectGetHeight(frame) * self.normalizedOffset.dy); + } + else if (self.coordinate) { + referencePoint = self.coordinate.fb_screenPoint; + } + CGPoint screenPoint = CGPointMake( + referencePoint.x + self.pointsOffset.dx, + referencePoint.y + self.pointsOffset.dy); + CGRect rect = self.referencedElement.frame; + return CGPointMake( + MIN(CGRectGetMaxX(rect), screenPoint.x), + MIN(CGRectGetMaxY(rect), screenPoint.y)); +} + +@end diff --git a/WebDriverAgentLib/Categories/XCUIDevice+FBRotation.m b/WebDriverAgentLib/Categories/XCUIDevice+FBRotation.m index e3da61fc5..c25e0f1f7 100644 --- a/WebDriverAgentLib/Categories/XCUIDevice+FBRotation.m +++ b/WebDriverAgentLib/Categories/XCUIDevice+FBRotation.m @@ -36,13 +36,15 @@ - (BOOL)fb_setDeviceRotation:(NSDictionary *)rotationObj - (BOOL)waitUntilInterfaceIsAtOrientation:(NSInteger)orientation application:(FBApplication *)application { NSDate *startDate = [NSDate date]; - while (![@(application.interfaceOrientation) isEqualToNumber:@(orientation)] && (-1 * [startDate timeIntervalSinceNow]) < kFBWebDriverOrientationChangeDelay) { + while (application.interfaceOrientation != orientation && + [XCUIDevice sharedDevice].orientation != orientation && + (-1 * [startDate timeIntervalSinceNow]) < kFBWebDriverOrientationChangeDelay) { CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.3, YES); } // Tapping elements immediately after rotation may fail due to way UIKit is handling touches. // We should wait till UI cools off, before continuing [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:FBRotationCoolOffTime]]; - return [@(application.interfaceOrientation) isEqualToNumber:@(orientation)]; + return application.interfaceOrientation == orientation; } - (NSDictionary *)fb_rotationMapping diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBScrolling.m b/WebDriverAgentLib/Categories/XCUIElement+FBScrolling.m index 4c91970c8..08c4d5c96 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBScrolling.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBScrolling.m @@ -20,6 +20,7 @@ #import "XCElementSnapshot.h" #import "XCUIApplication.h" #import "XCUICoordinate.h" +#import "XCUICoordinate+FBFix.h" #import "XCUIElement+FBIsVisible.h" #import "XCUIElement.h" #import "XCUIElement+FBUtilities.h" @@ -199,6 +200,11 @@ - (BOOL)fb_isEquivalentElementSnapshotVisible:(XCElementSnapshot *)snapshot @implementation XCElementSnapshot (FBScrolling) +- (CGRect)scrollingFrame +{ + return self.visibleFrame; +} + - (void)fb_scrollUpByNormalizedDistance:(CGFloat)distance inApplication:(XCUIApplication *)application { [self fb_scrollByNormalizedVector:CGVectorMake(0.0, distance) inApplication:application]; @@ -221,20 +227,20 @@ - (void)fb_scrollRightByNormalizedDistance:(CGFloat)distance inApplication:(XCUI - (BOOL)fb_scrollByNormalizedVector:(CGVector)normalizedScrollVector inApplication:(XCUIApplication *)application { - CGVector scrollVector = CGVectorMake(CGRectGetWidth(self.frame) * normalizedScrollVector.dx, - CGRectGetHeight(self.frame) * normalizedScrollVector.dy + CGVector scrollVector = CGVectorMake(CGRectGetWidth(self.scrollingFrame) * normalizedScrollVector.dx, + CGRectGetHeight(self.scrollingFrame) * normalizedScrollVector.dy ); return [self fb_scrollByVector:scrollVector inApplication:application error:nil]; } - (BOOL)fb_scrollByVector:(CGVector)vector inApplication:(XCUIApplication *)application error:(NSError **)error { - CGVector scrollBoundingVector = CGVectorMake(CGRectGetWidth(self.frame) * FBScrollTouchProportion - FBScrollBoundingVelocityPadding, - CGRectGetHeight(self.frame)* FBScrollTouchProportion - FBScrollBoundingVelocityPadding + CGVector scrollBoundingVector = CGVectorMake(CGRectGetWidth(self.scrollingFrame) * FBScrollTouchProportion - FBScrollBoundingVelocityPadding, + CGRectGetHeight(self.scrollingFrame)* FBScrollTouchProportion - FBScrollBoundingVelocityPadding ); scrollBoundingVector.dx = (CGFloat)floor(copysign(scrollBoundingVector.dx, vector.dx)); scrollBoundingVector.dy = (CGFloat)floor(copysign(scrollBoundingVector.dy, vector.dy)); - + NSUInteger scrollLimit = 100; BOOL shouldFinishScrolling = NO; while (!shouldFinishScrolling) { @@ -252,8 +258,8 @@ - (BOOL)fb_scrollByVector:(CGVector)vector inApplication:(XCUIApplication *)appl - (CGVector)fb_hitPointOffsetForScrollingVector:(CGVector)scrollingVector { - CGFloat x = CGRectGetMinX(self.frame) + CGRectGetWidth(self.frame) * (scrollingVector.dx < 0.0f ? FBScrollTouchProportion : (1 - FBScrollTouchProportion)); - CGFloat y = CGRectGetMinY(self.frame) + CGRectGetHeight(self.frame) * (scrollingVector.dy < 0.0f ? FBScrollTouchProportion : (1 - FBScrollTouchProportion)); + CGFloat x = CGRectGetMinX(self.scrollingFrame) + CGRectGetWidth(self.scrollingFrame) * (scrollingVector.dx < 0.0f ? FBScrollTouchProportion : (1 - FBScrollTouchProportion)); + CGFloat y = CGRectGetMinY(self.scrollingFrame) + CGRectGetHeight(self.scrollingFrame) * (scrollingVector.dy < 0.0f ? FBScrollTouchProportion : (1 - FBScrollTouchProportion)); return CGVectorMake((CGFloat)floor(x), (CGFloat)floor(y)); } @@ -265,7 +271,7 @@ - (BOOL)fb_scrollAncestorScrollViewByVectorWithinScrollViewFrame:(CGVector)vecto XCUICoordinate *startCoordinate = [[XCUICoordinate alloc] initWithCoordinate:appCoordinate pointsOffset:hitpointOffset]; XCUICoordinate *endCoordinate = [[XCUICoordinate alloc] initWithCoordinate:startCoordinate pointsOffset:vector]; - if (FBPointFuzzyEqualToPoint(startCoordinate.screenPoint, endCoordinate.screenPoint, FBFuzzyPointThreshold)) { + if (FBPointFuzzyEqualToPoint(startCoordinate.fb_screenPoint, endCoordinate.fb_screenPoint, FBFuzzyPointThreshold)) { return YES; } diff --git a/WebDriverAgentTests/IntegrationApp/Classes/ViewController.m b/WebDriverAgentTests/IntegrationApp/Classes/ViewController.m index 044e6b20a..6014a5674 100644 --- a/WebDriverAgentTests/IntegrationApp/Classes/ViewController.m +++ b/WebDriverAgentTests/IntegrationApp/Classes/ViewController.m @@ -10,6 +10,7 @@ #import "ViewController.h" @interface ViewController () +@property (weak, nonatomic) IBOutlet UILabel *orentationLabel; @end @implementation ViewController @@ -26,4 +27,33 @@ - (IBAction)didTapButton:(UIButton *)button button.selected = !button.selected; } +- (void)viewDidLayoutSubviews +{ + [super viewDidLayoutSubviews]; + [self updateOrentationLabel]; +} + +- (void)updateOrentationLabel +{ + NSString *orientation = nil; + switch (self.interfaceOrientation) { + case UIInterfaceOrientationPortrait: + orientation = @"Portrait"; + break; + case UIInterfaceOrientationPortraitUpsideDown: + orientation = @"PortraitUpsideDown"; + break; + case UIInterfaceOrientationLandscapeLeft: + orientation = @"LandscapeLeft"; + break; + case UIInterfaceOrientationLandscapeRight: + orientation = @"LandscapeRight"; + break; + case UIInterfaceOrientationUnknown: + orientation = @"Unknown"; + break; + } + self.orentationLabel.text = orientation; +} + @end diff --git a/WebDriverAgentTests/IntegrationApp/Resources/Base.lproj/Main.storyboard b/WebDriverAgentTests/IntegrationApp/Resources/Base.lproj/Main.storyboard index 183eff8f1..dc82b12b0 100644 --- a/WebDriverAgentTests/IntegrationApp/Resources/Base.lproj/Main.storyboard +++ b/WebDriverAgentTests/IntegrationApp/Resources/Base.lproj/Main.storyboard @@ -1,11 +1,11 @@ - + - + @@ -63,6 +63,12 @@ + @@ -71,17 +77,22 @@ + + + + + - + @@ -460,7 +471,7 @@