appium-webdriveragent 16.12.4 → 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 +6 -0
- package/WebDriverAgent.xcodeproj/project.pbxproj +12 -0
- package/WebDriverAgentLib/Info.plist +2 -2
- 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/Resources/Base.lproj/Main.storyboard +13 -10
- package/WebDriverAgentTests/IntegrationTests/FBElementVisibilityTests.m +8 -6
- package/WebDriverAgentTests/IntegrationTests/FBIntegrationAppTests.m +78 -0
- package/WebDriverAgentTests/UnitTests/FBTouchableViewTests.m +121 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
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
|
+
|
|
1
7
|
## [16.12.4](https://github.com/appium/WebDriverAgent/compare/v16.12.3...v16.12.4) (2026-09-06)
|
|
2
8
|
|
|
3
9
|
### Miscellaneous Chores
|
|
@@ -1270,6 +1270,10 @@
|
|
|
1270
1270
|
FEC3A97A4929115A192F947A /* XCUIDeviceEventAndStateInterface-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 003AAAB9CB5FB38E45E05F6F /* XCUIDeviceEventAndStateInterface-Protocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
1271
1271
|
FFA7672B731B57AB9283DD40 /* FBXCElementSnapshotWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 13DE7A53287CA1EC003243C6 /* FBXCElementSnapshotWrapper.h */; };
|
|
1272
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 */; };
|
|
1273
1277
|
/* End PBXBuildFile section */
|
|
1274
1278
|
|
|
1275
1279
|
/* Begin PBXContainerItemProxy section */
|
|
@@ -1962,6 +1966,8 @@
|
|
|
1962
1966
|
FCD1815F2BF21CA0936B04E1 /* XCTMessagingRole_SiriAutomation-Protocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "XCTMessagingRole_SiriAutomation-Protocol.h"; sourceTree = "<group>"; };
|
|
1963
1967
|
FDB15E393EA0850C004D26B2 /* XCTScreenCapturePolicy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = XCTScreenCapturePolicy.h; sourceTree = "<group>"; };
|
|
1964
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>"; };
|
|
1965
1971
|
/* End PBXFileReference section */
|
|
1966
1972
|
|
|
1967
1973
|
/* Begin PBXFrameworksBuildPhase section */
|
|
@@ -2632,6 +2638,7 @@
|
|
|
2632
2638
|
EE9B76541CF7987300275851 /* IntegrationTests */ = {
|
|
2633
2639
|
isa = PBXGroup;
|
|
2634
2640
|
children = (
|
|
2641
|
+
27B518E261C14E29B943AB9B /* FBIntegrationAppTests.m */,
|
|
2635
2642
|
EE9B76991CF799F400275851 /* FBAlertTests.m */,
|
|
2636
2643
|
719CD8FE2126C90200C7D0C2 /* FBAutoAlertsHandlerTests.m */,
|
|
2637
2644
|
EE26409C1D0EBA25009BE6B0 /* FBElementAttributeTests.m */,
|
|
@@ -2675,6 +2682,7 @@
|
|
|
2675
2682
|
EE9B76561CF7987300275851 /* UnitTests */ = {
|
|
2676
2683
|
isa = PBXGroup;
|
|
2677
2684
|
children = (
|
|
2685
|
+
1D04760558C64B8EB69380E0 /* FBTouchableViewTests.m */,
|
|
2678
2686
|
ADBC39951D07840300327304 /* Doubles */,
|
|
2679
2687
|
71A7EAFB1E229302001DA4F2 /* FBClassChainTests.m */,
|
|
2680
2688
|
EEE16E961D33A25500172525 /* FBConfigurationTests.m */,
|
|
@@ -4814,6 +4822,9 @@
|
|
|
4814
4822
|
isa = PBXSourcesBuildPhase;
|
|
4815
4823
|
buildActionMask = 2147483647;
|
|
4816
4824
|
files = (
|
|
4825
|
+
B6DE70BFF27148BDAC72F80C /* TouchSpotView.m in Sources */,
|
|
4826
|
+
81E462B8A75F497CBFC6FD8B /* TouchableView.m in Sources */,
|
|
4827
|
+
6C07E44E139D41D6BA092F39 /* FBTouchableViewTests.m in Sources */,
|
|
4817
4828
|
713352FD26CEF31D00523CBC /* FBLRUCacheTests.m in Sources */,
|
|
4818
4829
|
EE3F8CFE1D08AA17006F02CE /* FBRunLoopSpinnerTests.m in Sources */,
|
|
4819
4830
|
A09D847635CA4C155583B967 /* FBXCAXClientProxyTests.m in Sources */,
|
|
@@ -4869,6 +4880,7 @@
|
|
|
4869
4880
|
isa = PBXSourcesBuildPhase;
|
|
4870
4881
|
buildActionMask = 2147483647;
|
|
4871
4882
|
files = (
|
|
4883
|
+
C15E49E6B6924191BAAD9FDF /* FBIntegrationAppTests.m in Sources */,
|
|
4872
4884
|
EE26409D1D0EBA25009BE6B0 /* FBElementAttributeTests.m in Sources */,
|
|
4873
4885
|
7119E1EC1E891F8600D0B125 /* FBPickerWheelSelectTests.m in Sources */,
|
|
4874
4886
|
71ACF5B8242F2FDC00F0AAD4 /* FBSafariAlertTests.m in Sources */,
|
|
@@ -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>
|
|
@@ -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
|
|
@@ -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>
|
|
@@ -142,7 +143,7 @@
|
|
|
142
143
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
143
144
|
<accessibility key="accessibilityConfiguration" identifier="touchableView"/>
|
|
144
145
|
<constraints>
|
|
145
|
-
<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"/>
|
|
146
147
|
</constraints>
|
|
147
148
|
</view>
|
|
148
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">
|
|
@@ -160,17 +161,19 @@
|
|
|
160
161
|
<nil key="highlightedColor"/>
|
|
161
162
|
</label>
|
|
162
163
|
</subviews>
|
|
164
|
+
<viewLayoutGuide key="safeArea" id="tch-sa-Area"/>
|
|
163
165
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
164
166
|
<constraints>
|
|
165
|
-
<constraint firstItem="C6B-Wo-jWm" firstAttribute="top" secondItem="
|
|
166
|
-
<constraint firstAttribute="
|
|
167
|
-
<constraint firstAttribute="trailing" secondItem="
|
|
168
|
-
<constraint firstItem="IV8-Ak-Z8e" firstAttribute="
|
|
169
|
-
<constraint firstAttribute="
|
|
170
|
-
<constraint firstItem="
|
|
171
|
-
<constraint firstItem="Q4X-EY-aSL" firstAttribute="top" secondItem="IV8-Ak-Z8e" secondAttribute="bottom" constant="
|
|
172
|
-
<constraint firstItem="
|
|
173
|
-
<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"/>
|
|
174
177
|
</constraints>
|
|
175
178
|
</view>
|
|
176
179
|
<navigationItem key="navigationItem" id="fDl-EC-1lc"/>
|
|
@@ -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
|