appium-webdriveragent 5.0.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/WebDriverAgent.xcodeproj/project.pbxproj +0 -20
- package/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.m +0 -12
- package/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m +1 -15
- package/WebDriverAgentLib/Categories/XCUIElement+FBScrolling.m +7 -37
- package/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.h +0 -7
- package/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m +0 -49
- package/WebDriverAgentLib/Commands/FBElementCommands.m +37 -19
- package/WebDriverAgentLib/Utilities/FBAppiumActionsSynthesizer.m +23 -15
- package/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.h +4 -13
- package/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.m +36 -56
- package/WebDriverAgentLib/Utilities/FBMathUtils.h +0 -6
- package/WebDriverAgentLib/Utilities/FBMathUtils.m +0 -29
- package/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m +23 -29
- package/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.h +0 -4
- package/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m +0 -12
- package/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m +0 -16
- package/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m +0 -19
- package/WebDriverAgentTests/UnitTests/FBMathUtilsTests.m +0 -12
- package/package.json +1 -1
- package/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.h +0 -18
- package/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.m +0 -46
- package/WebDriverAgentTests/IntegrationTests/FBElementScreenshotTests.m +0 -52
- package/WebDriverAgentTests/UnitTests/XCUICoordinateFix.m +0 -63
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [5.1.0](https://github.com/appium/WebDriverAgent/compare/v5.0.0...v5.1.0) (2023-05-14)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* Add a possibility to provide a target picker value ([#699](https://github.com/appium/WebDriverAgent/issues/699)) ([fc76aee](https://github.com/appium/WebDriverAgent/commit/fc76aeecb087429974b7b52b725173186e6f0246))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Code Refactoring
|
|
10
|
+
|
|
11
|
+
* Remove obsolete coordinate calculation workarounds needed for older xCode SDKs ([#698](https://github.com/appium/WebDriverAgent/issues/698)) ([025b42c](https://github.com/appium/WebDriverAgent/commit/025b42c8a34ff0beba4379f4cb0c1d79d2b222ed))
|
|
12
|
+
|
|
1
13
|
## [5.0.0](https://github.com/appium/WebDriverAgent/compare/v4.15.1...v5.0.0) (2023-05-14)
|
|
2
14
|
|
|
3
15
|
|
|
@@ -86,7 +86,6 @@
|
|
|
86
86
|
641EE6042240C5CA00173FCB /* NSString+FBXMLSafeString.m in Sources */ = {isa = PBXBuildFile; fileRef = 716E0BCD1E917E810087A825 /* NSString+FBXMLSafeString.m */; };
|
|
87
87
|
641EE6052240C5CA00173FCB /* FBUnknownCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB7651CAEDF0C008C271F /* FBUnknownCommands.m */; };
|
|
88
88
|
641EE6062240C5CA00173FCB /* FBOrientationCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB75D1CAEDF0C008C271F /* FBOrientationCommands.m */; };
|
|
89
|
-
641EE6072240C5CA00173FCB /* XCUICoordinate+FBFix.m in Sources */ = {isa = PBXBuildFile; fileRef = EEC9EED520064FAA00BC0D5B /* XCUICoordinate+FBFix.m */; };
|
|
90
89
|
641EE6082240C5CA00173FCB /* FBRuntimeUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB7921CAEDF0C008C271F /* FBRuntimeUtils.m */; };
|
|
91
90
|
641EE6092240C5CA00173FCB /* XCUIElement+FBUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = EEE376401D59F81400ED88DD /* XCUIElement+FBUtilities.m */; };
|
|
92
91
|
641EE60A2240C5CA00173FCB /* FBLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9B76A41CF7A43900275851 /* FBLogger.m */; };
|
|
@@ -160,7 +159,6 @@
|
|
|
160
159
|
641EE65B2240C5CA00173FCB /* XCUIElementHitPointCoordinate.h in Headers */ = {isa = PBXBuildFile; fileRef = EE35AD011E3B77D600A02D78 /* XCUIElementHitPointCoordinate.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
161
160
|
641EE65C2240C5CA00173FCB /* XCTDarwinNotificationExpectation.h in Headers */ = {isa = PBXBuildFile; fileRef = EE35ACCE1E3B77D600A02D78 /* XCTDarwinNotificationExpectation.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
162
161
|
641EE65D2240C5CA00173FCB /* XCTRunnerAutomationSession.h in Headers */ = {isa = PBXBuildFile; fileRef = EE35ACEE1E3B77D600A02D78 /* XCTRunnerAutomationSession.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
163
|
-
641EE65E2240C5CA00173FCB /* XCUICoordinate+FBFix.h in Headers */ = {isa = PBXBuildFile; fileRef = EEC9EED420064FAA00BC0D5B /* XCUICoordinate+FBFix.h */; };
|
|
164
162
|
641EE65F2240C5CA00173FCB /* XCSourceCodeTreeNodeEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = EE35ACC61E3B77D600A02D78 /* XCSourceCodeTreeNodeEnumerator.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
165
163
|
641EE6602240C5CA00173FCB /* XCUIElement+FBIsVisible.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB7471CAEDF0C008C271F /* XCUIElement+FBIsVisible.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
166
164
|
641EE6612240C5CA00173FCB /* XCUIElement+FBTap.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB74B1CAEDF0C008C271F /* XCUIElement+FBTap.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
@@ -456,7 +454,6 @@
|
|
|
456
454
|
71A7EAF91E224648001DA4F2 /* FBClassChainQueryParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A7EAF71E224648001DA4F2 /* FBClassChainQueryParser.h */; };
|
|
457
455
|
71A7EAFA1E224648001DA4F2 /* FBClassChainQueryParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 71A7EAF81E224648001DA4F2 /* FBClassChainQueryParser.m */; };
|
|
458
456
|
71A7EAFC1E229302001DA4F2 /* FBClassChainTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 71A7EAFB1E229302001DA4F2 /* FBClassChainTests.m */; };
|
|
459
|
-
71AB82B21FDAE8C000D1D7C3 /* FBElementScreenshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 71AB82B11FDAE8C000D1D7C3 /* FBElementScreenshotTests.m */; };
|
|
460
457
|
71ACF5B8242F2FDC00F0AAD4 /* FBSafariAlertTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 71ACF5B7242F2FDC00F0AAD4 /* FBSafariAlertTests.m */; };
|
|
461
458
|
71B155DA23070ECF00646AFB /* FBHTTPStatusCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 71B155D923070ECF00646AFB /* FBHTTPStatusCodes.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
462
459
|
71B155DC230711E900646AFB /* FBCommandStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 71B155DB230711E900646AFB /* FBCommandStatus.m */; };
|
|
@@ -785,9 +782,6 @@
|
|
|
785
782
|
EE9B76AA1CF7A43900275851 /* FBMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9B76A51CF7A43900275851 /* FBMacros.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
786
783
|
EEBBD48B1D47746D00656A81 /* XCUIElement+FBFind.h in Headers */ = {isa = PBXBuildFile; fileRef = EEBBD4891D47746D00656A81 /* XCUIElement+FBFind.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
787
784
|
EEBBD48C1D47746D00656A81 /* XCUIElement+FBFind.m in Sources */ = {isa = PBXBuildFile; fileRef = EEBBD48A1D47746D00656A81 /* XCUIElement+FBFind.m */; };
|
|
788
|
-
EEC9EED620064FAA00BC0D5B /* XCUICoordinate+FBFix.h in Headers */ = {isa = PBXBuildFile; fileRef = EEC9EED420064FAA00BC0D5B /* XCUICoordinate+FBFix.h */; };
|
|
789
|
-
EEC9EED720064FAA00BC0D5B /* XCUICoordinate+FBFix.m in Sources */ = {isa = PBXBuildFile; fileRef = EEC9EED520064FAA00BC0D5B /* XCUICoordinate+FBFix.m */; };
|
|
790
|
-
EEC9EED920077D8E00BC0D5B /* XCUICoordinateFix.m in Sources */ = {isa = PBXBuildFile; fileRef = EEC9EED820077D8E00BC0D5B /* XCUICoordinateFix.m */; };
|
|
791
785
|
EEDFE1211D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = EEDFE11F1D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
792
786
|
EEDFE1221D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDFE1201D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.m */; };
|
|
793
787
|
EEE16E971D33A25500172525 /* FBConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EEE16E961D33A25500172525 /* FBConfigurationTests.m */; };
|
|
@@ -1043,7 +1037,6 @@
|
|
|
1043
1037
|
71A7EAF71E224648001DA4F2 /* FBClassChainQueryParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBClassChainQueryParser.h; sourceTree = "<group>"; };
|
|
1044
1038
|
71A7EAF81E224648001DA4F2 /* FBClassChainQueryParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBClassChainQueryParser.m; sourceTree = "<group>"; };
|
|
1045
1039
|
71A7EAFB1E229302001DA4F2 /* FBClassChainTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBClassChainTests.m; sourceTree = "<group>"; };
|
|
1046
|
-
71AB82B11FDAE8C000D1D7C3 /* FBElementScreenshotTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBElementScreenshotTests.m; sourceTree = "<group>"; };
|
|
1047
1040
|
71ACF5B7242F2FDC00F0AAD4 /* FBSafariAlertTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSafariAlertTests.m; sourceTree = "<group>"; };
|
|
1048
1041
|
71B155D923070ECF00646AFB /* FBHTTPStatusCodes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBHTTPStatusCodes.h; sourceTree = "<group>"; };
|
|
1049
1042
|
71B155DB230711E900646AFB /* FBCommandStatus.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBCommandStatus.m; sourceTree = "<group>"; };
|
|
@@ -1353,9 +1346,6 @@
|
|
|
1353
1346
|
EEC088E41CB56AC000B65968 /* FBElementCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBElementCache.m; sourceTree = "<group>"; };
|
|
1354
1347
|
EEC088E61CB56DA400B65968 /* FBExceptionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBExceptionHandler.h; sourceTree = "<group>"; };
|
|
1355
1348
|
EEC088E71CB56DA400B65968 /* FBExceptionHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBExceptionHandler.m; sourceTree = "<group>"; };
|
|
1356
|
-
EEC9EED420064FAA00BC0D5B /* XCUICoordinate+FBFix.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XCUICoordinate+FBFix.h"; sourceTree = "<group>"; };
|
|
1357
|
-
EEC9EED520064FAA00BC0D5B /* XCUICoordinate+FBFix.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "XCUICoordinate+FBFix.m"; sourceTree = "<group>"; };
|
|
1358
|
-
EEC9EED820077D8E00BC0D5B /* XCUICoordinateFix.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XCUICoordinateFix.m; sourceTree = "<group>"; };
|
|
1359
1349
|
EEDBEBBA1CB2681900A790A2 /* WebDriverAgent.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = WebDriverAgent.bundle; sourceTree = "<group>"; };
|
|
1360
1350
|
EEDFE11F1D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "XCUIDevice+FBHealthCheck.h"; sourceTree = "<group>"; };
|
|
1361
1351
|
EEDFE1201D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "XCUIDevice+FBHealthCheck.m"; sourceTree = "<group>"; };
|
|
@@ -1737,8 +1727,6 @@
|
|
|
1737
1727
|
716C9DFF27315EFF005AD475 /* XCUIApplication+FBUIInterruptions.m */,
|
|
1738
1728
|
71D475C02538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.h */,
|
|
1739
1729
|
71D475C12538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.m */,
|
|
1740
|
-
EEC9EED420064FAA00BC0D5B /* XCUICoordinate+FBFix.h */,
|
|
1741
|
-
EEC9EED520064FAA00BC0D5B /* XCUICoordinate+FBFix.m */,
|
|
1742
1730
|
719CD8FA2126C88B00C7D0C2 /* XCUIApplication+FBAlert.h */,
|
|
1743
1731
|
719CD8FB2126C88B00C7D0C2 /* XCUIApplication+FBAlert.m */,
|
|
1744
1732
|
71BD20711F86116100B36EC2 /* XCUIApplication+FBTouchAction.h */,
|
|
@@ -1985,7 +1973,6 @@
|
|
|
1985
1973
|
719A97AB1F88E7370063B4BD /* FBAppiumMultiTouchActionsIntegrationTests.m */,
|
|
1986
1974
|
719CD8FE2126C90200C7D0C2 /* FBAutoAlertsHandlerTests.m */,
|
|
1987
1975
|
EE26409C1D0EBA25009BE6B0 /* FBElementAttributeTests.m */,
|
|
1988
|
-
71AB82B11FDAE8C000D1D7C3 /* FBElementScreenshotTests.m */,
|
|
1989
1976
|
71F5BE33252E5B2200EE9EBA /* FBElementSwipingTests.m */,
|
|
1990
1977
|
EE006EAC1EB99B15006900A4 /* FBElementVisibilityTests.m */,
|
|
1991
1978
|
EE6A89361D0B35920083E92B /* FBFailureProofTestCaseTests.m */,
|
|
@@ -2045,7 +2032,6 @@
|
|
|
2045
2032
|
EE9B76581CF7987300275851 /* Info.plist */,
|
|
2046
2033
|
7139145B1DF01A12005896C2 /* NSExpressionFBFormatTests.m */,
|
|
2047
2034
|
71A224E71DE326C500844D55 /* NSPredicateFBFormatTests.m */,
|
|
2048
|
-
EEC9EED820077D8E00BC0D5B /* XCUICoordinateFix.m */,
|
|
2049
2035
|
713914591DF01989005896C2 /* XCUIElementHelpersTests.m */,
|
|
2050
2036
|
);
|
|
2051
2037
|
path = UnitTests;
|
|
@@ -2311,7 +2297,6 @@
|
|
|
2311
2297
|
641EE65B2240C5CA00173FCB /* XCUIElementHitPointCoordinate.h in Headers */,
|
|
2312
2298
|
641EE65C2240C5CA00173FCB /* XCTDarwinNotificationExpectation.h in Headers */,
|
|
2313
2299
|
641EE65D2240C5CA00173FCB /* XCTRunnerAutomationSession.h in Headers */,
|
|
2314
|
-
641EE65E2240C5CA00173FCB /* XCUICoordinate+FBFix.h in Headers */,
|
|
2315
2300
|
641EE65F2240C5CA00173FCB /* XCSourceCodeTreeNodeEnumerator.h in Headers */,
|
|
2316
2301
|
641EE6602240C5CA00173FCB /* XCUIElement+FBIsVisible.h in Headers */,
|
|
2317
2302
|
641EE6612240C5CA00173FCB /* XCUIElement+FBTap.h in Headers */,
|
|
@@ -2548,7 +2533,6 @@
|
|
|
2548
2533
|
EE35AD3F1E3B77D600A02D78 /* XCTDarwinNotificationExpectation.h in Headers */,
|
|
2549
2534
|
EE35AD5F1E3B77D600A02D78 /* XCTRunnerAutomationSession.h in Headers */,
|
|
2550
2535
|
71C9EAAC25E8415A00470CD8 /* FBScreenshot.h in Headers */,
|
|
2551
|
-
EEC9EED620064FAA00BC0D5B /* XCUICoordinate+FBFix.h in Headers */,
|
|
2552
2536
|
EE35AD371E3B77D600A02D78 /* XCSourceCodeTreeNodeEnumerator.h in Headers */,
|
|
2553
2537
|
EE158AB01CBD456F00A3E3F0 /* XCUIElement+FBIsVisible.h in Headers */,
|
|
2554
2538
|
71414ED42670A1EE003A8C5D /* LRUCache.h in Headers */,
|
|
@@ -3141,7 +3125,6 @@
|
|
|
3141
3125
|
641EE6052240C5CA00173FCB /* FBUnknownCommands.m in Sources */,
|
|
3142
3126
|
641EE6062240C5CA00173FCB /* FBOrientationCommands.m in Sources */,
|
|
3143
3127
|
641EE7092240CDEB00173FCB /* XCUIElement+FBTVFocuse.m in Sources */,
|
|
3144
|
-
641EE6072240C5CA00173FCB /* XCUICoordinate+FBFix.m in Sources */,
|
|
3145
3128
|
641EE6082240C5CA00173FCB /* FBRuntimeUtils.m in Sources */,
|
|
3146
3129
|
641EE6092240C5CA00173FCB /* XCUIElement+FBUtilities.m in Sources */,
|
|
3147
3130
|
641EE60A2240C5CA00173FCB /* FBLogger.m in Sources */,
|
|
@@ -3259,7 +3242,6 @@
|
|
|
3259
3242
|
EE158AC51CBD456F00A3E3F0 /* FBOrientationCommands.m in Sources */,
|
|
3260
3243
|
71D475C42538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.m in Sources */,
|
|
3261
3244
|
641EE7082240CDEB00173FCB /* XCUIElement+FBTVFocuse.m in Sources */,
|
|
3262
|
-
EEC9EED720064FAA00BC0D5B /* XCUICoordinate+FBFix.m in Sources */,
|
|
3263
3245
|
71E75E6F254824230099FC87 /* XCUIElementQuery+FBHelpers.m in Sources */,
|
|
3264
3246
|
71D04DCA25356C43008A052C /* XCUIElement+FBCaching.m in Sources */,
|
|
3265
3247
|
EE158AEB1CBD456F00A3E3F0 /* FBRuntimeUtils.m in Sources */,
|
|
@@ -3330,7 +3312,6 @@
|
|
|
3330
3312
|
715AFAC41FFA2AAF0053896D /* FBScreenTests.m in Sources */,
|
|
3331
3313
|
EE22021E1ECC618900A29571 /* FBTapTest.m in Sources */,
|
|
3332
3314
|
71930C472066434000D3AFEC /* FBPasteboardTests.m in Sources */,
|
|
3333
|
-
71AB82B21FDAE8C000D1D7C3 /* FBElementScreenshotTests.m in Sources */,
|
|
3334
3315
|
7150FFF722476B3A00B2EE28 /* FBForceTouchTests.m in Sources */,
|
|
3335
3316
|
);
|
|
3336
3317
|
runOnlyForDeploymentPostprocessing = 0;
|
|
@@ -3382,7 +3363,6 @@
|
|
|
3382
3363
|
ADBC39981D07842800327304 /* XCUIElementDouble.m in Sources */,
|
|
3383
3364
|
7139145A1DF01989005896C2 /* XCUIElementHelpersTests.m in Sources */,
|
|
3384
3365
|
EE6A89261D0B19E60083E92B /* FBSessionTests.m in Sources */,
|
|
3385
|
-
EEC9EED920077D8E00BC0D5B /* XCUICoordinateFix.m in Sources */,
|
|
3386
3366
|
71A7EAFC1E229302001DA4F2 /* FBClassChainTests.m in Sources */,
|
|
3387
3367
|
EE18883D1DA663EB00307AA8 /* FBMathUtilsTests.m in Sources */,
|
|
3388
3368
|
);
|
|
@@ -186,18 +186,6 @@
|
|
|
186
186
|
}
|
|
187
187
|
CGPoint midPoint = CGPointMake(visibleRect.origin.x + visibleRect.size.width / 2,
|
|
188
188
|
visibleRect.origin.y + visibleRect.size.height / 2);
|
|
189
|
-
#if !TARGET_OS_TV // TV has no orientation, so it does not need to coordinate
|
|
190
|
-
id<FBXCElementSnapshot> appElement = ancestors.count > 0 ? [ancestors lastObject] : self;
|
|
191
|
-
CGRect appFrame = appElement.frame;
|
|
192
|
-
CGRect windowFrame = nil == parentWindow ? selfFrame : parentWindow.frame;
|
|
193
|
-
if ((appFrame.size.height > appFrame.size.width && windowFrame.size.height < windowFrame.size.width) ||
|
|
194
|
-
(appFrame.size.height < appFrame.size.width && windowFrame.size.height > windowFrame.size.width)) {
|
|
195
|
-
// This is the indication of the fact that transformation is broken and coordinates should be
|
|
196
|
-
// recalculated manually.
|
|
197
|
-
// However, upside-down case cannot be covered this way, which is not important for Appium
|
|
198
|
-
midPoint = FBInvertPointForApplication(midPoint, appFrame.size, FBApplication.fb_activeApplication.interfaceOrientation);
|
|
199
|
-
}
|
|
200
|
-
#endif
|
|
201
189
|
id<FBXCAccessibilityElement> hitElement = [FBActiveAppDetectionPoint axElementWithPoint:midPoint];
|
|
202
190
|
if (nil != hitElement) {
|
|
203
191
|
if (FBIsAXElementEqualToOther(self.accessibilityElement, hitElement)) {
|
|
@@ -12,9 +12,7 @@
|
|
|
12
12
|
#import "FBRunLoopSpinner.h"
|
|
13
13
|
#import "FBXCElementSnapshot.h"
|
|
14
14
|
#import "FBXCodeCompatibility.h"
|
|
15
|
-
#import "XCUIApplication+FBTouchAction.h"
|
|
16
15
|
#import "XCUICoordinate.h"
|
|
17
|
-
#import "XCUICoordinate+FBFix.h"
|
|
18
16
|
#import "XCUIElement+FBCaching.h"
|
|
19
17
|
#import "XCUIElement+FBResolve.h"
|
|
20
18
|
|
|
@@ -31,16 +29,6 @@ static const NSTimeInterval VALUE_CHANGE_TIMEOUT = 2;
|
|
|
31
29
|
NSString *previousValue = snapshot.value;
|
|
32
30
|
XCUICoordinate *startCoord = [self coordinateWithNormalizedOffset:CGVectorMake(0.5, 0.5)];
|
|
33
31
|
XCUICoordinate *endCoord = [startCoord coordinateWithOffset:CGVectorMake(0.0, relativeHeightOffset * snapshot.frame.size.height)];
|
|
34
|
-
CGPoint tapPoint = endCoord.fb_screenPoint;
|
|
35
|
-
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
|
36
|
-
@[@{
|
|
37
|
-
@"action": @"tap",
|
|
38
|
-
@"options": @{
|
|
39
|
-
@"x": @(tapPoint.x),
|
|
40
|
-
@"y": @(tapPoint.y),
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
];
|
|
44
32
|
// If picker value is reflected in its accessiblity id
|
|
45
33
|
// then fetching of the next snapshot may fail with StaleElementReferenceError
|
|
46
34
|
// because we bound elements by their accessbility ids by default.
|
|
@@ -48,9 +36,7 @@ static const NSTimeInterval VALUE_CHANGE_TIMEOUT = 2;
|
|
|
48
36
|
// unique element identifier (UID), so it could be found next time even if its
|
|
49
37
|
// id is different from the initial one. See https://github.com/appium/appium/issues/17569
|
|
50
38
|
XCUIElement *stableInstance = self.fb_stableInstance;
|
|
51
|
-
|
|
52
|
-
return NO;
|
|
53
|
-
}
|
|
39
|
+
[endCoord tap];
|
|
54
40
|
return [[[[FBRunLoopSpinner new]
|
|
55
41
|
timeout:VALUE_CHANGE_TIMEOUT]
|
|
56
42
|
timeoutErrorMessage:[NSString stringWithFormat:@"Picker wheel value has not been changed after %@ seconds timeout", @(VALUE_CHANGE_TIMEOUT)]]
|
|
@@ -16,11 +16,9 @@
|
|
|
16
16
|
#import "FBXCodeCompatibility.h"
|
|
17
17
|
#import "FBXCElementSnapshotWrapper.h"
|
|
18
18
|
#import "FBXCElementSnapshotWrapper+Helpers.h"
|
|
19
|
-
#import "XCUIApplication+FBTouchAction.h"
|
|
20
19
|
#import "XCUIElement+FBCaching.h"
|
|
21
20
|
#import "XCUIApplication.h"
|
|
22
21
|
#import "XCUICoordinate.h"
|
|
23
|
-
#import "XCUICoordinate+FBFix.h"
|
|
24
22
|
#import "XCUIElement+FBIsVisible.h"
|
|
25
23
|
#import "XCUIElement.h"
|
|
26
24
|
#import "XCUIElement+FBUtilities.h"
|
|
@@ -28,7 +26,8 @@
|
|
|
28
26
|
|
|
29
27
|
const CGFloat FBFuzzyPointThreshold = 20.f; //Smallest determined value that is not interpreted as touch
|
|
30
28
|
const CGFloat FBScrollToVisibleNormalizedDistance = .5f;
|
|
31
|
-
const CGFloat FBTouchEventDelay =
|
|
29
|
+
const CGFloat FBTouchEventDelay = 0.5f;
|
|
30
|
+
const CGFloat FBTouchVelocity = 300; // pixels per sec
|
|
32
31
|
const CGFloat FBScrollTouchProportion = 0.75f;
|
|
33
32
|
|
|
34
33
|
#if !TARGET_OS_TV
|
|
@@ -321,45 +320,16 @@ const CGFloat FBScrollTouchProportion = 0.75f;
|
|
|
321
320
|
|
|
322
321
|
XCUICoordinate *appCoordinate = [[XCUICoordinate alloc] initWithElement:application normalizedOffset:CGVectorMake(0.0, 0.0)];
|
|
323
322
|
XCUICoordinate *startCoordinate = [[XCUICoordinate alloc] initWithCoordinate:appCoordinate pointsOffset:hitpointOffset];
|
|
324
|
-
CGPoint startPoint = startCoordinate.fb_screenPoint;
|
|
325
323
|
XCUICoordinate *endCoordinate = [[XCUICoordinate alloc] initWithCoordinate:startCoordinate pointsOffset:vector];
|
|
326
|
-
CGPoint endPoint = endCoordinate.fb_screenPoint;
|
|
327
324
|
|
|
328
|
-
if (FBPointFuzzyEqualToPoint(
|
|
325
|
+
if (FBPointFuzzyEqualToPoint(startCoordinate.screenPoint, endCoordinate.screenPoint, FBFuzzyPointThreshold)) {
|
|
329
326
|
return YES;
|
|
330
327
|
}
|
|
331
328
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
@"x": @(startPoint.x),
|
|
337
|
-
@"y": @(startPoint.y),
|
|
338
|
-
}
|
|
339
|
-
},
|
|
340
|
-
@{
|
|
341
|
-
@"action": @"wait",
|
|
342
|
-
@"options": @{
|
|
343
|
-
@"ms": @(FBTouchEventDelay * 1000),
|
|
344
|
-
}
|
|
345
|
-
},
|
|
346
|
-
@{
|
|
347
|
-
@"action": @"moveTo",
|
|
348
|
-
@"options": @{
|
|
349
|
-
@"x": @(endPoint.x),
|
|
350
|
-
@"y": @(endPoint.y),
|
|
351
|
-
}
|
|
352
|
-
},
|
|
353
|
-
@{
|
|
354
|
-
@"action": @"release"
|
|
355
|
-
}
|
|
356
|
-
];
|
|
357
|
-
if (![application fb_performAppiumTouchActions:gesture
|
|
358
|
-
elementCache:nil
|
|
359
|
-
error:error]) {
|
|
360
|
-
return NO;
|
|
361
|
-
}
|
|
362
|
-
|
|
329
|
+
[startCoordinate pressForDuration:FBTouchEventDelay
|
|
330
|
+
thenDragToCoordinate:endCoordinate
|
|
331
|
+
withVelocity:FBTouchVelocity
|
|
332
|
+
thenHoldForDuration:FBTouchEventDelay];
|
|
363
333
|
return YES;
|
|
364
334
|
}
|
|
365
335
|
|
|
@@ -98,13 +98,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
98
98
|
*/
|
|
99
99
|
- (void)fb_waitUntilStableWithTimeout:(NSTimeInterval)timeout;
|
|
100
100
|
|
|
101
|
-
/**
|
|
102
|
-
Returns screenshot of the particular element
|
|
103
|
-
@param error If there is an error, upon return contains an NSError object that describes the problem.
|
|
104
|
-
@return Element screenshot as PNG-encoded data or nil in case of failure
|
|
105
|
-
*/
|
|
106
|
-
- (nullable NSData *)fb_screenshotWithError:(NSError*__autoreleasing*)error;
|
|
107
|
-
|
|
108
101
|
@end
|
|
109
102
|
|
|
110
103
|
NS_ASSUME_NONNULL_END
|
|
@@ -197,53 +197,4 @@
|
|
|
197
197
|
FBConfiguration.waitForIdleTimeout = previousTimeout;
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
- (NSData *)fb_screenshotWithError:(NSError **)error
|
|
201
|
-
{
|
|
202
|
-
id<FBXCElementSnapshot> selfSnapshot = self.fb_isResolvedFromCache.boolValue
|
|
203
|
-
? self.lastSnapshot
|
|
204
|
-
: self.fb_takeSnapshot;
|
|
205
|
-
if (CGRectIsEmpty(selfSnapshot.frame)) {
|
|
206
|
-
if (error) {
|
|
207
|
-
*error = [[FBErrorBuilder.builder withDescription:@"Cannot get a screenshot of zero-sized element"] build];
|
|
208
|
-
}
|
|
209
|
-
return nil;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
CGRect elementRect = selfSnapshot.frame;
|
|
213
|
-
#if !TARGET_OS_TV
|
|
214
|
-
UIInterfaceOrientation orientation = self.application.interfaceOrientation;
|
|
215
|
-
if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) {
|
|
216
|
-
// Workaround XCTest bug when element frame is returned as in portrait mode even if the screenshot is rotated
|
|
217
|
-
NSArray<id<FBXCElementSnapshot>> *ancestors = [FBXCElementSnapshotWrapper ensureWrapped:selfSnapshot].fb_ancestors;
|
|
218
|
-
id<FBXCElementSnapshot> parentWindow = nil;
|
|
219
|
-
if (1 == ancestors.count) {
|
|
220
|
-
parentWindow = selfSnapshot;
|
|
221
|
-
} else if (ancestors.count > 1) {
|
|
222
|
-
parentWindow = [ancestors objectAtIndex:ancestors.count - 2];
|
|
223
|
-
}
|
|
224
|
-
if (nil != parentWindow) {
|
|
225
|
-
CGRect appFrame = ancestors.lastObject.frame;
|
|
226
|
-
CGRect parentWindowFrame = parentWindow.frame;
|
|
227
|
-
if (CGRectEqualToRect(appFrame, parentWindowFrame)
|
|
228
|
-
|| (appFrame.size.width > appFrame.size.height && parentWindowFrame.size.width > parentWindowFrame.size.height)
|
|
229
|
-
|| (appFrame.size.width < appFrame.size.height && parentWindowFrame.size.width < parentWindowFrame.size.height)) {
|
|
230
|
-
CGPoint fixedOrigin = orientation == UIInterfaceOrientationLandscapeLeft ?
|
|
231
|
-
CGPointMake(appFrame.size.height - elementRect.origin.y - elementRect.size.height, elementRect.origin.x) :
|
|
232
|
-
CGPointMake(elementRect.origin.y, appFrame.size.width - elementRect.origin.x - elementRect.size.width);
|
|
233
|
-
elementRect = CGRectMake(fixedOrigin.x, fixedOrigin.y, elementRect.size.height, elementRect.size.width);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
#endif
|
|
238
|
-
|
|
239
|
-
// adjust element rect for the actual screen scale
|
|
240
|
-
XCUIScreen *mainScreen = XCUIScreen.mainScreen;
|
|
241
|
-
elementRect = CGRectMake(elementRect.origin.x * mainScreen.scale, elementRect.origin.y * mainScreen.scale,
|
|
242
|
-
elementRect.size.width * mainScreen.scale, elementRect.size.height * mainScreen.scale);
|
|
243
|
-
|
|
244
|
-
return [FBScreenshot takeInOriginalResolutionWithQuality:FBConfiguration.screenshotQuality
|
|
245
|
-
rect:elementRect
|
|
246
|
-
error:error];
|
|
247
|
-
}
|
|
248
|
-
|
|
249
200
|
@end
|
|
@@ -594,10 +594,10 @@
|
|
|
594
594
|
{
|
|
595
595
|
FBElementCache *elementCache = request.session.elementCache;
|
|
596
596
|
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
597
|
-
|
|
598
|
-
NSData *screenshotData = [element fb_screenshotWithError:&error];
|
|
597
|
+
NSData *screenshotData = [element.screenshot PNGRepresentation];
|
|
599
598
|
if (nil == screenshotData) {
|
|
600
|
-
|
|
599
|
+
NSString *errMsg = [NSString stringWithFormat:@"Cannot take a screenshot of %@", element.description];
|
|
600
|
+
return FBResponseWithStatus([FBCommandStatus unableToCaptureScreenErrorWithMessage:errMsg
|
|
601
601
|
traceback:nil]);
|
|
602
602
|
}
|
|
603
603
|
NSString *screenshot = [screenshotData base64EncodedStringWithOptions:0];
|
|
@@ -606,36 +606,54 @@
|
|
|
606
606
|
|
|
607
607
|
|
|
608
608
|
#if !TARGET_OS_TV
|
|
609
|
-
static const CGFloat
|
|
609
|
+
static const CGFloat DEFAULT_PICKER_OFFSET = (CGFloat)0.2;
|
|
610
|
+
static const NSInteger DEFAULT_MAX_PICKER_ATTEMPTS = 25;
|
|
611
|
+
|
|
610
612
|
|
|
611
613
|
+ (id<FBResponsePayload>)handleWheelSelect:(FBRouteRequest *)request
|
|
612
614
|
{
|
|
613
615
|
FBElementCache *elementCache = request.session.elementCache;
|
|
614
616
|
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
615
617
|
if ([element.lastSnapshot elementType] != XCUIElementTypePickerWheel) {
|
|
616
|
-
|
|
618
|
+
NSString *errMsg = [NSString stringWithFormat:@"The element is expected to be a valid Picker Wheel control. '%@' was given instead", element.wdType];
|
|
619
|
+
return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:errMsg
|
|
620
|
+
traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]);
|
|
617
621
|
}
|
|
618
622
|
NSString* order = [request.arguments[@"order"] lowercaseString];
|
|
619
|
-
CGFloat offset =
|
|
623
|
+
CGFloat offset = DEFAULT_PICKER_OFFSET;
|
|
620
624
|
if (request.arguments[@"offset"]) {
|
|
621
625
|
offset = (CGFloat)[request.arguments[@"offset"] doubleValue];
|
|
622
626
|
if (offset <= 0.0 || offset > 0.5) {
|
|
623
|
-
|
|
627
|
+
NSString *errMsg = [NSString stringWithFormat:@"'offset' value is expected to be in range (0.0, 0.5]. '%@' was given instead", request.arguments[@"offset"]];
|
|
628
|
+
return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:errMsg
|
|
629
|
+
traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]);
|
|
624
630
|
}
|
|
625
631
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
632
|
+
NSNumber *maxAttempts = request.arguments[@"maxAttempts"] ?: @(DEFAULT_MAX_PICKER_ATTEMPTS);
|
|
633
|
+
NSString *expectedValue = request.arguments[@"value"];
|
|
634
|
+
NSInteger attempt = 0;
|
|
635
|
+
while (attempt < [maxAttempts integerValue]) {
|
|
636
|
+
BOOL isSuccessful = false;
|
|
637
|
+
NSError *error;
|
|
638
|
+
if ([order isEqualToString:@"next"]) {
|
|
639
|
+
isSuccessful = [element fb_selectNextOptionWithOffset:offset error:&error];
|
|
640
|
+
} else if ([order isEqualToString:@"previous"]) {
|
|
641
|
+
isSuccessful = [element fb_selectPreviousOptionWithOffset:offset error:&error];
|
|
642
|
+
} else {
|
|
643
|
+
NSString *errMsg = [NSString stringWithFormat:@"Only 'previous' and 'next' order values are supported. '%@' was given instead", request.arguments[@"order"]];
|
|
644
|
+
return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:errMsg
|
|
645
|
+
traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]);
|
|
646
|
+
}
|
|
647
|
+
if (!isSuccessful) {
|
|
648
|
+
return FBResponseWithStatus([FBCommandStatus invalidElementStateErrorWithMessage:error.description traceback:nil]);
|
|
649
|
+
}
|
|
650
|
+
if (nil == expectedValue || [element.wdValue isEqualToString:expectedValue]) {
|
|
651
|
+
return FBResponseWithOK();
|
|
652
|
+
}
|
|
653
|
+
attempt++;
|
|
637
654
|
}
|
|
638
|
-
|
|
655
|
+
NSString *errMsg = [NSString stringWithFormat:@"Cannot select the expected picker wheel value '%@' after %ld attempts", expectedValue, attempt];
|
|
656
|
+
return FBResponseWithStatus([FBCommandStatus invalidElementStateErrorWithMessage:errMsg traceback:nil]);
|
|
639
657
|
}
|
|
640
658
|
|
|
641
659
|
#pragma mark - Helpers
|
|
@@ -80,7 +80,7 @@ static const double FB_LONG_TAP_DURATION_MS = 600.0;
|
|
|
80
80
|
|
|
81
81
|
- (nullable instancetype)initWithActionItem:(NSDictionary<NSString *, id> *)item
|
|
82
82
|
application:(XCUIApplication *)application
|
|
83
|
-
atPosition:(nullable
|
|
83
|
+
atPosition:(nullable XCUICoordinate *)atPosition
|
|
84
84
|
offset:(double)offset
|
|
85
85
|
error:(NSError **)error
|
|
86
86
|
{
|
|
@@ -90,14 +90,14 @@ static const double FB_LONG_TAP_DURATION_MS = 600.0;
|
|
|
90
90
|
self.application = application;
|
|
91
91
|
self.offset = offset;
|
|
92
92
|
id options = [item objectForKey:FB_OPTIONS_KEY];
|
|
93
|
-
if (atPosition) {
|
|
94
|
-
self.atPosition =
|
|
93
|
+
if (nil != atPosition) {
|
|
94
|
+
self.atPosition = (id) atPosition;
|
|
95
95
|
} else {
|
|
96
|
-
|
|
96
|
+
XCUICoordinate *result = [self coordinatesWithOptions:options error:error];
|
|
97
97
|
if (nil == result) {
|
|
98
98
|
return nil;
|
|
99
99
|
}
|
|
100
|
-
self.atPosition =
|
|
100
|
+
self.atPosition = result;
|
|
101
101
|
}
|
|
102
102
|
self.duration = [self durationWithOptions:options];
|
|
103
103
|
if (self.duration < 0) {
|
|
@@ -124,7 +124,8 @@ static const double FB_LONG_TAP_DURATION_MS = 600.0;
|
|
|
124
124
|
0.0;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
- (nullable
|
|
127
|
+
- (nullable XCUICoordinate *)coordinatesWithOptions:(nullable NSDictionary<NSString *, id> *)options
|
|
128
|
+
error:(NSError **)error
|
|
128
129
|
{
|
|
129
130
|
if (![options isKindOfClass:NSDictionary.class]) {
|
|
130
131
|
NSString *description = [NSString stringWithFormat:@"'%@' key is mandatory for '%@' action", FB_OPTIONS_KEY, self.class.actionName];
|
|
@@ -169,7 +170,7 @@ static const double FB_LONG_TAP_DURATION_MS = 600.0;
|
|
|
169
170
|
NSTimeInterval currentOffset = FBMillisToSeconds(self.offset);
|
|
170
171
|
NSMutableArray<XCPointerEventPath *> *result = [NSMutableArray array];
|
|
171
172
|
XCPointerEventPath *currentPath = [[XCPointerEventPath alloc]
|
|
172
|
-
initForTouchAtPoint:self.atPosition
|
|
173
|
+
initForTouchAtPoint:self.atPosition.screenPoint
|
|
173
174
|
offset:currentOffset];
|
|
174
175
|
[result addObject:currentPath];
|
|
175
176
|
currentOffset += FBMillisToSeconds(FB_TAP_DURATION_MS);
|
|
@@ -180,7 +181,8 @@ static const double FB_LONG_TAP_DURATION_MS = 600.0;
|
|
|
180
181
|
NSNumber *tapCount = [options objectForKey:FB_OPTION_COUNT] ?: @1;
|
|
181
182
|
for (NSInteger times = 1; times < tapCount.integerValue; ++times) {
|
|
182
183
|
currentOffset += FBMillisToSeconds(FB_INTERTAP_MIN_DURATION_MS);
|
|
183
|
-
XCPointerEventPath *nextPath = [[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition
|
|
184
|
+
XCPointerEventPath *nextPath = [[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition.screenPoint
|
|
185
|
+
offset:currentOffset];
|
|
184
186
|
[result addObject:nextPath];
|
|
185
187
|
currentOffset += FBMillisToSeconds(FB_TAP_DURATION_MS);
|
|
186
188
|
[nextPath liftUpAtOffset:currentOffset];
|
|
@@ -204,7 +206,7 @@ static const double FB_LONG_TAP_DURATION_MS = 600.0;
|
|
|
204
206
|
|
|
205
207
|
- (nullable instancetype)initWithActionItem:(NSDictionary<NSString *, id> *)item
|
|
206
208
|
application:(XCUIApplication *)application
|
|
207
|
-
atPosition:(nullable
|
|
209
|
+
atPosition:(nullable XCUICoordinate *)atPosition
|
|
208
210
|
offset:(double)offset
|
|
209
211
|
error:(NSError **)error
|
|
210
212
|
{
|
|
@@ -239,7 +241,7 @@ static const double FB_LONG_TAP_DURATION_MS = 600.0;
|
|
|
239
241
|
error:(NSError **)error
|
|
240
242
|
{
|
|
241
243
|
XCPointerEventPath *result = [[XCPointerEventPath alloc]
|
|
242
|
-
initForTouchAtPoint:self.atPosition
|
|
244
|
+
initForTouchAtPoint:self.atPosition.screenPoint
|
|
243
245
|
offset:FBMillisToSeconds(self.offset)];
|
|
244
246
|
if (nil != self.pressure && nil != result.pointerEvents.lastObject) {
|
|
245
247
|
XCPointerEvent *pointerEvent = (XCPointerEvent *)result.pointerEvents.lastObject;
|
|
@@ -272,7 +274,7 @@ static const double FB_LONG_TAP_DURATION_MS = 600.0;
|
|
|
272
274
|
currentItemIndex:(NSUInteger)currentItemIndex
|
|
273
275
|
error:(NSError **)error
|
|
274
276
|
{
|
|
275
|
-
return @[[[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition
|
|
277
|
+
return @[[[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition.screenPoint
|
|
276
278
|
offset:FBMillisToSeconds(self.offset)]];
|
|
277
279
|
}
|
|
278
280
|
|
|
@@ -312,7 +314,8 @@ static const double FB_LONG_TAP_DURATION_MS = 600.0;
|
|
|
312
314
|
}
|
|
313
315
|
}
|
|
314
316
|
NSTimeInterval currentOffset = FBMillisToSeconds(self.offset + self.duration);
|
|
315
|
-
XCPointerEventPath *result = [[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition
|
|
317
|
+
XCPointerEventPath *result = [[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition.screenPoint
|
|
318
|
+
offset:currentOffset];
|
|
316
319
|
if (currentItemIndex == allItems.count - 1) {
|
|
317
320
|
[result liftUpAtOffset:currentOffset];
|
|
318
321
|
}
|
|
@@ -353,7 +356,8 @@ static const double FB_LONG_TAP_DURATION_MS = 600.0;
|
|
|
353
356
|
return nil;
|
|
354
357
|
}
|
|
355
358
|
|
|
356
|
-
[eventPath moveToPoint:self.atPosition
|
|
359
|
+
[eventPath moveToPoint:self.atPosition.screenPoint
|
|
360
|
+
atOffset:FBMillisToSeconds(self.offset)];
|
|
357
361
|
return @[];
|
|
358
362
|
}
|
|
359
363
|
|
|
@@ -509,7 +513,11 @@ static const double FB_LONG_TAP_DURATION_MS = 600.0;
|
|
|
509
513
|
return nil;
|
|
510
514
|
}
|
|
511
515
|
FBAppiumGestureItem *lastItem = [chain.items lastObject];
|
|
512
|
-
gestureItem = [[gestureItemClass alloc] initWithActionItem:actionItem
|
|
516
|
+
gestureItem = [[gestureItemClass alloc] initWithActionItem:actionItem
|
|
517
|
+
application:self.application
|
|
518
|
+
atPosition:lastItem.atPosition
|
|
519
|
+
offset:chain.durationOffset
|
|
520
|
+
error:error];
|
|
513
521
|
}
|
|
514
522
|
if (nil == gestureItem) {
|
|
515
523
|
return nil;
|
|
@@ -527,7 +535,7 @@ static const double FB_LONG_TAP_DURATION_MS = 600.0;
|
|
|
527
535
|
BOOL isMultiTouch = [self.actions.firstObject isKindOfClass:NSArray.class];
|
|
528
536
|
eventRecord = [[XCSynthesizedEventRecord alloc]
|
|
529
537
|
initWithName:(isMultiTouch ? @"Multi-Finger Touch Action" : @"Single-Finger Touch Action")
|
|
530
|
-
interfaceOrientation:
|
|
538
|
+
interfaceOrientation:self.application.interfaceOrientation];
|
|
531
539
|
for (NSArray<NSDictionary<NSString *, id> *> *action in (isMultiTouch ? self.actions : @[self.actions])) {
|
|
532
540
|
NSArray<NSDictionary<NSString *, id> *> *preprocessedAction = [self preprocessAction:action];
|
|
533
541
|
NSArray<XCPointerEventPath *> *eventPaths = [self eventPathsWithAction:preprocessedAction error:error];
|
|
@@ -51,19 +51,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
51
51
|
@interface FBBaseGestureItem : FBBaseActionItem
|
|
52
52
|
|
|
53
53
|
/*! Absolute position on the screen where the gesure should be performed */
|
|
54
|
-
@property (nonatomic)
|
|
54
|
+
@property (nonatomic) XCUICoordinate *atPosition;
|
|
55
55
|
/*! Gesture duration in milliseconds */
|
|
56
56
|
@property (nonatomic) double duration;
|
|
57
57
|
|
|
58
|
-
/**
|
|
59
|
-
Returns fixed hit point coordinates for the case when XCTest fails to transform element snaapshot properly on screen rotation.
|
|
60
|
-
|
|
61
|
-
@param hitPoint The initial hitpoint coordinates
|
|
62
|
-
@param snapshot Element's snapshot instance
|
|
63
|
-
@return The fixed hit point coordinates, if there is a need to fix them, or the unchanged hit point value
|
|
64
|
-
*/
|
|
65
|
-
- (CGPoint)fixedHitPointWith:(CGPoint)hitPoint forSnapshot:(id<FBXCElementSnapshot>)snapshot;
|
|
66
|
-
|
|
67
58
|
/**
|
|
68
59
|
Calculate absolute gesture position on the screen based on provided element and positionOffset values.
|
|
69
60
|
|
|
@@ -72,9 +63,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
72
63
|
@param error If there is an error, upon return contains an NSError object that describes the problem
|
|
73
64
|
@return Adbsolute gesture position on the screen or nil if the calculation fails (for example, the element is invisible)
|
|
74
65
|
*/
|
|
75
|
-
- (nullable
|
|
76
|
-
|
|
77
|
-
|
|
66
|
+
- (nullable XCUICoordinate *)hitpointWithElement:(nullable XCUIElement *)element
|
|
67
|
+
positionOffset:(nullable NSValue *)positionOffset
|
|
68
|
+
error:(NSError **)error;
|
|
78
69
|
|
|
79
70
|
@end
|
|
80
71
|
|
|
@@ -31,7 +31,10 @@
|
|
|
31
31
|
return nil;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
- (NSArray<XCPointerEventPath *> *)addToEventPath:(XCPointerEventPath *)eventPath
|
|
34
|
+
- (NSArray<XCPointerEventPath *> *)addToEventPath:(XCPointerEventPath *)eventPath
|
|
35
|
+
allItems:(NSArray *)allItems
|
|
36
|
+
currentItemIndex:(NSUInteger)currentItemIndex
|
|
37
|
+
error:(NSError **)error
|
|
35
38
|
{
|
|
36
39
|
@throw [[FBErrorBuilder.builder withDescription:@"Override this method in subclasses"] build];
|
|
37
40
|
return nil;
|
|
@@ -41,66 +44,40 @@
|
|
|
41
44
|
|
|
42
45
|
@implementation FBBaseGestureItem
|
|
43
46
|
|
|
44
|
-
- (
|
|
47
|
+
- (nullable XCUICoordinate *)hitpointWithElement:(nullable XCUIElement *)element
|
|
48
|
+
positionOffset:(nullable NSValue *)positionOffset
|
|
49
|
+
error:(NSError **)error
|
|
45
50
|
{
|
|
46
|
-
UIInterfaceOrientation interfaceOrientation = self.application.interfaceOrientation;
|
|
47
|
-
if (interfaceOrientation == UIInterfaceOrientationPortrait) {
|
|
48
|
-
// There is no need to recalculate anything for portrait orientation
|
|
49
|
-
return hitPoint;
|
|
50
|
-
}
|
|
51
|
-
// For Xcode11+ it is always necessary to adjust the tap point coordinates
|
|
52
|
-
return FBInvertPointForApplication(hitPoint, self.application.frame.size, interfaceOrientation);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
- (nullable NSValue *)hitpointWithElement:(nullable XCUIElement *)element positionOffset:(nullable NSValue *)positionOffset error:(NSError **)error
|
|
56
|
-
{
|
|
57
|
-
CGPoint hitPoint;
|
|
58
51
|
if (nil == element) {
|
|
52
|
+
CGVector offset = CGVectorMake(positionOffset.CGPointValue.x, positionOffset.CGPointValue.y);
|
|
59
53
|
// Only absolute offset is defined
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// The offset relative to the element is defined
|
|
69
|
-
|
|
70
|
-
id<FBXCElementSnapshot> snapshot = element.fb_isResolvedFromCache.boolValue
|
|
71
|
-
? element.lastSnapshot
|
|
72
|
-
: element.fb_takeSnapshot;
|
|
73
|
-
if (nil == positionOffset) {
|
|
74
|
-
NSValue *hitPointValue = [FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_hitPoint;
|
|
75
|
-
if (nil != hitPointValue) {
|
|
76
|
-
// short circuit element hitpoint
|
|
77
|
-
return hitPointValue;
|
|
78
|
-
}
|
|
79
|
-
[FBLogger logFmt:@"Will use the frame of '%@' for hit point calculation instead", element.debugDescription];
|
|
80
|
-
}
|
|
81
|
-
CGRect visibleFrame = snapshot.visibleFrame;
|
|
82
|
-
CGRect frame = CGRectIsEmpty(visibleFrame) ? element.frame : visibleFrame;
|
|
83
|
-
if (CGRectIsEmpty(frame)) {
|
|
84
|
-
[FBLogger log:self.application.fb_descriptionRepresentation];
|
|
85
|
-
NSString *description = [NSString stringWithFormat:@"The element '%@' is not visible on the screen and thus is not interactable", element.description];
|
|
86
|
-
if (error) {
|
|
87
|
-
*error = [[FBErrorBuilder.builder withDescription:description] build];
|
|
88
|
-
}
|
|
89
|
-
return nil;
|
|
54
|
+
return [[self.application coordinateWithNormalizedOffset:CGVectorMake(0, 0)] coordinateWithOffset:offset];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// The offset relative to the element is defined
|
|
58
|
+
if (nil == positionOffset) {
|
|
59
|
+
if (element.hittable) {
|
|
60
|
+
// short circuit element hitpoint
|
|
61
|
+
return element.hitPointCoordinate;
|
|
90
62
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
// TODO: Shall we throw an exception if hitPoint is out of the element frame?
|
|
63
|
+
[FBLogger logFmt:@"Will use the frame of '%@' for hit point calculation instead", element.debugDescription];
|
|
64
|
+
}
|
|
65
|
+
if (CGRectIsEmpty(element.frame)) {
|
|
66
|
+
[FBLogger log:self.application.fb_descriptionRepresentation];
|
|
67
|
+
NSString *description = [NSString stringWithFormat:@"The element '%@' is not visible on the screen and thus is not interactable",
|
|
68
|
+
element.description];
|
|
69
|
+
if (error) {
|
|
70
|
+
*error = [[FBErrorBuilder.builder withDescription:description] build];
|
|
100
71
|
}
|
|
101
|
-
|
|
72
|
+
return nil;
|
|
73
|
+
}
|
|
74
|
+
if (nil == positionOffset) {
|
|
75
|
+
return [element coordinateWithNormalizedOffset:CGVectorMake(0.5, 0.5)];
|
|
102
76
|
}
|
|
103
|
-
|
|
77
|
+
|
|
78
|
+
CGVector offset = CGVectorMake(positionOffset.CGPointValue.x, positionOffset.CGPointValue.y);
|
|
79
|
+
// TODO: Shall we throw an exception if hitPoint is out of the element frame?
|
|
80
|
+
return [[element coordinateWithNormalizedOffset:CGVectorMake(0, 0)] coordinateWithOffset:offset];
|
|
104
81
|
}
|
|
105
82
|
|
|
106
83
|
@end
|
|
@@ -161,7 +138,10 @@
|
|
|
161
138
|
|
|
162
139
|
@implementation FBBaseActionsSynthesizer
|
|
163
140
|
|
|
164
|
-
- (instancetype)initWithActions:(NSArray *)actions
|
|
141
|
+
- (instancetype)initWithActions:(NSArray *)actions
|
|
142
|
+
forApplication:(XCUIApplication *)application
|
|
143
|
+
elementCache:(nullable FBElementCache *)elementCache
|
|
144
|
+
error:(NSError **)error
|
|
165
145
|
{
|
|
166
146
|
self = [super init];
|
|
167
147
|
if (self) {
|
|
@@ -32,12 +32,6 @@ BOOL FBSizeFuzzyEqualToSize(CGSize size1, CGSize size2, CGFloat threshold);
|
|
|
32
32
|
BOOL FBRectFuzzyEqualToRect(CGRect rect1, CGRect rect2, CGFloat threshold);
|
|
33
33
|
|
|
34
34
|
#if !TARGET_OS_TV
|
|
35
|
-
/*! Inverts point if necessary to match location on screen */
|
|
36
|
-
CGPoint FBInvertPointForApplication(CGPoint point, CGSize screenSize, UIInterfaceOrientation orientation);
|
|
37
|
-
|
|
38
|
-
/*! Inverts offset if necessary to match screen orientation */
|
|
39
|
-
CGPoint FBInvertOffsetForOrientation(CGPoint offset, UIInterfaceOrientation orientation);
|
|
40
|
-
|
|
41
35
|
/*! Inverts size if necessary to match current screen orientation */
|
|
42
36
|
CGSize FBAdjustDimensionsForApplication(CGSize actualSize, UIInterfaceOrientation orientation);
|
|
43
37
|
#endif
|
|
@@ -46,35 +46,6 @@ BOOL FBRectFuzzyEqualToRect(CGRect rect1, CGRect rect2, CGFloat threshold)
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
#if !TARGET_OS_TV
|
|
49
|
-
CGPoint FBInvertPointForApplication(CGPoint point, CGSize screenSize, UIInterfaceOrientation orientation)
|
|
50
|
-
{
|
|
51
|
-
switch (orientation) {
|
|
52
|
-
case UIInterfaceOrientationUnknown:
|
|
53
|
-
case UIInterfaceOrientationPortrait:
|
|
54
|
-
return point;
|
|
55
|
-
case UIInterfaceOrientationPortraitUpsideDown:
|
|
56
|
-
return CGPointMake(screenSize.width - point.x, screenSize.height - point.y);
|
|
57
|
-
case UIInterfaceOrientationLandscapeLeft:
|
|
58
|
-
return CGPointMake(point.y, MAX(screenSize.width, screenSize.height) - point.x);
|
|
59
|
-
case UIInterfaceOrientationLandscapeRight:
|
|
60
|
-
return CGPointMake(MIN(screenSize.width, screenSize.height) - point.y, point.x);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
CGPoint FBInvertOffsetForOrientation(CGPoint offset, UIInterfaceOrientation orientation)
|
|
65
|
-
{
|
|
66
|
-
switch (orientation) {
|
|
67
|
-
case UIInterfaceOrientationUnknown:
|
|
68
|
-
case UIInterfaceOrientationPortrait:
|
|
69
|
-
return offset;
|
|
70
|
-
case UIInterfaceOrientationPortraitUpsideDown:
|
|
71
|
-
return CGPointMake(-offset.x, -offset.y);
|
|
72
|
-
case UIInterfaceOrientationLandscapeLeft:
|
|
73
|
-
return CGPointMake(offset.y, -offset.x);
|
|
74
|
-
case UIInterfaceOrientationLandscapeRight:
|
|
75
|
-
return CGPointMake(-offset.y, offset.x);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
49
|
|
|
79
50
|
CGSize FBAdjustDimensionsForApplication(CGSize actualSize, UIInterfaceOrientation orientation)
|
|
80
51
|
{
|
|
@@ -133,16 +133,16 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
|
|
|
133
133
|
return nil;
|
|
134
134
|
}
|
|
135
135
|
self.duration = durationObj.doubleValue;
|
|
136
|
-
|
|
136
|
+
XCUICoordinate *position = [self positionWithError:error];
|
|
137
137
|
if (nil == position) {
|
|
138
138
|
return nil;
|
|
139
139
|
}
|
|
140
|
-
self.atPosition =
|
|
140
|
+
self.atPosition = position;
|
|
141
141
|
}
|
|
142
142
|
return self;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
- (nullable
|
|
145
|
+
- (nullable XCUICoordinate *)positionWithError:(NSError **)error
|
|
146
146
|
{
|
|
147
147
|
if (nil == self.previousItem) {
|
|
148
148
|
NSString *errorDescription = [NSString stringWithFormat:@"The '%@' action item must be preceded by %@ item", self.actionItem, FB_ACTION_ITEM_TYPE_POINTER_MOVE];
|
|
@@ -151,39 +151,32 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
|
|
|
151
151
|
}
|
|
152
152
|
return nil;
|
|
153
153
|
}
|
|
154
|
-
return
|
|
154
|
+
return self.previousItem.atPosition;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
- (nullable
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
- (nullable XCUICoordinate *)hitpointWithElement:(nullable XCUIElement *)element
|
|
158
|
+
positionOffset:(nullable NSValue *)positionOffset
|
|
159
|
+
error:(NSError **)error
|
|
160
160
|
{
|
|
161
161
|
if (nil == element || nil == positionOffset) {
|
|
162
162
|
return [super hitpointWithElement:element positionOffset:positionOffset error:error];
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
// An offset relative to the element is defined
|
|
166
|
-
|
|
167
|
-
? element.lastSnapshot
|
|
168
|
-
: element.fb_takeSnapshot;
|
|
169
|
-
CGRect frame = snapshot.frame;
|
|
170
|
-
if (CGRectIsEmpty(frame)) {
|
|
166
|
+
if (CGRectIsEmpty(element.frame)) {
|
|
171
167
|
[FBLogger log:self.application.fb_descriptionRepresentation];
|
|
172
|
-
NSString *description = [NSString stringWithFormat:@"The element '%@' is not visible on the screen and thus is not interactable",
|
|
168
|
+
NSString *description = [NSString stringWithFormat:@"The element '%@' is not visible on the screen and thus is not interactable",
|
|
169
|
+
element.description];
|
|
173
170
|
if (error) {
|
|
174
171
|
*error = [[FBErrorBuilder.builder withDescription:description] build];
|
|
175
172
|
}
|
|
176
173
|
return nil;
|
|
177
174
|
}
|
|
178
|
-
|
|
179
|
-
frame = CGRectIsEmpty(visibleFrame) ? frame : visibleFrame;
|
|
175
|
+
|
|
180
176
|
// W3C standard requires that relative element coordinates start at the center of the element's rectangle
|
|
181
|
-
|
|
182
|
-
CGPoint offsetValue = [positionOffset CGPointValue];
|
|
183
|
-
hitPoint = CGPointMake(hitPoint.x + offsetValue.x, hitPoint.y + offsetValue.y);
|
|
177
|
+
CGVector offset = CGVectorMake(positionOffset.CGPointValue.x, positionOffset.CGPointValue.y);
|
|
184
178
|
// TODO: Shall we throw an exception if hitPoint is out of the element frame?
|
|
185
|
-
|
|
186
|
-
return [NSValue valueWithCGPoint:hitPoint];
|
|
179
|
+
return [[element coordinateWithNormalizedOffset:CGVectorMake(0.5, 0.5)] coordinateWithOffset:offset];
|
|
187
180
|
}
|
|
188
181
|
|
|
189
182
|
@end
|
|
@@ -220,7 +213,7 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
|
|
|
220
213
|
}
|
|
221
214
|
}
|
|
222
215
|
if (nil == self.pressure) {
|
|
223
|
-
XCPointerEventPath *result = [[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition
|
|
216
|
+
XCPointerEventPath *result = [[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition.screenPoint
|
|
224
217
|
offset:FBMillisToSeconds(self.offset)];
|
|
225
218
|
return @[result];
|
|
226
219
|
}
|
|
@@ -247,7 +240,7 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
|
|
|
247
240
|
|
|
248
241
|
@implementation FBPointerMoveItem
|
|
249
242
|
|
|
250
|
-
- (nullable
|
|
243
|
+
- (nullable XCUICoordinate *)positionWithError:(NSError **)error
|
|
251
244
|
{
|
|
252
245
|
static NSArray<NSString *> *supportedOriginTypes;
|
|
253
246
|
static dispatch_once_t onceToken;
|
|
@@ -295,10 +288,9 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
|
|
|
295
288
|
}
|
|
296
289
|
return nil;
|
|
297
290
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
return [NSValue valueWithCGPoint:CGPointMake(recentPosition.x + offsetRelativeToRecentPosition.x, recentPosition.y + offsetRelativeToRecentPosition.y)];
|
|
291
|
+
XCUICoordinate *recentPosition = self.previousItem.atPosition;
|
|
292
|
+
CGVector offsetRelativeToRecentPosition = (nil == x && nil == y) ? CGVectorMake(0, 0) : CGVectorMake(x.floatValue, y.floatValue);
|
|
293
|
+
return [recentPosition coordinateWithOffset:offsetRelativeToRecentPosition];
|
|
302
294
|
}
|
|
303
295
|
|
|
304
296
|
+ (NSString *)actionName
|
|
@@ -312,9 +304,11 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
|
|
|
312
304
|
error:(NSError **)error
|
|
313
305
|
{
|
|
314
306
|
if (nil == eventPath) {
|
|
315
|
-
return @[[[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition
|
|
307
|
+
return @[[[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition.screenPoint
|
|
308
|
+
offset:FBMillisToSeconds(self.offset + self.duration)]];
|
|
316
309
|
}
|
|
317
|
-
[eventPath moveToPoint:self.atPosition
|
|
310
|
+
[eventPath moveToPoint:self.atPosition.screenPoint
|
|
311
|
+
atOffset:FBMillisToSeconds(self.offset + self.duration)];
|
|
318
312
|
return @[];
|
|
319
313
|
}
|
|
320
314
|
|
|
@@ -888,7 +882,7 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
|
|
|
888
882
|
{
|
|
889
883
|
XCSynthesizedEventRecord *eventRecord = [[XCSynthesizedEventRecord alloc]
|
|
890
884
|
initWithName:@"W3C Touch Action"
|
|
891
|
-
interfaceOrientation:
|
|
885
|
+
interfaceOrientation:self.application.interfaceOrientation];
|
|
892
886
|
NSMutableDictionary<NSString *, NSDictionary<NSString *, id> *> *actionsMapping = [NSMutableDictionary new];
|
|
893
887
|
NSMutableArray<NSString *> *actionIds = [NSMutableArray new];
|
|
894
888
|
for (NSDictionary<NSString *, id> *action in self.actions) {
|
|
@@ -23,10 +23,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
23
23
|
|
|
24
24
|
+ (id<XCTestManager_ManagerInterface>)testRunnerProxy;
|
|
25
25
|
|
|
26
|
-
#if !TARGET_OS_TV
|
|
27
|
-
+ (UIInterfaceOrientation)orientationWithApplication:(XCUIApplication *)application;
|
|
28
|
-
#endif
|
|
29
|
-
|
|
30
26
|
+ (BOOL)synthesizeEventWithRecord:(XCSynthesizedEventRecord *)record
|
|
31
27
|
error:(NSError *__autoreleasing*)error;
|
|
32
28
|
|
|
@@ -30,7 +30,6 @@ static dispatch_once_t onceTestRunnerDaemonClass;
|
|
|
30
30
|
|
|
31
31
|
+ (void)load
|
|
32
32
|
{
|
|
33
|
-
// XCTRunnerDaemonSession class is only available since Xcode 8.3
|
|
34
33
|
dispatch_once(&onceTestRunnerDaemonClass, ^{
|
|
35
34
|
FBXCTRunnerDaemonSessionClass = objc_lookUpClass("XCTRunnerDaemonSession");
|
|
36
35
|
});
|
|
@@ -60,17 +59,6 @@ static dispatch_once_t onceTestRunnerDaemonClass;
|
|
|
60
59
|
return ((XCTRunnerDaemonSession *)[FBXCTRunnerDaemonSessionClass sharedSession]).daemonProxy;
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
#if !TARGET_OS_TV
|
|
64
|
-
+ (UIInterfaceOrientation)orientationWithApplication:(XCUIApplication *)application
|
|
65
|
-
{
|
|
66
|
-
if (nil == FBXCTRunnerDaemonSessionClass ||
|
|
67
|
-
[[FBXCTRunnerDaemonSessionClass sharedSession] useLegacyEventCoordinateTransformationPath]) {
|
|
68
|
-
return application.interfaceOrientation;
|
|
69
|
-
}
|
|
70
|
-
return UIInterfaceOrientationPortrait;
|
|
71
|
-
}
|
|
72
|
-
#endif
|
|
73
|
-
|
|
74
62
|
+ (BOOL)synthesizeEventWithRecord:(XCSynthesizedEventRecord *)record error:(NSError *__autoreleasing*)error
|
|
75
63
|
{
|
|
76
64
|
__block BOOL didSucceed = NO;
|
|
@@ -194,14 +194,6 @@
|
|
|
194
194
|
|
|
195
195
|
- (void)testDoubleTap
|
|
196
196
|
{
|
|
197
|
-
if ([UIDevice.currentDevice userInterfaceIdiom] == UIUserInterfaceIdiomPad &&
|
|
198
|
-
SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
|
|
199
|
-
// "tap the element" does not work on iPadOS simulator after change the rotation in iOS 15
|
|
200
|
-
// while selecting the element worked. (I confirmed with getting an element screenshot that
|
|
201
|
-
// the FBShowAlertButtonName was actually selected after changing the orientation.)
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
197
|
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
|
206
198
|
@[@{
|
|
207
199
|
@"action": @"tap",
|
|
@@ -214,16 +206,8 @@
|
|
|
214
206
|
[self verifyGesture:gesture orientation:UIDeviceOrientationLandscapeLeft];
|
|
215
207
|
}
|
|
216
208
|
|
|
217
|
-
// TODO: UIDeviceOrientationLandscapeRight is not so good in iOS 16? (Especially simulators)
|
|
218
209
|
- (void)testPress
|
|
219
210
|
{
|
|
220
|
-
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
|
|
221
|
-
// Does not work on iOS 15.0.
|
|
222
|
-
// The same action tap the FBShowAlertButtonName after rotating the screen
|
|
223
|
-
// worked with W3C actions. `.click` action did not work.
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
211
|
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
|
228
212
|
@[@{
|
|
229
213
|
@"action": @"press",
|
|
@@ -294,18 +294,8 @@
|
|
|
294
294
|
[self verifyGesture:gesture orientation:UIDeviceOrientationPortrait];
|
|
295
295
|
}
|
|
296
296
|
|
|
297
|
-
// TODO: UIDeviceOrientationLandscapeLeft did not work in iOS 16 simumlator.
|
|
298
|
-
// UIDeviceOrientationPortrait was ok.
|
|
299
297
|
- (void)testDoubleTap
|
|
300
298
|
{
|
|
301
|
-
if ([UIDevice.currentDevice userInterfaceIdiom] == UIUserInterfaceIdiomPad &&
|
|
302
|
-
SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
|
|
303
|
-
// "tap the element" does not work on iPadOS simulator after change the rotation in iOS 15
|
|
304
|
-
// while selecting the element worked. (I confirmed with getting an element screenshot that
|
|
305
|
-
// the FBShowAlertButtonName was actually selected after changing the orientation.)
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
299
|
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
|
310
300
|
@[@{
|
|
311
301
|
@"type": @"pointer",
|
|
@@ -326,17 +316,8 @@
|
|
|
326
316
|
[self verifyGesture:gesture orientation:UIDeviceOrientationLandscapeLeft];
|
|
327
317
|
}
|
|
328
318
|
|
|
329
|
-
// TODO: UIDeviceOrientationLandscapeRight did not work in iOS 16 simumlator.
|
|
330
|
-
// UIDeviceOrientationPortrait was ok.
|
|
331
319
|
- (void)testLongPressWithCombinedPause
|
|
332
320
|
{
|
|
333
|
-
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
|
|
334
|
-
// Xcode 13 x iOS 14 also does not work while Xcode 12.5 x iOS 14 worked.
|
|
335
|
-
// Skip this test for iOS 15 since iOS 15 works with Xcode 13 at least.
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
|
|
340
321
|
NSArray<NSDictionary<NSString *, id> *> *gesture =
|
|
341
322
|
@[@{
|
|
342
323
|
@"type": @"pointer",
|
|
@@ -98,18 +98,6 @@
|
|
|
98
98
|
XCTAssertFalse(FBRectFuzzyEqualToRect(referenceRect, CGRectMake(-1, -1, 1, 1), 1));
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
- (void)testPointInvertion
|
|
103
|
-
{
|
|
104
|
-
const CGPoint testPoint = CGPointMake(1, 2);
|
|
105
|
-
const CGSize screenSize = CGSizeMake(10, 15);
|
|
106
|
-
const CGFloat t = FBDefaultFrameFuzzyThreshold;
|
|
107
|
-
XCTAssertTrue(FBPointFuzzyEqualToPoint(CGPointMake(1, 2), FBInvertPointForApplication(testPoint, screenSize, UIInterfaceOrientationPortrait), t));
|
|
108
|
-
XCTAssertTrue(FBPointFuzzyEqualToPoint(CGPointMake(9, 13), FBInvertPointForApplication(testPoint, screenSize, UIInterfaceOrientationPortraitUpsideDown), t));
|
|
109
|
-
XCTAssertTrue(FBPointFuzzyEqualToPoint(CGPointMake(2, 14), FBInvertPointForApplication(testPoint, screenSize, UIInterfaceOrientationLandscapeLeft), t));
|
|
110
|
-
XCTAssertTrue(FBPointFuzzyEqualToPoint(CGPointMake(8, 1), FBInvertPointForApplication(testPoint, screenSize, UIInterfaceOrientationLandscapeRight), t));
|
|
111
|
-
}
|
|
112
|
-
|
|
113
101
|
- (void)testSizeInversion
|
|
114
102
|
{
|
|
115
103
|
const CGSize screenSizePortrait = CGSizeMake(10, 15);
|
package/package.json
CHANGED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2015-present, Facebook, Inc.
|
|
3
|
-
* All rights reserved.
|
|
4
|
-
*
|
|
5
|
-
* This source code is licensed under the BSD-style license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree. An additional grant
|
|
7
|
-
* of patent rights can be found in the PATENTS file in the same directory.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
#import <XCTest/XCTest.h>
|
|
11
|
-
|
|
12
|
-
#if !TARGET_OS_TV
|
|
13
|
-
@interface XCUICoordinate (FBFix)
|
|
14
|
-
|
|
15
|
-
- (CGPoint)fb_screenPoint;
|
|
16
|
-
|
|
17
|
-
@end
|
|
18
|
-
#endif
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2015-present, Facebook, Inc.
|
|
3
|
-
* All rights reserved.
|
|
4
|
-
*
|
|
5
|
-
* This source code is licensed under the BSD-style license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree. An additional grant
|
|
7
|
-
* of patent rights can be found in the PATENTS file in the same directory.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
#import "XCUICoordinate+FBFix.h"
|
|
11
|
-
|
|
12
|
-
#import "XCUICoordinate.h"
|
|
13
|
-
#import "XCUIElement+FBUtilities.h"
|
|
14
|
-
|
|
15
|
-
# if !TARGET_OS_TV
|
|
16
|
-
@implementation XCUICoordinate (FBFix)
|
|
17
|
-
|
|
18
|
-
- (CGPoint)fb_screenPoint
|
|
19
|
-
{
|
|
20
|
-
CGPoint referencePoint = CGPointMake(0, 0);
|
|
21
|
-
NSValue *referencedElementFrame = nil;
|
|
22
|
-
if (self.element) {
|
|
23
|
-
CGRect elementFrame = self.element.frame;
|
|
24
|
-
if (self.referencedElement == self.element) {
|
|
25
|
-
referencedElementFrame = [NSValue valueWithCGRect:elementFrame];
|
|
26
|
-
}
|
|
27
|
-
referencePoint = CGPointMake(
|
|
28
|
-
CGRectGetMinX(elementFrame) + CGRectGetWidth(elementFrame) * self.normalizedOffset.dx,
|
|
29
|
-
CGRectGetMinY(elementFrame) + CGRectGetHeight(elementFrame) * self.normalizedOffset.dy);
|
|
30
|
-
} else if (self.coordinate) {
|
|
31
|
-
referencePoint = self.coordinate.fb_screenPoint;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
CGPoint screenPoint = CGPointMake(
|
|
35
|
-
referencePoint.x + self.pointsOffset.dx,
|
|
36
|
-
referencePoint.y + self.pointsOffset.dy);
|
|
37
|
-
if (nil == referencedElementFrame) {
|
|
38
|
-
referencedElementFrame = [NSValue valueWithCGRect:self.referencedElement.frame];
|
|
39
|
-
}
|
|
40
|
-
return CGPointMake(
|
|
41
|
-
MIN(CGRectGetMaxX(referencedElementFrame.CGRectValue), screenPoint.x),
|
|
42
|
-
MIN(CGRectGetMaxY(referencedElementFrame.CGRectValue), screenPoint.y));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
@end
|
|
46
|
-
#endif
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2015-present, Facebook, Inc.
|
|
3
|
-
* All rights reserved.
|
|
4
|
-
*
|
|
5
|
-
* This source code is licensed under the BSD-style license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree. An additional grant
|
|
7
|
-
* of patent rights can be found in the PATENTS file in the same directory.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
#import <XCTest/XCTest.h>
|
|
11
|
-
|
|
12
|
-
#import "FBMacros.h"
|
|
13
|
-
#import "FBIntegrationTestCase.h"
|
|
14
|
-
#import "XCUIDevice+FBRotation.h"
|
|
15
|
-
#import "XCUIElement+FBUtilities.h"
|
|
16
|
-
#import "XCUIScreen.h"
|
|
17
|
-
|
|
18
|
-
@interface FBElementScreenshotTests : FBIntegrationTestCase
|
|
19
|
-
@end
|
|
20
|
-
|
|
21
|
-
@implementation FBElementScreenshotTests
|
|
22
|
-
|
|
23
|
-
- (void)setUp
|
|
24
|
-
{
|
|
25
|
-
[super setUp];
|
|
26
|
-
static dispatch_once_t onceToken;
|
|
27
|
-
dispatch_once(&onceToken, ^{
|
|
28
|
-
[self launchApplication];
|
|
29
|
-
[self goToAlertsPage];
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
- (void)tearDown
|
|
34
|
-
{
|
|
35
|
-
[self resetOrientation];
|
|
36
|
-
[super tearDown];
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
- (void)testElementScreenshot
|
|
40
|
-
{
|
|
41
|
-
[[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:UIDeviceOrientationLandscapeLeft];
|
|
42
|
-
XCUIElement *button = self.testedApplication.buttons[FBShowAlertButtonName];
|
|
43
|
-
NSError *error = nil;
|
|
44
|
-
NSData *screenshotData = [button fb_screenshotWithError:&error];
|
|
45
|
-
XCTAssertNotNil(screenshotData);
|
|
46
|
-
XCTAssertNil(error);
|
|
47
|
-
UIImage *image = [UIImage imageWithData:screenshotData];
|
|
48
|
-
XCTAssertNotNil(image);
|
|
49
|
-
XCTAssertTrue(image.size.width > image.size.height);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
@end
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2015-present, Facebook, Inc.
|
|
3
|
-
* All rights reserved.
|
|
4
|
-
*
|
|
5
|
-
* This source code is licensed under the BSD-style license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree. An additional grant
|
|
7
|
-
* of patent rights can be found in the PATENTS file in the same directory.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
#import <XCTest/XCTest.h>
|
|
11
|
-
|
|
12
|
-
#import "FBMathUtils.h"
|
|
13
|
-
#import "XCUICoordinate.h"
|
|
14
|
-
#import "XCUICoordinate+FBFix.h"
|
|
15
|
-
#import "XCUIElementDouble.h"
|
|
16
|
-
|
|
17
|
-
@interface XCUICoordinateFix : XCTestCase
|
|
18
|
-
@property (nonatomic, strong, nullable) XCUIElement *mockElement;
|
|
19
|
-
@property (nonatomic, strong, nullable) XCUICoordinate *defaultCoordinate;
|
|
20
|
-
@end
|
|
21
|
-
|
|
22
|
-
@implementation XCUICoordinateFix
|
|
23
|
-
|
|
24
|
-
- (void)setUp
|
|
25
|
-
{
|
|
26
|
-
[super setUp];
|
|
27
|
-
XCUIElementDouble *element = [XCUIElementDouble new];
|
|
28
|
-
element.frame = CGRectMake(1, 2, 9, 10);
|
|
29
|
-
self.mockElement = (XCUIElement *)element;
|
|
30
|
-
self.defaultCoordinate = [[XCUICoordinate alloc] initWithElement:self.mockElement normalizedOffset:CGVectorMake(0.0, 0.0)];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
- (void)testCoordinateWithElement
|
|
34
|
-
{
|
|
35
|
-
XCUICoordinate *coordinate = [[XCUICoordinate alloc] initWithElement:self.mockElement normalizedOffset:CGVectorMake(0.0, 0.0)];
|
|
36
|
-
XCTAssertTrue(FBPointFuzzyEqualToPoint(coordinate.fb_screenPoint, CGPointMake(1, 2), 0.1));
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
- (void)testCoordinateWithElementWithOffset
|
|
40
|
-
{
|
|
41
|
-
XCUICoordinate *coordinate = [[XCUICoordinate alloc] initWithElement:self.mockElement normalizedOffset:CGVectorMake(0.5, 0.5)];
|
|
42
|
-
XCTAssertTrue(FBPointFuzzyEqualToPoint(coordinate.fb_screenPoint, CGPointMake(5.5, 7), 0.1));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
- (void)testCoordinateWithCoordinate
|
|
46
|
-
{
|
|
47
|
-
XCUICoordinate *coordinate = [[XCUICoordinate alloc] initWithCoordinate:self.defaultCoordinate pointsOffset:CGVectorMake(0, 0)];
|
|
48
|
-
XCTAssertTrue(FBPointFuzzyEqualToPoint(coordinate.fb_screenPoint, CGPointMake(1, 2), 0.1));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
- (void)testCoordinateWithCoordinateWithOffset
|
|
52
|
-
{
|
|
53
|
-
XCUICoordinate *coordinate = [[XCUICoordinate alloc] initWithCoordinate:self.defaultCoordinate pointsOffset:CGVectorMake(1, 2)];
|
|
54
|
-
XCTAssertTrue(FBPointFuzzyEqualToPoint(coordinate.fb_screenPoint, CGPointMake(2, 4), 0.1));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
- (void)testCoordinateWithCoordinateWithOffsetOffBounds
|
|
58
|
-
{
|
|
59
|
-
XCUICoordinate *coordinate = [[XCUICoordinate alloc] initWithCoordinate:self.defaultCoordinate pointsOffset:CGVectorMake(200, 200)];
|
|
60
|
-
XCTAssertTrue(FBPointFuzzyEqualToPoint(coordinate.fb_screenPoint, CGPointMake(10, 12), 0.1));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
@end
|