appium-webdriveragent 16.12.3 → 16.12.5
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 +18 -0
- package/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/IntegrationApp_watchOS.xcscheme +2 -0
- package/WebDriverAgentLib/Info.plist +2 -2
- package/WebDriverAgentTests/IntegrationApp/COORDINATE_PROBE.md +50 -0
- package/WebDriverAgentTests/IntegrationApp/Classes/FBCoordinateProbeViewController.h +4 -0
- package/WebDriverAgentTests/IntegrationApp/Classes/FBCoordinateProbeViewController.m +176 -0
- package/WebDriverAgentTests/IntegrationApp/Classes/FBScrollViewController.m +15 -2
- package/WebDriverAgentTests/IntegrationApp/Classes/TouchViewController.h +1 -1
- package/WebDriverAgentTests/IntegrationApp/Classes/TouchableView.h +2 -1
- package/WebDriverAgentTests/IntegrationApp/Classes/TouchableView.m +7 -2
- package/WebDriverAgentTests/IntegrationApp/Classes/ViewController.m +8 -2
- package/WebDriverAgentTests/IntegrationApp/Info.plist +2 -2
- package/WebDriverAgentTests/IntegrationApp/Resources/Base.lproj/Main.storyboard +40 -21
- package/WebDriverAgentTests/IntegrationTests/FBConfigurationTests.m +4 -5
- package/WebDriverAgentTests/IntegrationTests/FBElementVisibilityTests.m +8 -6
- package/WebDriverAgentTests/IntegrationTests/FBIntegrationAppTests.m +78 -0
- package/WebDriverAgentTests/IntegrationTests/FBIntegrationTestCase.m +1 -0
- package/WebDriverAgentTests/UnitTests/FBTouchableViewTests.m +121 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [16.12.5](https://github.com/appium/WebDriverAgent/compare/v16.12.4...v16.12.5) (2026-09-07)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* touch and scroll related view issue in IntegrationApp ([#1253](https://github.com/appium/WebDriverAgent/issues/1253)) ([34859e9](https://github.com/appium/WebDriverAgent/commit/34859e9b443c184505206576b3b531d85d2afbcf))
|
|
6
|
+
|
|
7
|
+
## [16.12.4](https://github.com/appium/WebDriverAgent/compare/v16.12.3...v16.12.4) (2026-09-06)
|
|
8
|
+
|
|
9
|
+
### Miscellaneous Chores
|
|
10
|
+
|
|
11
|
+
* add coordinate screen in the integration app ([#1251](https://github.com/appium/WebDriverAgent/issues/1251)) ([de6acac](https://github.com/appium/WebDriverAgent/commit/de6acac7ebbaf70915f0c09093e3a12623efcea2))
|
|
12
|
+
|
|
1
13
|
## [16.12.3](https://github.com/appium/WebDriverAgent/compare/v16.12.2...v16.12.3) (2026-09-04)
|
|
2
14
|
|
|
3
15
|
### Bug Fixes
|
|
@@ -932,6 +932,7 @@
|
|
|
932
932
|
BEA2FA45BED17FE03010FECD /* FBFindElementCommands.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB7581CAEDF0C008C271F /* FBFindElementCommands.h */; };
|
|
933
933
|
BF9B191D841681A571BAFED1 /* _XCTestObservationPrivate-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = C840A8703A7C8D48897E158A /* _XCTestObservationPrivate-Protocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
934
934
|
BFF5D9B9446DD542E5D6017D /* XCTTagSelection.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E2092D85A7C691F157B1971 /* XCTTagSelection.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
935
|
+
C01249000000000000000003 /* FBCoordinateProbeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C01249000000000000000002 /* FBCoordinateProbeViewController.m */; };
|
|
935
936
|
C040AE5F2E3B934E8EEAEE0F /* XCUIApplicationProcessDelegate-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 43FCB89739438814F43BCA24 /* XCUIApplicationProcessDelegate-Protocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
936
937
|
C07F140AF96143A0A5CAA2B0 /* XCTestCaseDiscoveryUIAutomationDelegate-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = E29888B75A756D1CCD21604C /* XCTestCaseDiscoveryUIAutomationDelegate-Protocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
937
938
|
C1414C29C836902466C4D6DB /* XCTestCastMethodNamesUIAutomationDelegate-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = A80A1C12FA9899367D316E8C /* XCTestCastMethodNamesUIAutomationDelegate-Protocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
@@ -1269,6 +1270,10 @@
|
|
|
1269
1270
|
FEC3A97A4929115A192F947A /* XCUIDeviceEventAndStateInterface-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 003AAAB9CB5FB38E45E05F6F /* XCUIDeviceEventAndStateInterface-Protocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
1270
1271
|
FFA7672B731B57AB9283DD40 /* FBXCElementSnapshotWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 13DE7A53287CA1EC003243C6 /* FBXCElementSnapshotWrapper.h */; };
|
|
1271
1272
|
FFD70914E6D8CE5D4FED4B69 /* XCUIAXNotificationHandling-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = EA96C2FEDE73CB5148BA4949 /* XCUIAXNotificationHandling-Protocol.h */; };
|
|
1273
|
+
6C07E44E139D41D6BA092F39 /* FBTouchableViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D04760558C64B8EB69380E0 /* FBTouchableViewTests.m */; };
|
|
1274
|
+
C15E49E6B6924191BAAD9FDF /* FBIntegrationAppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 27B518E261C14E29B943AB9B /* FBIntegrationAppTests.m */; };
|
|
1275
|
+
81E462B8A75F497CBFC6FD8B /* TouchableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 315A15002518CB8700A3A064 /* TouchableView.m */; };
|
|
1276
|
+
B6DE70BFF27148BDAC72F80C /* TouchSpotView.m in Sources */ = {isa = PBXBuildFile; fileRef = 315A15062518CC2800A3A064 /* TouchSpotView.m */; };
|
|
1272
1277
|
/* End PBXBuildFile section */
|
|
1273
1278
|
|
|
1274
1279
|
/* Begin PBXContainerItemProxy section */
|
|
@@ -1748,6 +1753,8 @@
|
|
|
1748
1753
|
B8A163261EFA440E42CA6AC1 /* XCTRunnerDaemonSessionUIAutomationDelegate-Protocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "XCTRunnerDaemonSessionUIAutomationDelegate-Protocol.h"; sourceTree = "<group>"; };
|
|
1749
1754
|
B98A9F937EF98D6359FCCC7A /* XCTRuntimeIssueDetectionPolicy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = XCTRuntimeIssueDetectionPolicy.h; sourceTree = "<group>"; };
|
|
1750
1755
|
BCED63DFD03326F6351165FE /* WDAFindIntegrationTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = WDAFindIntegrationTests.swift; sourceTree = "<group>"; };
|
|
1756
|
+
C01249000000000000000001 /* FBCoordinateProbeViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBCoordinateProbeViewController.h; sourceTree = "<group>"; };
|
|
1757
|
+
C01249000000000000000002 /* FBCoordinateProbeViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBCoordinateProbeViewController.m; sourceTree = "<group>"; };
|
|
1751
1758
|
C840A8703A7C8D48897E158A /* _XCTestObservationPrivate-Protocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "_XCTestObservationPrivate-Protocol.h"; sourceTree = "<group>"; };
|
|
1752
1759
|
C878996F07A9B26E66FC4EAC /* WDAClickIntegrationTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = WDAClickIntegrationTests.swift; sourceTree = "<group>"; };
|
|
1753
1760
|
C8FB547322D3949C00B69954 /* LSApplicationWorkspace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSApplicationWorkspace.h; sourceTree = "<group>"; };
|
|
@@ -1959,6 +1966,8 @@
|
|
|
1959
1966
|
FCD1815F2BF21CA0936B04E1 /* XCTMessagingRole_SiriAutomation-Protocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "XCTMessagingRole_SiriAutomation-Protocol.h"; sourceTree = "<group>"; };
|
|
1960
1967
|
FDB15E393EA0850C004D26B2 /* XCTScreenCapturePolicy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = XCTScreenCapturePolicy.h; sourceTree = "<group>"; };
|
|
1961
1968
|
FF8E3B470FC9639D5F18E2EA /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
|
1969
|
+
1D04760558C64B8EB69380E0 /* FBTouchableViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBTouchableViewTests.m; sourceTree = "<group>"; };
|
|
1970
|
+
27B518E261C14E29B943AB9B /* FBIntegrationAppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBIntegrationAppTests.m; sourceTree = "<group>"; };
|
|
1962
1971
|
/* End PBXFileReference section */
|
|
1963
1972
|
|
|
1964
1973
|
/* Begin PBXFrameworksBuildPhase section */
|
|
@@ -2629,6 +2638,7 @@
|
|
|
2629
2638
|
EE9B76541CF7987300275851 /* IntegrationTests */ = {
|
|
2630
2639
|
isa = PBXGroup;
|
|
2631
2640
|
children = (
|
|
2641
|
+
27B518E261C14E29B943AB9B /* FBIntegrationAppTests.m */,
|
|
2632
2642
|
EE9B76991CF799F400275851 /* FBAlertTests.m */,
|
|
2633
2643
|
719CD8FE2126C90200C7D0C2 /* FBAutoAlertsHandlerTests.m */,
|
|
2634
2644
|
EE26409C1D0EBA25009BE6B0 /* FBElementAttributeTests.m */,
|
|
@@ -2672,6 +2682,7 @@
|
|
|
2672
2682
|
EE9B76561CF7987300275851 /* UnitTests */ = {
|
|
2673
2683
|
isa = PBXGroup;
|
|
2674
2684
|
children = (
|
|
2685
|
+
1D04760558C64B8EB69380E0 /* FBTouchableViewTests.m */,
|
|
2675
2686
|
ADBC39951D07840300327304 /* Doubles */,
|
|
2676
2687
|
71A7EAFB1E229302001DA4F2 /* FBClassChainTests.m */,
|
|
2677
2688
|
EEE16E961D33A25500172525 /* FBConfigurationTests.m */,
|
|
@@ -2732,6 +2743,8 @@
|
|
|
2732
2743
|
EE55B3231D1D5388003AAAEC /* FBTableDataSource.m */,
|
|
2733
2744
|
EE9B76841CF7997600275851 /* ViewController.h */,
|
|
2734
2745
|
EE9B76851CF7997600275851 /* ViewController.m */,
|
|
2746
|
+
C01249000000000000000001 /* FBCoordinateProbeViewController.h */,
|
|
2747
|
+
C01249000000000000000002 /* FBCoordinateProbeViewController.m */,
|
|
2735
2748
|
315A14FF2518CB8700A3A064 /* TouchableView.h */,
|
|
2736
2749
|
315A15002518CB8700A3A064 /* TouchableView.m */,
|
|
2737
2750
|
315A15052518CC2800A3A064 /* TouchSpotView.h */,
|
|
@@ -4809,6 +4822,9 @@
|
|
|
4809
4822
|
isa = PBXSourcesBuildPhase;
|
|
4810
4823
|
buildActionMask = 2147483647;
|
|
4811
4824
|
files = (
|
|
4825
|
+
B6DE70BFF27148BDAC72F80C /* TouchSpotView.m in Sources */,
|
|
4826
|
+
81E462B8A75F497CBFC6FD8B /* TouchableView.m in Sources */,
|
|
4827
|
+
6C07E44E139D41D6BA092F39 /* FBTouchableViewTests.m in Sources */,
|
|
4812
4828
|
713352FD26CEF31D00523CBC /* FBLRUCacheTests.m in Sources */,
|
|
4813
4829
|
EE3F8CFE1D08AA17006F02CE /* FBRunLoopSpinnerTests.m in Sources */,
|
|
4814
4830
|
A09D847635CA4C155583B967 /* FBXCAXClientProxyTests.m in Sources */,
|
|
@@ -4851,6 +4867,7 @@
|
|
|
4851
4867
|
315A15072518CC2800A3A064 /* TouchSpotView.m in Sources */,
|
|
4852
4868
|
EE9B76911CF7997600275851 /* main.m in Sources */,
|
|
4853
4869
|
EE9B768F1CF7997600275851 /* ViewController.m in Sources */,
|
|
4870
|
+
C01249000000000000000003 /* FBCoordinateProbeViewController.m in Sources */,
|
|
4854
4871
|
315A15012518CB8700A3A064 /* TouchableView.m in Sources */,
|
|
4855
4872
|
315A150A2518D6F400A3A064 /* TouchViewController.m in Sources */,
|
|
4856
4873
|
ADDA07241D6BB2BF001700AC /* FBScrollViewController.m in Sources */,
|
|
@@ -4863,6 +4880,7 @@
|
|
|
4863
4880
|
isa = PBXSourcesBuildPhase;
|
|
4864
4881
|
buildActionMask = 2147483647;
|
|
4865
4882
|
files = (
|
|
4883
|
+
C15E49E6B6924191BAAD9FDF /* FBIntegrationAppTests.m in Sources */,
|
|
4866
4884
|
EE26409D1D0EBA25009BE6B0 /* FBElementAttributeTests.m in Sources */,
|
|
4867
4885
|
7119E1EC1E891F8600D0B125 /* FBPickerWheelSelectTests.m in Sources */,
|
|
4868
4886
|
71ACF5B8242F2FDC00F0AAD4 /* FBSafariAlertTests.m in Sources */,
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
BuildableIdentifier = "primary"
|
|
47
47
|
BlueprintIdentifier = "9D6B02D8FC050BAF7159284F"
|
|
48
48
|
BuildableName = "IntegrationApp_watchOS.app"
|
|
49
|
+
BlueprintName = "IntegrationApp_watchOS"
|
|
49
50
|
ReferencedContainer = "container:WebDriverAgent.xcodeproj">
|
|
50
51
|
</BuildableReference>
|
|
51
52
|
</BuildableProductRunnable>
|
|
@@ -62,6 +63,7 @@
|
|
|
62
63
|
BuildableIdentifier = "primary"
|
|
63
64
|
BlueprintIdentifier = "9D6B02D8FC050BAF7159284F"
|
|
64
65
|
BuildableName = "IntegrationApp_watchOS.app"
|
|
66
|
+
BlueprintName = "IntegrationApp_watchOS"
|
|
65
67
|
ReferencedContainer = "container:WebDriverAgent.xcodeproj">
|
|
66
68
|
</BuildableReference>
|
|
67
69
|
</BuildableProductRunnable>
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
<key>CFBundlePackageType</key>
|
|
16
16
|
<string>FMWK</string>
|
|
17
17
|
<key>CFBundleShortVersionString</key>
|
|
18
|
-
<string>16.12.
|
|
18
|
+
<string>16.12.5</string>
|
|
19
19
|
<key>CFBundleSignature</key>
|
|
20
20
|
<string>????</string>
|
|
21
21
|
<key>CFBundleVersion</key>
|
|
22
|
-
<string>16.12.
|
|
22
|
+
<string>16.12.5</string>
|
|
23
23
|
<key>NSPrincipalClass</key>
|
|
24
24
|
<string/>
|
|
25
25
|
</dict>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Coordinate probe
|
|
2
|
+
|
|
3
|
+
Open **Coordinate Probe** below **DeepHierarchy** on the IntegrationApp home screen.
|
|
4
|
+
Use the standard Back button to return to the existing fixtures. Opening the probe
|
|
5
|
+
creates a fresh measurement session.
|
|
6
|
+
|
|
7
|
+
The **Touch** canvas records actual `UITouch.locationInView:` coordinates rather
|
|
8
|
+
than assuming that a gesture succeeded because it hit a large button. **Scroll**
|
|
9
|
+
shows 80 numbered rows, each 44 points high.
|
|
10
|
+
|
|
11
|
+
## Automation identifiers
|
|
12
|
+
|
|
13
|
+
| Identifier | Purpose |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| `coordinate-probe` | Home screen button that opens the probe |
|
|
16
|
+
| `probe-status` | Label containing the measurement JSON |
|
|
17
|
+
| `coordinate-canvas` | Touch target |
|
|
18
|
+
| `probe-mode` | Touch/Scroll segmented control |
|
|
19
|
+
| `probe-table` | Scrollable table |
|
|
20
|
+
| `probe-row-0` through `probe-row-79` | Individual table rows |
|
|
21
|
+
|
|
22
|
+
The `probe-status` label exposes `start`, `last`, `phase`, and `count` after a
|
|
23
|
+
touch. `start` and `last` are **canvas-local app points**. It also exposes
|
|
24
|
+
`canvasBounds`, `canvasWindowRect`, `windowSize`, `screenSize`, and `scrollY`.
|
|
25
|
+
Geometry is refreshed when the view lays out, including after rotation or window
|
|
26
|
+
resizing. Touch-related fields are absent before the first touch.
|
|
27
|
+
|
|
28
|
+
For example, locate `coordinate-probe` by accessibility ID and click it. Then
|
|
29
|
+
locate `coordinate-canvas`, send an element-relative action, and read the JSON
|
|
30
|
+
from `probe-status`. Check that `count` increased and compare `start`/`last` with
|
|
31
|
+
the expected canvas-local point within a suitable tolerance. Derive test offsets
|
|
32
|
+
from the current element rectangle rather than hard-coding a device size.
|
|
33
|
+
|
|
34
|
+
## Native and compatibility builds
|
|
35
|
+
|
|
36
|
+
The screen uses the same source for both configurations. Keep the IntegrationApp
|
|
37
|
+
scheme and set the build's `TARGETED_DEVICE_FAMILY`:
|
|
38
|
+
|
|
39
|
+
- `1,2`: native support for iPhone and iPad (the existing default).
|
|
40
|
+
- `1`: iPhone-only; install on iPad to exercise iPhone compatibility mode.
|
|
41
|
+
|
|
42
|
+
These are build settings, not a switch within the running app. Verify the actual
|
|
43
|
+
window and element frames before interpreting results. An iPad-native app can
|
|
44
|
+
also run in a resized window; maximize it when testing a full-screen native case.
|
|
45
|
+
For the compatibility case, compare app and SpringBoard window sizes and the
|
|
46
|
+
reported element rectangles with the recorded probe geometry.
|
|
47
|
+
|
|
48
|
+
If keeping both builds installed at once, give them distinct bundle IDs. This
|
|
49
|
+
change does not add another app target or alter the existing bundle ID or signing
|
|
50
|
+
configuration.
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
#import "FBCoordinateProbeViewController.h"
|
|
2
|
+
|
|
3
|
+
@interface FBCoordinateProbeCanvas : UIView
|
|
4
|
+
@property (nonatomic, copy) void (^onTouch)(NSString *phase, CGPoint point);
|
|
5
|
+
@end
|
|
6
|
+
|
|
7
|
+
@implementation FBCoordinateProbeCanvas
|
|
8
|
+
|
|
9
|
+
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
|
10
|
+
{
|
|
11
|
+
self.onTouch(@"began", [touches.anyObject locationInView:self]);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
|
15
|
+
{
|
|
16
|
+
self.onTouch(@"moved", [touches.anyObject locationInView:self]);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
|
20
|
+
{
|
|
21
|
+
self.onTouch(@"ended", [touches.anyObject locationInView:self]);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
|
25
|
+
{
|
|
26
|
+
self.onTouch(@"cancelled", [touches.anyObject locationInView:self]);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
- (void)drawRect:(CGRect)rect
|
|
30
|
+
{
|
|
31
|
+
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
32
|
+
CGContextSetStrokeColorWithColor(context, UIColor.whiteColor.CGColor);
|
|
33
|
+
for (NSInteger i = 1; i < 4; i++) {
|
|
34
|
+
CGFloat x = CGRectGetWidth(self.bounds) * i / 4.0;
|
|
35
|
+
CGFloat y = CGRectGetHeight(self.bounds) * i / 4.0;
|
|
36
|
+
CGContextMoveToPoint(context, x, 0);
|
|
37
|
+
CGContextAddLineToPoint(context, x, CGRectGetHeight(self.bounds));
|
|
38
|
+
CGContextMoveToPoint(context, 0, y);
|
|
39
|
+
CGContextAddLineToPoint(context, CGRectGetWidth(self.bounds), y);
|
|
40
|
+
}
|
|
41
|
+
CGContextStrokePath(context);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@end
|
|
45
|
+
|
|
46
|
+
@interface FBCoordinateProbeViewController () <UITableViewDataSource, UITableViewDelegate>
|
|
47
|
+
@property (nonatomic, strong) UILabel *statusLabel;
|
|
48
|
+
@property (nonatomic, strong) UISegmentedControl *modeControl;
|
|
49
|
+
@property (nonatomic, strong) FBCoordinateProbeCanvas *canvas;
|
|
50
|
+
@property (nonatomic, strong) UITableView *table;
|
|
51
|
+
@property (nonatomic, strong) NSMutableDictionary<NSString *, id> *measurement;
|
|
52
|
+
@property (nonatomic) NSUInteger touchCount;
|
|
53
|
+
@end
|
|
54
|
+
|
|
55
|
+
@implementation FBCoordinateProbeViewController
|
|
56
|
+
|
|
57
|
+
- (void)viewDidLoad
|
|
58
|
+
{
|
|
59
|
+
[super viewDidLoad];
|
|
60
|
+
self.title = @"Coordinate Probe";
|
|
61
|
+
self.view.backgroundColor = UIColor.systemBackgroundColor;
|
|
62
|
+
self.measurement = [NSMutableDictionary dictionary];
|
|
63
|
+
|
|
64
|
+
self.statusLabel = [UILabel new];
|
|
65
|
+
self.statusLabel.accessibilityIdentifier = @"probe-status";
|
|
66
|
+
self.statusLabel.font = [UIFont monospacedSystemFontOfSize:10 weight:UIFontWeightRegular];
|
|
67
|
+
self.statusLabel.numberOfLines = 0;
|
|
68
|
+
[self.view addSubview:self.statusLabel];
|
|
69
|
+
|
|
70
|
+
self.modeControl = [[UISegmentedControl alloc] initWithItems:@[@"Touch", @"Scroll"]];
|
|
71
|
+
self.modeControl.accessibilityIdentifier = @"probe-mode";
|
|
72
|
+
self.modeControl.selectedSegmentIndex = 0;
|
|
73
|
+
[self.modeControl addTarget:self action:@selector(modeChanged) forControlEvents:UIControlEventValueChanged];
|
|
74
|
+
[self.view addSubview:self.modeControl];
|
|
75
|
+
|
|
76
|
+
self.canvas = [FBCoordinateProbeCanvas new];
|
|
77
|
+
self.canvas.backgroundColor = UIColor.systemBlueColor;
|
|
78
|
+
self.canvas.isAccessibilityElement = YES;
|
|
79
|
+
self.canvas.accessibilityIdentifier = @"coordinate-canvas";
|
|
80
|
+
self.canvas.accessibilityLabel = @"Coordinate canvas";
|
|
81
|
+
self.canvas.accessibilityTraits = UIAccessibilityTraitAllowsDirectInteraction;
|
|
82
|
+
self.canvas.contentMode = UIViewContentModeRedraw;
|
|
83
|
+
__weak typeof(self) weakSelf = self;
|
|
84
|
+
self.canvas.onTouch = ^(NSString *phase, CGPoint point) {
|
|
85
|
+
FBCoordinateProbeViewController *controller = weakSelf;
|
|
86
|
+
if (nil == controller) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if ([phase isEqualToString:@"began"]) {
|
|
90
|
+
controller.touchCount++;
|
|
91
|
+
controller.measurement[@"start"] = @[@(point.x), @(point.y)];
|
|
92
|
+
}
|
|
93
|
+
controller.measurement[@"last"] = @[@(point.x), @(point.y)];
|
|
94
|
+
controller.measurement[@"phase"] = phase;
|
|
95
|
+
controller.measurement[@"count"] = @(controller.touchCount);
|
|
96
|
+
[controller publishMeasurement];
|
|
97
|
+
};
|
|
98
|
+
[self.view addSubview:self.canvas];
|
|
99
|
+
|
|
100
|
+
self.table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
|
|
101
|
+
self.table.accessibilityIdentifier = @"probe-table";
|
|
102
|
+
self.table.rowHeight = 44;
|
|
103
|
+
self.table.dataSource = self;
|
|
104
|
+
self.table.delegate = self;
|
|
105
|
+
self.table.hidden = YES;
|
|
106
|
+
[self.view addSubview:self.table];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
- (void)viewDidLayoutSubviews
|
|
110
|
+
{
|
|
111
|
+
[super viewDidLayoutSubviews];
|
|
112
|
+
// Use the app's actual available area, including navigation bars and resized iPad windows.
|
|
113
|
+
CGRect safeFrame = self.view.safeAreaLayoutGuide.layoutFrame;
|
|
114
|
+
CGFloat width = MAX(0, CGRectGetWidth(safeFrame) - 40);
|
|
115
|
+
CGFloat left = CGRectGetMinX(safeFrame) + 20;
|
|
116
|
+
CGFloat top = CGRectGetMinY(safeFrame) + 8;
|
|
117
|
+
self.statusLabel.frame = CGRectMake(left, top, width, 96);
|
|
118
|
+
self.modeControl.frame = CGRectMake(left, top + 104, width, 30);
|
|
119
|
+
CGRect contentFrame = CGRectMake(left, top + 146, width,
|
|
120
|
+
MAX(0, CGRectGetMaxY(safeFrame) - top - 166));
|
|
121
|
+
self.canvas.frame = contentFrame;
|
|
122
|
+
self.table.frame = contentFrame;
|
|
123
|
+
[self publishMeasurement];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
- (void)publishMeasurement
|
|
127
|
+
{
|
|
128
|
+
UIWindow *window = self.view.window;
|
|
129
|
+
if (nil == window) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
CGRect bounds = self.canvas.bounds;
|
|
133
|
+
CGRect frame = [self.canvas convertRect:bounds toView:window];
|
|
134
|
+
// Touch coordinates are local to the canvas. Window geometry lets tests compare
|
|
135
|
+
// those measurements with WDA's element rectangles without assuming a screen size.
|
|
136
|
+
self.measurement[@"canvasBounds"] = @[@(bounds.size.width), @(bounds.size.height)];
|
|
137
|
+
self.measurement[@"canvasWindowRect"] = @[@(frame.origin.x), @(frame.origin.y),
|
|
138
|
+
@(frame.size.width), @(frame.size.height)];
|
|
139
|
+
self.measurement[@"windowSize"] = @[@(window.bounds.size.width), @(window.bounds.size.height)];
|
|
140
|
+
self.measurement[@"screenSize"] = @[@(window.screen.bounds.size.width), @(window.screen.bounds.size.height)];
|
|
141
|
+
self.measurement[@"scrollY"] = @(self.table.contentOffset.y);
|
|
142
|
+
NSData *data = [NSJSONSerialization dataWithJSONObject:self.measurement
|
|
143
|
+
options:NSJSONWritingSortedKeys
|
|
144
|
+
error:nil];
|
|
145
|
+
self.statusLabel.text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
- (void)modeChanged
|
|
149
|
+
{
|
|
150
|
+
self.canvas.hidden = self.modeControl.selectedSegmentIndex == 1;
|
|
151
|
+
self.table.hidden = !self.canvas.hidden;
|
|
152
|
+
[self publishMeasurement];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
|
156
|
+
{
|
|
157
|
+
return 80;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
|
161
|
+
{
|
|
162
|
+
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"probe-row"];
|
|
163
|
+
if (nil == cell) {
|
|
164
|
+
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"probe-row"];
|
|
165
|
+
}
|
|
166
|
+
cell.textLabel.text = [NSString stringWithFormat:@"Probe row %ld", (long)indexPath.row];
|
|
167
|
+
cell.accessibilityIdentifier = [NSString stringWithFormat:@"probe-row-%ld", (long)indexPath.row];
|
|
168
|
+
return cell;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
|
|
172
|
+
{
|
|
173
|
+
[self publishMeasurement];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@end
|
|
@@ -15,6 +15,7 @@ static const CGFloat FBSubviewHeight = 40.0;
|
|
|
15
15
|
@interface FBScrollViewController ()
|
|
16
16
|
@property (nonatomic, weak) IBOutlet UIScrollView *scrollView;
|
|
17
17
|
@property (nonatomic, strong) IBOutlet FBTableDataSource *dataSource;
|
|
18
|
+
@property (nonatomic, copy) NSArray<UILabel *> *rowLabels;
|
|
18
19
|
@end
|
|
19
20
|
|
|
20
21
|
@implementation FBScrollViewController
|
|
@@ -22,18 +23,30 @@ static const CGFloat FBSubviewHeight = 40.0;
|
|
|
22
23
|
- (void)viewDidLoad {
|
|
23
24
|
[super viewDidLoad];
|
|
24
25
|
[self setupLabelViews];
|
|
25
|
-
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
- (void)viewDidLayoutSubviews
|
|
29
|
+
{
|
|
30
|
+
[super viewDidLayoutSubviews];
|
|
31
|
+
CGFloat width = CGRectGetWidth(self.scrollView.bounds);
|
|
32
|
+
[self.rowLabels enumerateObjectsUsingBlock:^(UILabel *label, NSUInteger index, BOOL *stop) {
|
|
33
|
+
label.frame = CGRectMake(0, index * FBSubviewHeight, width, FBSubviewHeight);
|
|
34
|
+
}];
|
|
35
|
+
self.scrollView.contentSize = CGSizeMake(width, self.rowLabels.count * FBSubviewHeight);
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
- (void)setupLabelViews
|
|
29
39
|
{
|
|
30
40
|
NSUInteger count = self.dataSource.count;
|
|
41
|
+
NSMutableArray<UILabel *> *labels = [NSMutableArray arrayWithCapacity:count];
|
|
31
42
|
for (NSInteger i = 0 ; i < count ; i++) {
|
|
32
|
-
UILabel *label = [
|
|
43
|
+
UILabel *label = [UILabel new];
|
|
33
44
|
label.text = [self.dataSource textForElementAtIndex:i];
|
|
34
45
|
label.textAlignment = NSTextAlignmentCenter;
|
|
35
46
|
[self.scrollView addSubview:label];
|
|
47
|
+
[labels addObject:label];
|
|
36
48
|
}
|
|
49
|
+
self.rowLabels = labels;
|
|
37
50
|
}
|
|
38
51
|
|
|
39
52
|
@end
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
NS_ASSUME_NONNULL_BEGIN
|
|
13
13
|
|
|
14
|
-
@interface TouchViewController : UIViewController
|
|
14
|
+
@interface TouchViewController : UIViewController <TouchableViewDelegate>
|
|
15
15
|
|
|
16
16
|
@property (weak, nonatomic) IBOutlet TouchableView *touchable;
|
|
17
17
|
@property (weak, nonatomic) IBOutlet UILabel *numberOfTapsLabel;
|
|
@@ -21,8 +21,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
21
21
|
@interface TouchableView : UIView
|
|
22
22
|
|
|
23
23
|
@property (nonatomic) NSMutableDictionary<NSNumber*, TouchSpotView*> *touchViews;
|
|
24
|
+
// Cumulative completed contacts; cancelled contacts are excluded.
|
|
24
25
|
@property (nonatomic) int numberOFTaps;
|
|
25
|
-
@property (nonatomic) id delegate;
|
|
26
|
+
@property (nonatomic, weak, nullable) id<TouchableViewDelegate> delegate;
|
|
26
27
|
|
|
27
28
|
@end
|
|
28
29
|
|
|
@@ -34,12 +34,11 @@
|
|
|
34
34
|
|
|
35
35
|
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
|
36
36
|
{
|
|
37
|
-
self.numberOFTaps += 1;
|
|
38
|
-
[self.delegate shouldHandleTouchesNumber:(int)touches.count];
|
|
39
37
|
for (UITouch *touch in touches)
|
|
40
38
|
{
|
|
41
39
|
[self createViewForTouch:touch];
|
|
42
40
|
}
|
|
41
|
+
[self.delegate shouldHandleTouchesNumber:(int)self.touchViews.count];
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
|
@@ -56,8 +55,13 @@
|
|
|
56
55
|
{
|
|
57
56
|
for (UITouch *touch in touches)
|
|
58
57
|
{
|
|
58
|
+
// Count completed contacts, independently of how UIKit batches callbacks.
|
|
59
|
+
if ([self viewForTouch:touch] != nil) {
|
|
60
|
+
self.numberOFTaps += 1;
|
|
61
|
+
}
|
|
59
62
|
[self removeViewForTouch:touch];
|
|
60
63
|
}
|
|
64
|
+
[self.delegate shouldHandleTouchesNumber:(int)self.touchViews.count];
|
|
61
65
|
[self.delegate shouldHandleTapsNumber:self.numberOFTaps];
|
|
62
66
|
}
|
|
63
67
|
|
|
@@ -67,6 +71,7 @@
|
|
|
67
71
|
{
|
|
68
72
|
[self removeViewForTouch:touch];
|
|
69
73
|
}
|
|
74
|
+
[self.delegate shouldHandleTouchesNumber:(int)self.touchViews.count];
|
|
70
75
|
}
|
|
71
76
|
|
|
72
77
|
- (void)createViewForTouch:(UITouch *)touch
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
#import "ViewController.h"
|
|
10
|
+
#import "FBCoordinateProbeViewController.h"
|
|
10
11
|
|
|
11
12
|
@interface ViewController ()
|
|
12
13
|
@property (weak, nonatomic) IBOutlet UILabel *orentationLabel;
|
|
@@ -30,6 +31,11 @@
|
|
|
30
31
|
self.button.accessibilityCustomActions = @[action1, action2];
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
- (IBAction)showCoordinateProbe:(id)sender
|
|
35
|
+
{
|
|
36
|
+
[self.navigationController pushViewController:[FBCoordinateProbeViewController new] animated:NO];
|
|
37
|
+
}
|
|
38
|
+
|
|
33
39
|
- (BOOL)handleCustomAction:(UIAccessibilityCustomAction *)action
|
|
34
40
|
{
|
|
35
41
|
// Custom action handler - just return YES to indicate success
|
|
@@ -57,13 +63,13 @@
|
|
|
57
63
|
// lay out. This page exists purely as a fixture for exercising element
|
|
58
64
|
// lookups (e.g. class chain locators) against a deep accessibility tree.
|
|
59
65
|
UIViewController *deepHierarchyViewController = [UIViewController new];
|
|
60
|
-
deepHierarchyViewController.view.backgroundColor = UIColor.
|
|
66
|
+
deepHierarchyViewController.view.backgroundColor = UIColor.systemBackgroundColor;
|
|
61
67
|
deepHierarchyViewController.view.accessibilityIdentifier = @"DeepHierarchyPage";
|
|
62
68
|
|
|
63
69
|
NSInteger depth = 70;
|
|
64
70
|
// A plain UILabel sibling, not part of the nested chain below, so the
|
|
65
71
|
// fixture stays recognizable to a human glancing at the simulator instead
|
|
66
|
-
// of showing a blank
|
|
72
|
+
// of showing a blank screen.
|
|
67
73
|
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 60, CGRectGetWidth(UIScreen.mainScreen.bounds) - 40, 60)];
|
|
68
74
|
titleLabel.text = [NSString stringWithFormat:@"Deep Hierarchy\n%ld nested elements", (long)depth];
|
|
69
75
|
titleLabel.numberOfLines = 2;
|
|
@@ -30,8 +30,6 @@
|
|
|
30
30
|
<string>Yo Yo</string>
|
|
31
31
|
<key>NSPhotoLibraryUsageDescription</key>
|
|
32
32
|
<string>Yo Yo</string>
|
|
33
|
-
<key>UILaunchStoryboardName</key>
|
|
34
|
-
<string>LaunchScreen</string>
|
|
35
33
|
<key>UIApplicationSceneManifest</key>
|
|
36
34
|
<dict>
|
|
37
35
|
<key>UIApplicationSupportsMultipleScenes</key>
|
|
@@ -49,6 +47,8 @@
|
|
|
49
47
|
</array>
|
|
50
48
|
</dict>
|
|
51
49
|
</dict>
|
|
50
|
+
<key>UILaunchStoryboardName</key>
|
|
51
|
+
<string>LaunchScreen</string>
|
|
52
52
|
<key>UIRequiredDeviceCapabilities</key>
|
|
53
53
|
<array>
|
|
54
54
|
<string>armv7</string>
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
<dependencies>
|
|
5
5
|
<deployment identifier="iOS"/>
|
|
6
6
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
|
|
7
|
+
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
|
7
8
|
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
|
8
9
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
|
9
10
|
</dependencies>
|
|
@@ -83,8 +84,19 @@
|
|
|
83
84
|
<action selector="goToDeepHierarchy:" destination="BYZ-38-t0r" eventType="touchUpInside" id="dHi-03-Act"/>
|
|
84
85
|
</connections>
|
|
85
86
|
</button>
|
|
87
|
+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cPr-01-Btn">
|
|
88
|
+
<rect key="frame" x="139" y="418" width="136" height="30"/>
|
|
89
|
+
<accessibility key="accessibilityConfiguration" identifier="coordinate-probe"/>
|
|
90
|
+
<constraints>
|
|
91
|
+
<constraint firstAttribute="height" constant="30" id="cPr-02-Hgt"/>
|
|
92
|
+
</constraints>
|
|
93
|
+
<state key="normal" title="Coordinate Probe"/>
|
|
94
|
+
<connections>
|
|
95
|
+
<action selector="showCoordinateProbe:" destination="BYZ-38-t0r" eventType="touchUpInside" id="cPr-03-Act"/>
|
|
96
|
+
</connections>
|
|
97
|
+
</button>
|
|
86
98
|
</subviews>
|
|
87
|
-
<color key="backgroundColor"
|
|
99
|
+
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
88
100
|
<accessibility key="accessibilityConfiguration" label="MainView"/>
|
|
89
101
|
<constraints>
|
|
90
102
|
<constraint firstItem="YgP-SF-TkS" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="41Q-cm-l5K"/>
|
|
@@ -101,6 +113,8 @@
|
|
|
101
113
|
<constraint firstItem="M2N-Yn-ytb" firstAttribute="top" secondItem="YgP-SF-TkS" secondAttribute="bottom" constant="8" id="tMN-gl-smg"/>
|
|
102
114
|
<constraint firstItem="dHi-01-Btn" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="dHi-04-Cnt"/>
|
|
103
115
|
<constraint firstItem="dHi-01-Btn" firstAttribute="top" secondItem="1Ht-AF-MGW" secondAttribute="bottom" constant="8" id="dHi-05-Top"/>
|
|
116
|
+
<constraint firstItem="cPr-01-Btn" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="cPr-04-Cnt"/>
|
|
117
|
+
<constraint firstItem="cPr-01-Btn" firstAttribute="top" secondItem="dHi-01-Btn" secondAttribute="bottom" constant="8" id="cPr-05-Top"/>
|
|
104
118
|
</constraints>
|
|
105
119
|
</view>
|
|
106
120
|
<navigationItem key="navigationItem" id="dmu-Fe-aoT"/>
|
|
@@ -129,7 +143,7 @@
|
|
|
129
143
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
130
144
|
<accessibility key="accessibilityConfiguration" identifier="touchableView"/>
|
|
131
145
|
<constraints>
|
|
132
|
-
<constraint firstAttribute="width" secondItem="C6B-Wo-jWm" secondAttribute="height" multiplier="288:269" id="LeW-u7-tWl"/>
|
|
146
|
+
<constraint firstAttribute="width" secondItem="C6B-Wo-jWm" secondAttribute="height" multiplier="288:269" priority="749" id="LeW-u7-tWl"/>
|
|
133
147
|
</constraints>
|
|
134
148
|
</view>
|
|
135
149
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Taps" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IV8-Ak-Z8e">
|
|
@@ -147,17 +161,19 @@
|
|
|
147
161
|
<nil key="highlightedColor"/>
|
|
148
162
|
</label>
|
|
149
163
|
</subviews>
|
|
164
|
+
<viewLayoutGuide key="safeArea" id="tch-sa-Area"/>
|
|
150
165
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
151
166
|
<constraints>
|
|
152
|
-
<constraint firstItem="C6B-Wo-jWm" firstAttribute="top" secondItem="
|
|
153
|
-
<constraint firstAttribute="
|
|
154
|
-
<constraint firstAttribute="trailing" secondItem="
|
|
155
|
-
<constraint firstItem="IV8-Ak-Z8e" firstAttribute="
|
|
156
|
-
<constraint firstAttribute="
|
|
157
|
-
<constraint firstItem="
|
|
158
|
-
<constraint firstItem="Q4X-EY-aSL" firstAttribute="top" secondItem="IV8-Ak-Z8e" secondAttribute="bottom" constant="
|
|
159
|
-
<constraint firstItem="
|
|
160
|
-
<constraint firstItem="
|
|
167
|
+
<constraint firstItem="C6B-Wo-jWm" firstAttribute="top" secondItem="tch-sa-Area" secondAttribute="top" constant="8" id="1PW-tn-oTF"/>
|
|
168
|
+
<constraint firstItem="C6B-Wo-jWm" firstAttribute="leading" secondItem="tch-sa-Area" secondAttribute="leading" constant="16" id="pI7-Ds-hXG"/>
|
|
169
|
+
<constraint firstItem="tch-sa-Area" firstAttribute="trailing" secondItem="C6B-Wo-jWm" secondAttribute="trailing" constant="16" id="CaC-dk-dbo"/>
|
|
170
|
+
<constraint firstItem="IV8-Ak-Z8e" firstAttribute="top" secondItem="C6B-Wo-jWm" secondAttribute="bottom" constant="8" id="77y-Kf-c0Y"/>
|
|
171
|
+
<constraint firstItem="IV8-Ak-Z8e" firstAttribute="leading" secondItem="C6B-Wo-jWm" secondAttribute="leading" id="vbu-wn-Qvc"/>
|
|
172
|
+
<constraint firstItem="IV8-Ak-Z8e" firstAttribute="trailing" secondItem="C6B-Wo-jWm" secondAttribute="trailing" id="5Tn-XG-5OD"/>
|
|
173
|
+
<constraint firstItem="Q4X-EY-aSL" firstAttribute="top" secondItem="IV8-Ak-Z8e" secondAttribute="bottom" constant="8" id="ktv-kW-VWI"/>
|
|
174
|
+
<constraint firstItem="Q4X-EY-aSL" firstAttribute="leading" secondItem="C6B-Wo-jWm" secondAttribute="leading" id="Ych-oZ-hmA"/>
|
|
175
|
+
<constraint firstItem="Q4X-EY-aSL" firstAttribute="trailing" secondItem="C6B-Wo-jWm" secondAttribute="trailing" id="6Rr-L0-eoR"/>
|
|
176
|
+
<constraint firstItem="tch-sa-Area" firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="Q4X-EY-aSL" secondAttribute="bottom" constant="8" id="tch-btm-Fit"/>
|
|
161
177
|
</constraints>
|
|
162
178
|
</view>
|
|
163
179
|
<navigationItem key="navigationItem" id="fDl-EC-1lc"/>
|
|
@@ -237,7 +253,7 @@
|
|
|
237
253
|
<constraint firstAttribute="height" constant="21" id="VBZ-ac-GvI"/>
|
|
238
254
|
</constraints>
|
|
239
255
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
240
|
-
<color key="textColor"
|
|
256
|
+
<color key="textColor" systemColor="labelColor"/>
|
|
241
257
|
<nil key="highlightedColor"/>
|
|
242
258
|
</label>
|
|
243
259
|
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="Wim-fT-xNl">
|
|
@@ -282,7 +298,7 @@
|
|
|
282
298
|
<constraint firstAttribute="height" constant="21" id="664-Z3-V7W"/>
|
|
283
299
|
</constraints>
|
|
284
300
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
285
|
-
<color key="textColor"
|
|
301
|
+
<color key="textColor" systemColor="labelColor"/>
|
|
286
302
|
<nil key="highlightedColor"/>
|
|
287
303
|
</label>
|
|
288
304
|
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="hidden_invisible" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vt6-b1-U0h">
|
|
@@ -291,7 +307,7 @@
|
|
|
291
307
|
<constraint firstAttribute="height" constant="21" id="51j-sl-XYd"/>
|
|
292
308
|
</constraints>
|
|
293
309
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
294
|
-
<color key="textColor"
|
|
310
|
+
<color key="textColor" systemColor="labelColor"/>
|
|
295
311
|
<nil key="highlightedColor"/>
|
|
296
312
|
</label>
|
|
297
313
|
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="GsS-jO-scK">
|
|
@@ -319,7 +335,7 @@
|
|
|
319
335
|
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no"/>
|
|
320
336
|
</textField>
|
|
321
337
|
</subviews>
|
|
322
|
-
<color key="backgroundColor"
|
|
338
|
+
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
323
339
|
<constraints>
|
|
324
340
|
<constraint firstItem="GsS-jO-scK" firstAttribute="leading" secondItem="Ucg-Ag-VpP" secondAttribute="leadingMargin" constant="154" id="1RA-Fx-3Jh"/>
|
|
325
341
|
<constraint firstItem="SjL-dx-Zsi" firstAttribute="top" secondItem="U7D-NR-20N" secondAttribute="bottom" constant="8" id="3NW-Hc-tPr"/>
|
|
@@ -445,7 +461,7 @@
|
|
|
445
461
|
<constraint firstAttribute="height" constant="21" id="2qA-NT-ddc"/>
|
|
446
462
|
</constraints>
|
|
447
463
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
448
|
-
<color key="textColor"
|
|
464
|
+
<color key="textColor" systemColor="labelColor"/>
|
|
449
465
|
<nil key="highlightedColor"/>
|
|
450
466
|
</label>
|
|
451
467
|
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3Zk-wE-jwj">
|
|
@@ -466,7 +482,7 @@
|
|
|
466
482
|
<state key="normal" title="Create Alert (Force Touch)"/>
|
|
467
483
|
</button>
|
|
468
484
|
</subviews>
|
|
469
|
-
<color key="backgroundColor"
|
|
485
|
+
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
470
486
|
<constraints>
|
|
471
487
|
<constraint firstItem="3Zk-wE-jwj" firstAttribute="centerX" secondItem="JWE-cA-TW0" secondAttribute="centerX" id="83u-1W-xLt"/>
|
|
472
488
|
<constraint firstItem="D7g-22-s49" firstAttribute="centerX" secondItem="JWE-cA-TW0" secondAttribute="centerX" id="9nT-k0-9gf"/>
|
|
@@ -527,7 +543,7 @@
|
|
|
527
543
|
</connections>
|
|
528
544
|
</button>
|
|
529
545
|
</subviews>
|
|
530
|
-
<color key="backgroundColor"
|
|
546
|
+
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
531
547
|
<constraints>
|
|
532
548
|
<constraint firstItem="vYb-QB-vwU" firstAttribute="centerX" secondItem="55R-aH-x4M" secondAttribute="centerX" id="0MT-Eq-8dG"/>
|
|
533
549
|
<constraint firstItem="vYb-QB-vwU" firstAttribute="top" secondItem="yvD-8P-ibI" secondAttribute="bottom" constant="20" id="c3y-G3-HCj"/>
|
|
@@ -548,7 +564,7 @@
|
|
|
548
564
|
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="jo0-3M-nUd">
|
|
549
565
|
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
|
550
566
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
551
|
-
<color key="backgroundColor"
|
|
567
|
+
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
552
568
|
<prototypes>
|
|
553
569
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="Cell" textLabel="2mC-E2-VxB" style="IBUITableViewCellStyleDefault" id="wCs-18-PFf">
|
|
554
570
|
<rect key="frame" x="0.0" y="50" width="414" height="44"/>
|
|
@@ -561,7 +577,7 @@
|
|
|
561
577
|
<rect key="frame" x="20" y="0.0" width="374" height="44"/>
|
|
562
578
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
|
563
579
|
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
|
564
|
-
<color key="textColor"
|
|
580
|
+
<color key="textColor" systemColor="labelColor"/>
|
|
565
581
|
<nil key="highlightedColor"/>
|
|
566
582
|
</label>
|
|
567
583
|
</subviews>
|
|
@@ -603,7 +619,7 @@
|
|
|
603
619
|
</userDefinedRuntimeAttributes>
|
|
604
620
|
</scrollView>
|
|
605
621
|
</subviews>
|
|
606
|
-
<color key="backgroundColor"
|
|
622
|
+
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
607
623
|
<constraints>
|
|
608
624
|
<constraint firstItem="xEQ-MI-a2g" firstAttribute="top" secondItem="KLL-RT-L40" secondAttribute="top" id="Bep-no-nwg"/>
|
|
609
625
|
<constraint firstAttribute="trailing" secondItem="xEQ-MI-a2g" secondAttribute="trailing" id="akP-zz-jsv"/>
|
|
@@ -624,6 +640,9 @@
|
|
|
624
640
|
</scene>
|
|
625
641
|
</scenes>
|
|
626
642
|
<resources>
|
|
643
|
+
<systemColor name="labelColor">
|
|
644
|
+
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
645
|
+
</systemColor>
|
|
627
646
|
<systemColor name="systemBackgroundColor">
|
|
628
647
|
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
629
648
|
</systemColor>
|
|
@@ -21,14 +21,10 @@
|
|
|
21
21
|
|
|
22
22
|
@implementation FBConfigurationTests
|
|
23
23
|
|
|
24
|
-
- (void)
|
|
24
|
+
- (void)testReduceMotion
|
|
25
25
|
{
|
|
26
|
-
[super setUp];
|
|
27
26
|
[self launchApplication];
|
|
28
|
-
}
|
|
29
27
|
|
|
30
|
-
- (void)testReduceMotion
|
|
31
|
-
{
|
|
32
28
|
BOOL defaultReduceMotionEnabled = FBConfiguration.sharedInstance.reduceMotionEnabled;
|
|
33
29
|
|
|
34
30
|
FBConfiguration.sharedInstance.reduceMotionEnabled = YES;
|
|
@@ -44,6 +40,9 @@
|
|
|
44
40
|
XCTSkip(@"Deliberately freezes the app for several seconds, too slow/flaky for CI");
|
|
45
41
|
}
|
|
46
42
|
|
|
43
|
+
// Launch only after the CI skip so a skipped test cannot time out in app startup.
|
|
44
|
+
[self launchApplication];
|
|
45
|
+
|
|
47
46
|
NSTimeInterval previousDeadline = FBConfiguration.sharedInstance.accessibilityDeadline;
|
|
48
47
|
// Also bounds any snapshot-based wait -tap itself may perform once the app is stuck.
|
|
49
48
|
FBConfiguration.sharedInstance.accessibilityDeadline = 3.0;
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
#import "FBTestMacros.h"
|
|
14
14
|
#import "FBXCodeCompatibility.h"
|
|
15
15
|
#import "XCUIElement+FBIsVisible.h"
|
|
16
|
+
#import "XCUIElement+FBUtilities.h"
|
|
16
17
|
|
|
17
18
|
@interface FBElementVisibilityTests : FBIntegrationTestCase
|
|
18
19
|
@end
|
|
@@ -26,14 +27,15 @@
|
|
|
26
27
|
}
|
|
27
28
|
[self launchApplication];
|
|
28
29
|
[self goToSpringBoardFirstPage];
|
|
30
|
+
[self.springboard fb_waitUntilStable];
|
|
29
31
|
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
// Calendar can match both its app icon and a widget on iOS 15+.
|
|
33
|
+
FBAssertWaitTillBecomesTrue(self.springboard.icons[@"Calendar"].firstMatch.fb_isVisible);
|
|
34
|
+
// Safari is in the dock; Reminders is not reliably visible on the first page
|
|
35
|
+
// of CI simulators. Wait for the Home transition before checking visibility.
|
|
36
|
+
FBAssertWaitTillBecomesTrue(self.springboard.icons[@"Safari"].firstMatch.fb_isVisible);
|
|
35
37
|
|
|
36
|
-
// Check
|
|
38
|
+
// Check the fixture icon on another page.
|
|
37
39
|
XCTAssertFalse(self.springboard.icons[@"IntegrationApp"].firstMatch.fb_isVisible);
|
|
38
40
|
}
|
|
39
41
|
|
|
@@ -0,0 +1,78 @@
|
|
|
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.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#import "FBIntegrationTestCase.h"
|
|
10
|
+
#import "FBTestMacros.h"
|
|
11
|
+
#import "XCUIDevice+FBRotation.h"
|
|
12
|
+
#import "XCUIElement+FBUtilities.h"
|
|
13
|
+
|
|
14
|
+
@interface FBIntegrationAppTests : FBIntegrationTestCase
|
|
15
|
+
@end
|
|
16
|
+
|
|
17
|
+
@implementation FBIntegrationAppTests
|
|
18
|
+
|
|
19
|
+
- (void)setUp
|
|
20
|
+
{
|
|
21
|
+
[super setUp];
|
|
22
|
+
[self resetOrientation];
|
|
23
|
+
[self launchApplication];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
- (void)tearDown
|
|
27
|
+
{
|
|
28
|
+
[self resetOrientation];
|
|
29
|
+
[super tearDown];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
- (void)rotateTo:(UIDeviceOrientation)orientation
|
|
33
|
+
{
|
|
34
|
+
XCTAssertTrue([[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:orientation]);
|
|
35
|
+
[self.testedApplication fb_waitUntilStable];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
- (void)testTouchControlsRemainOnScreenAfterRotation
|
|
39
|
+
{
|
|
40
|
+
[self goToTouchPage];
|
|
41
|
+
XCUIElement *canvas = [self.testedApplication descendantsMatchingType:XCUIElementTypeAny][@"touchableView"];
|
|
42
|
+
XCUIElement *taps = self.testedApplication.staticTexts[FBTapsCountLabelIdentifier];
|
|
43
|
+
XCUIElement *touches = self.testedApplication.staticTexts[FBTouchesCountLabelIdentifier];
|
|
44
|
+
NSArray<NSNumber *> *orientations = @[@(UIDeviceOrientationLandscapeLeft),
|
|
45
|
+
@(UIDeviceOrientationLandscapeRight),
|
|
46
|
+
@(UIDeviceOrientationPortrait)];
|
|
47
|
+
NSUInteger count = 0;
|
|
48
|
+
for (NSNumber *orientation in orientations) {
|
|
49
|
+
[self rotateTo:orientation.integerValue];
|
|
50
|
+
CGRect screen = self.testedApplication.frame;
|
|
51
|
+
XCTAssertTrue(CGRectContainsRect(screen, canvas.frame));
|
|
52
|
+
XCTAssertTrue(CGRectContainsRect(screen, taps.frame));
|
|
53
|
+
XCTAssertTrue(CGRectContainsRect(screen, touches.frame));
|
|
54
|
+
XCTAssertGreaterThan(CGRectGetHeight(canvas.frame), 0);
|
|
55
|
+
[canvas tap];
|
|
56
|
+
NSString *expectedTaps = [NSString stringWithFormat:@"%lu", (unsigned long)++count];
|
|
57
|
+
FBAssertWaitTillBecomesTrue([taps.label isEqualToString:expectedTaps]);
|
|
58
|
+
XCTAssertEqualObjects(touches.label, @"0");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
- (void)testScrollRowsResizeWhenRotatingInBothDirections
|
|
63
|
+
{
|
|
64
|
+
[self rotateTo:UIDeviceOrientationLandscapeLeft];
|
|
65
|
+
[self goToScrollPageWithCells:NO];
|
|
66
|
+
XCUIElement *scroll = self.testedApplication.scrollViews[@"scrollView"];
|
|
67
|
+
XCUIElement *row = scroll.staticTexts[@"3"];
|
|
68
|
+
NSArray<NSNumber *> *orientations = @[@(UIDeviceOrientationPortrait),
|
|
69
|
+
@(UIDeviceOrientationLandscapeRight)];
|
|
70
|
+
for (NSNumber *orientation in orientations) {
|
|
71
|
+
[self rotateTo:orientation.integerValue];
|
|
72
|
+
XCTAssertEqualWithAccuracy(CGRectGetWidth(row.frame), CGRectGetWidth(scroll.frame), 1);
|
|
73
|
+
XCTAssertEqualWithAccuracy(CGRectGetMidX(row.frame), CGRectGetMidX(scroll.frame), 1);
|
|
74
|
+
XCTAssertTrue(row.hittable);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@end
|
|
@@ -0,0 +1,121 @@
|
|
|
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.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#import <XCTest/XCTest.h>
|
|
10
|
+
|
|
11
|
+
#import "../IntegrationApp/Classes/TouchableView.h"
|
|
12
|
+
|
|
13
|
+
// Only the location and identity are needed to replay UIKit's touch callbacks.
|
|
14
|
+
@interface FBFixtureTouchDouble : NSObject
|
|
15
|
+
@end
|
|
16
|
+
|
|
17
|
+
@implementation FBFixtureTouchDouble
|
|
18
|
+
- (CGPoint)locationInView:(UIView *)view
|
|
19
|
+
{
|
|
20
|
+
return CGPointMake(50, 50);
|
|
21
|
+
}
|
|
22
|
+
@end
|
|
23
|
+
|
|
24
|
+
@interface FBTouchableViewTests : XCTestCase <TouchableViewDelegate>
|
|
25
|
+
@property (nonatomic, strong) TouchableView *touchable;
|
|
26
|
+
@property (nonatomic) int reportedTouches;
|
|
27
|
+
@property (nonatomic) int reportedTaps;
|
|
28
|
+
@end
|
|
29
|
+
|
|
30
|
+
@implementation FBTouchableViewTests
|
|
31
|
+
|
|
32
|
+
- (void)setUp
|
|
33
|
+
{
|
|
34
|
+
[super setUp];
|
|
35
|
+
self.reportedTouches = 0;
|
|
36
|
+
self.reportedTaps = 0;
|
|
37
|
+
self.touchable = [[TouchableView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
|
|
38
|
+
self.touchable.delegate = self;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
- (void)tearDown
|
|
42
|
+
{
|
|
43
|
+
self.touchable.delegate = nil;
|
|
44
|
+
self.touchable = nil;
|
|
45
|
+
[super tearDown];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
- (void)shouldHandleTouchesNumber:(int)touchesCount
|
|
49
|
+
{
|
|
50
|
+
self.reportedTouches = touchesCount;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
- (void)shouldHandleTapsNumber:(int)numberOfTaps
|
|
54
|
+
{
|
|
55
|
+
self.reportedTaps = numberOfTaps;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
- (UITouch *)newTouch
|
|
59
|
+
{
|
|
60
|
+
return (UITouch *)[FBFixtureTouchDouble new];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
- (void)testStaggeredTouchesTrackActiveFingers
|
|
64
|
+
{
|
|
65
|
+
NSSet *first = [NSSet setWithObject:[self newTouch]];
|
|
66
|
+
NSSet *second = [NSSet setWithObject:[self newTouch]];
|
|
67
|
+
[self.touchable touchesBegan:first withEvent:nil];
|
|
68
|
+
XCTAssertEqual(self.reportedTouches, 1);
|
|
69
|
+
[self.touchable touchesBegan:second withEvent:nil];
|
|
70
|
+
XCTAssertEqual(self.reportedTouches, 2);
|
|
71
|
+
XCTAssertEqual(self.reportedTaps, 0);
|
|
72
|
+
|
|
73
|
+
[self.touchable touchesEnded:first withEvent:nil];
|
|
74
|
+
XCTAssertEqual(self.reportedTouches, 1);
|
|
75
|
+
XCTAssertEqual(self.reportedTaps, 1);
|
|
76
|
+
[self.touchable touchesEnded:second withEvent:nil];
|
|
77
|
+
XCTAssertEqual(self.reportedTouches, 0);
|
|
78
|
+
XCTAssertEqual(self.reportedTaps, 2);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
- (void)testSimultaneousContactsCountIndependentlyOfCallbackBatching
|
|
82
|
+
{
|
|
83
|
+
NSSet *touches = [NSSet setWithObjects:[self newTouch], [self newTouch], nil];
|
|
84
|
+
[self.touchable touchesBegan:touches withEvent:nil];
|
|
85
|
+
XCTAssertEqual(self.reportedTouches, 2);
|
|
86
|
+
[self.touchable touchesEnded:touches withEvent:nil];
|
|
87
|
+
XCTAssertEqual(self.reportedTouches, 0);
|
|
88
|
+
XCTAssertEqual(self.reportedTaps, 2);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
- (void)testCancelledContactsDoNotCarryOverIntoNextTap
|
|
92
|
+
{
|
|
93
|
+
NSSet *first = [NSSet setWithObject:[self newTouch]];
|
|
94
|
+
NSSet *second = [NSSet setWithObject:[self newTouch]];
|
|
95
|
+
[self.touchable touchesBegan:first withEvent:nil];
|
|
96
|
+
[self.touchable touchesBegan:second withEvent:nil];
|
|
97
|
+
[self.touchable touchesCancelled:[first setByAddingObjectsFromSet:second] withEvent:nil];
|
|
98
|
+
XCTAssertEqual(self.reportedTouches, 0);
|
|
99
|
+
XCTAssertEqual(self.reportedTaps, 0);
|
|
100
|
+
|
|
101
|
+
NSSet *next = [NSSet setWithObject:[self newTouch]];
|
|
102
|
+
[self.touchable touchesBegan:next withEvent:nil];
|
|
103
|
+
[self.touchable touchesEnded:next withEvent:nil];
|
|
104
|
+
XCTAssertEqual(self.reportedTouches, 0);
|
|
105
|
+
XCTAssertEqual(self.reportedTaps, 1);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
- (void)testCancellingOneFingerPreservesTheOtherContact
|
|
109
|
+
{
|
|
110
|
+
NSSet *first = [NSSet setWithObject:[self newTouch]];
|
|
111
|
+
NSSet *second = [NSSet setWithObject:[self newTouch]];
|
|
112
|
+
[self.touchable touchesBegan:[first setByAddingObjectsFromSet:second] withEvent:nil];
|
|
113
|
+
[self.touchable touchesCancelled:first withEvent:nil];
|
|
114
|
+
XCTAssertEqual(self.reportedTouches, 1);
|
|
115
|
+
XCTAssertEqual(self.reportedTaps, 0);
|
|
116
|
+
[self.touchable touchesEnded:second withEvent:nil];
|
|
117
|
+
XCTAssertEqual(self.reportedTouches, 0);
|
|
118
|
+
XCTAssertEqual(self.reportedTaps, 1);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@end
|