appium-webdriveragent 16.1.2 → 16.1.4

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/WebDriverAgent.xcodeproj/project.pbxproj +297 -0
  3. package/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/IntegrationApp_tvOS.xcscheme +78 -0
  4. package/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/IntegrationTests_tvOS.xcscheme +86 -0
  5. package/WebDriverAgentLib/Categories/XCUIApplication+FBAlert.h +20 -8
  6. package/WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m +116 -60
  7. package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h +15 -0
  8. package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +16 -0
  9. package/WebDriverAgentLib/Categories/XCUIElement+FBTVFocuse.m +4 -4
  10. package/WebDriverAgentLib/Commands/FBAlertViewCommands.m +10 -36
  11. package/WebDriverAgentLib/Commands/FBElementCommands.m +3 -3
  12. package/WebDriverAgentLib/FBAlert.h +43 -30
  13. package/WebDriverAgentLib/FBAlert.m +257 -91
  14. package/WebDriverAgentLib/Info.plist +2 -2
  15. package/WebDriverAgentLib/Routing/FBExceptionHandler.m +8 -1
  16. package/WebDriverAgentLib/Routing/FBExceptions.h +9 -0
  17. package/WebDriverAgentLib/Routing/FBExceptions.m +3 -0
  18. package/WebDriverAgentLib/Routing/FBSession.m +11 -13
  19. package/WebDriverAgentLib/Utilities/FBAlertsMonitor.m +11 -9
  20. package/WebDriverAgentLib/Utilities/FBPasteboard.m +8 -4
  21. package/WebDriverAgentLib/Utilities/FBTVNavigationTracker-Private.h +10 -0
  22. package/WebDriverAgentLib/Utilities/FBTVNavigationTracker.h +29 -4
  23. package/WebDriverAgentLib/Utilities/FBTVNavigationTracker.m +62 -27
  24. package/WebDriverAgentTests/IntegrationApp_tvOS/AppDelegate.h +13 -0
  25. package/WebDriverAgentTests/IntegrationApp_tvOS/AppDelegate.m +26 -0
  26. package/WebDriverAgentTests/IntegrationApp_tvOS/Info.plist +41 -0
  27. package/WebDriverAgentTests/IntegrationApp_tvOS/SceneDelegate.h +15 -0
  28. package/WebDriverAgentTests/IntegrationApp_tvOS/SceneDelegate.m +22 -0
  29. package/WebDriverAgentTests/IntegrationApp_tvOS/ViewController.h +13 -0
  30. package/WebDriverAgentTests/IntegrationApp_tvOS/ViewController.m +79 -0
  31. package/WebDriverAgentTests/IntegrationApp_tvOS/main.m +17 -0
  32. package/WebDriverAgentTests/IntegrationTests/FBAlertTests.m +32 -51
  33. package/WebDriverAgentTests/IntegrationTests/FBIntegrationTestCase.m +9 -1
  34. package/WebDriverAgentTests/IntegrationTests/FBSafariAlertTests.m +1 -1
  35. package/WebDriverAgentTests/IntegrationTests_tvOS/FBTVFocusIntegrationTests.m +84 -0
  36. package/WebDriverAgentTests/IntegrationTests_tvOS/Info.plist +24 -0
  37. package/WebDriverAgentTests/UnitTests_tvOS/Doubles/FBXCAccessibilityElementDouble.h +27 -0
  38. package/WebDriverAgentTests/UnitTests_tvOS/Doubles/FBXCAccessibilityElementDouble.m +23 -0
  39. package/WebDriverAgentTests/UnitTests_tvOS/Doubles/FBXCElementSnapshotDouble.h +43 -0
  40. package/WebDriverAgentTests/UnitTests_tvOS/Doubles/FBXCElementSnapshotDouble.m +24 -0
  41. package/WebDriverAgentTests/UnitTests_tvOS/FBTVNavigationTrackerTests.m +48 -0
  42. package/package.json +1 -1
@@ -69,60 +69,54 @@
69
69
 
70
70
  - (void)testAlertPresence
71
71
  {
72
- FBAlert *alert = [FBAlert alertWithApplication:self.testedApplication];
73
- XCTAssertFalse(alert.isPresent);
72
+ XCTAssertFalse([FBAlert alertWithApplication:self.testedApplication].isPresent);
74
73
  [self showApplicationAlert];
75
- XCTAssertTrue(alert.isPresent);
74
+ XCTAssertTrue([FBAlert alertWithApplication:self.testedApplication].isPresent);
76
75
  }
77
76
 
78
77
  - (void)testAlertText
79
78
  {
80
- FBAlert *alert = [FBAlert alertWithApplication:self.testedApplication];
81
- XCTAssertNil(alert.text);
79
+ XCTAssertNil([FBAlert alertWithApplication:self.testedApplication].text);
82
80
  [self showApplicationAlert];
83
- XCTAssertTrue([alert.text containsString:@"Magic"]);
84
- XCTAssertTrue([alert.text containsString:@"Should read"]);
81
+ NSString *text = [FBAlert alertWithApplication:self.testedApplication].text;
82
+ XCTAssertTrue([text containsString:@"Magic"]);
83
+ XCTAssertTrue([text containsString:@"Should read"]);
85
84
  }
86
85
 
87
86
  - (void)testAlertLabels
88
87
  {
89
- FBAlert* alert = [FBAlert alertWithApplication:self.testedApplication];
90
- XCTAssertNil(alert.buttonLabels);
88
+ XCTAssertNil([FBAlert alertWithApplication:self.testedApplication].buttonLabels);
91
89
  [self showApplicationAlert];
92
- XCTAssertNotNil(alert.buttonLabels);
93
- XCTAssertEqual(1, alert.buttonLabels.count);
94
- XCTAssertEqualObjects(@"Will do", alert.buttonLabels[0]);
90
+ NSArray *labels = [FBAlert alertWithApplication:self.testedApplication].buttonLabels;
91
+ XCTAssertNotNil(labels);
92
+ XCTAssertEqual(1, labels.count);
93
+ XCTAssertEqualObjects(@"Will do", labels[0]);
95
94
  }
96
95
 
97
96
  - (void)testClickAlertButton
98
97
  {
99
- FBAlert* alert = [FBAlert alertWithApplication:self.testedApplication];
100
- XCTAssertFalse([alert clickAlertButton:@"Invalid" error:nil]);
98
+ XCTAssertThrows([[FBAlert alertWithApplication:self.testedApplication] clickAlertButton:@"Invalid"]);
101
99
  [self showApplicationAlert];
102
- XCTAssertFalse([alert clickAlertButton:@"Invalid" error:nil]);
103
- FBAssertWaitTillBecomesTrue(alert.isPresent);
104
- XCTAssertTrue([alert clickAlertButton:@"Will do" error:nil]);
105
- FBAssertWaitTillBecomesTrue(!alert.isPresent);
100
+ XCTAssertThrows([[FBAlert alertWithApplication:self.testedApplication] clickAlertButton:@"Invalid"]);
101
+ FBAssertWaitTillBecomesTrue([FBAlert alertWithApplication:self.testedApplication].isPresent);
102
+ XCTAssertNoThrow([[FBAlert alertWithApplication:self.testedApplication] clickAlertButton:@"Will do"]);
103
+ FBAssertWaitTillBecomesTrue(![FBAlert alertWithApplication:self.testedApplication].isPresent);
106
104
  }
107
105
 
108
106
  - (void)testAcceptingAlert
109
107
  {
110
- NSError *error;
111
108
  [self showApplicationAlert];
112
- XCTAssertTrue([[FBAlert alertWithApplication:self.testedApplication] acceptWithError:&error]);
109
+ XCTAssertNoThrow([[FBAlert alertWithApplication:self.testedApplication] accept]);
113
110
  FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count == 0);
114
- XCTAssertNil(error);
115
111
  }
116
112
 
117
113
  - (void)testAcceptingAlertWithCustomLocator
118
114
  {
119
- NSError *error;
120
115
  [self showApplicationAlert];
121
116
  [FBConfiguration setAcceptAlertButtonSelector:@"**/XCUIElementTypeButton[-1]"];
122
117
  @try {
123
- XCTAssertTrue([[FBAlert alertWithApplication:self.testedApplication] acceptWithError:&error]);
118
+ XCTAssertNoThrow([[FBAlert alertWithApplication:self.testedApplication] accept]);
124
119
  FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count == 0);
125
- XCTAssertNil(error);
126
120
  } @finally {
127
121
  [FBConfiguration setAcceptAlertButtonSelector:@""];
128
122
  }
@@ -130,65 +124,52 @@
130
124
 
131
125
  - (void)testDismissingAlert
132
126
  {
133
- NSError *error;
134
127
  [self showApplicationAlert];
135
- XCTAssertTrue([[FBAlert alertWithApplication:self.testedApplication] dismissWithError:&error]);
128
+ XCTAssertNoThrow([[FBAlert alertWithApplication:self.testedApplication] dismiss]);
136
129
  FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count == 0);
137
- XCTAssertNil(error);
138
130
  }
139
131
 
140
132
  - (void)testDismissingAlertWithCustomLocator
141
133
  {
142
- NSError *error;
143
134
  [self showApplicationAlert];
144
135
  [FBConfiguration setDismissAlertButtonSelector:@"**/XCUIElementTypeButton[-1]"];
145
136
  @try {
146
- XCTAssertTrue([[FBAlert alertWithApplication:self.testedApplication] dismissWithError:&error]);
137
+ XCTAssertNoThrow([[FBAlert alertWithApplication:self.testedApplication] dismiss]);
147
138
  FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count == 0);
148
- XCTAssertNil(error);
149
139
  } @finally {
150
140
  [FBConfiguration setDismissAlertButtonSelector:@""];
151
141
  }
152
142
  }
153
143
 
154
- - (void)testAlertElement
155
- {
156
- [self showApplicationAlert];
157
- XCUIElement *alertElement = [FBAlert alertWithApplication:self.testedApplication].alertElement;
158
- XCTAssertTrue(alertElement.exists);
159
- XCTAssertTrue(alertElement.elementType == XCUIElementTypeAlert);
160
- }
161
-
162
144
  - (void)testNotificationAlert
163
145
  {
164
- FBAlert *alert = [FBAlert alertWithApplication:self.testedApplication];
165
- XCTAssertNil(alert.text);
146
+ XCTAssertNil([FBAlert alertWithApplication:self.testedApplication].text);
166
147
  [self.testedApplication.buttons[@"Create Notification Alert"] tap];
167
- FBAssertWaitTillBecomesTrue(alert.isPresent);
148
+ FBAssertWaitTillBecomesTrue([FBAlert alertWithApplication:self.testedApplication].isPresent);
168
149
 
169
- XCTAssertTrue([alert.text containsString:@"Would Like to Send You Notifications"]);
170
- XCTAssertTrue([alert.text containsString:@"Notifications may include"]);
150
+ NSString *text = [FBAlert alertWithApplication:self.testedApplication].text;
151
+ XCTAssertTrue([text containsString:@"Would Like to Send You Notifications"]);
152
+ XCTAssertTrue([text containsString:@"Notifications may include"]);
171
153
  }
172
154
 
173
155
  - (void)testCameraRollAlert
174
156
  {
175
- FBAlert *alert = [FBAlert alertWithApplication:self.testedApplication];
176
- XCTAssertNil(alert.text);
157
+ XCTAssertNil([FBAlert alertWithApplication:self.testedApplication].text);
177
158
 
178
159
  [self.testedApplication.buttons[@"Create Camera Roll Alert"] tap];
179
- FBAssertWaitTillBecomesTrue(alert.isPresent);
160
+ FBAssertWaitTillBecomesTrue([FBAlert alertWithApplication:self.testedApplication].isPresent);
180
161
  }
181
162
 
182
163
  - (void)testGPSAccessAlert
183
164
  {
184
- FBAlert *alert = [FBAlert alertWithApplication:self.testedApplication];
185
- XCTAssertNil(alert.text);
165
+ XCTAssertNil([FBAlert alertWithApplication:self.testedApplication].text);
186
166
 
187
167
  [self.testedApplication.buttons[@"Create GPS access Alert"] tap];
188
- FBAssertWaitTillBecomesTrue(alert.isPresent);
168
+ FBAssertWaitTillBecomesTrue([FBAlert alertWithApplication:self.testedApplication].isPresent);
189
169
 
190
- XCTAssertTrue([alert.text containsString:@"location"]);
191
- XCTAssertTrue([alert.text containsString:@"Yo Yo"]);
170
+ NSString *text = [FBAlert alertWithApplication:self.testedApplication].text;
171
+ XCTAssertTrue([text containsString:@"location"]);
172
+ XCTAssertTrue([text containsString:@"Yo Yo"]);
192
173
  }
193
174
 
194
175
  @end
@@ -10,6 +10,7 @@
10
10
 
11
11
  #import "FBAlert.h"
12
12
  #import "FBTestMacros.h"
13
+ #import "FBExceptions.h"
13
14
  #import "FBIntegrationTestCase.h"
14
15
  #import "FBConfiguration.h"
15
16
  #import "FBMacros.h"
@@ -151,7 +152,14 @@ NSArray<NSString *> *const FBMainViewButtonLabels = @[
151
152
  - (void)clearAlert
152
153
  {
153
154
  [self.testedApplication fb_waitUntilStable];
154
- [[FBAlert alertWithApplication:self.testedApplication] dismissWithError:nil];
155
+ @try {
156
+ [[FBAlert alertWithApplication:self.testedApplication] dismiss];
157
+ } @catch (NSException *e) {
158
+ if (![e.name isEqualToString:FBAlertNotPresentException]) {
159
+ @throw e;
160
+ }
161
+ // No alert is present, nothing to clear
162
+ }
155
163
  [self.testedApplication fb_waitUntilStable];
156
164
  FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count == 0);
157
165
  }
@@ -67,7 +67,7 @@
67
67
  XCTAssertEqualObjects(buttonLabels.firstObject, @"Close");
68
68
  XCTAssertNotNil([self.safariApp fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@label='Close']"
69
69
  shouldReturnAfterFirstMatch:YES].firstObject);
70
- XCTAssertTrue([alert acceptWithError:nil]);
70
+ XCTAssertNoThrow([alert accept]);
71
71
  }
72
72
 
73
73
  @end
@@ -0,0 +1,84 @@
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
+ #if TARGET_OS_TV
12
+
13
+ // `XCUIElement+FBTVFocuse` is a project-internal category (not exposed as a
14
+ // Public framework header), so its two entry points are forward-declared
15
+ // here rather than imported. The real implementation - the one this suite
16
+ // exercises end to end against a live tvOS Simulator - is still the one
17
+ // linked in from WebDriverAgentLib_tvOS.framework.
18
+ @interface XCUIElement (FBTVFocuseForTesting)
19
+ - (BOOL)fb_setFocusWithError:(NSError **)error;
20
+ - (BOOL)fb_selectWithError:(NSError **)error;
21
+ @end
22
+
23
+ @interface FBTVFocusIntegrationTests : XCTestCase
24
+ @property (nonatomic, strong) XCUIApplication *app;
25
+ @end
26
+
27
+ @implementation FBTVFocusIntegrationTests
28
+
29
+ - (void)setUp
30
+ {
31
+ [super setUp];
32
+ self.continueAfterFailure = NO;
33
+ self.app = [XCUIApplication new];
34
+ [self.app launch];
35
+ XCTAssertTrue([self.app.buttons[@"cell_0_0"] waitForExistenceWithTimeout:15]);
36
+ }
37
+
38
+ - (void)testSetFocusMovesFocusToADistantElement
39
+ {
40
+ XCUIElement *target = self.app.buttons[@"cell_2_2"];
41
+ XCTAssertTrue(target.exists);
42
+ XCTAssertFalse(target.hasFocus);
43
+
44
+ NSError *error;
45
+ BOOL result = [target fb_setFocusWithError:&error];
46
+
47
+ XCTAssertTrue(result);
48
+ XCTAssertNil(error);
49
+ XCTAssertTrue(target.hasFocus);
50
+ }
51
+
52
+ - (void)testSelectMovesFocusAndTriggersTheElementsAction
53
+ {
54
+ XCUIElement *target = self.app.buttons[@"cell_1_2"];
55
+ XCUIElement *statusLabel = self.app.staticTexts[@"lastSelectedLabel"];
56
+
57
+ NSError *error;
58
+ BOOL result = [target fb_selectWithError:&error];
59
+
60
+ XCTAssertTrue(result);
61
+ XCTAssertNil(error);
62
+ XCTAssertTrue(target.hasFocus);
63
+
64
+ NSPredicate *labelUpdated = [NSPredicate predicateWithFormat:@"label == %@", @"cell_1_2"];
65
+ XCTNSPredicateExpectation *expectation = [[XCTNSPredicateExpectation alloc] initWithPredicate:labelUpdated object:statusLabel];
66
+ [self waitForExpectations:@[expectation] timeout:5];
67
+ }
68
+
69
+ - (void)testSetFocusOnADisabledElementFails
70
+ {
71
+ XCUIElement *disabled = self.app.buttons[@"disabledButton"];
72
+ XCTAssertTrue(disabled.exists);
73
+
74
+ NSError *error;
75
+ BOOL result = [disabled fb_setFocusWithError:&error];
76
+
77
+ XCTAssertFalse(result);
78
+ XCTAssertNotNil(error);
79
+ XCTAssertFalse(disabled.hasFocus);
80
+ }
81
+
82
+ @end
83
+
84
+ #endif
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>CFBundleDevelopmentRegion</key>
6
+ <string>en</string>
7
+ <key>CFBundleExecutable</key>
8
+ <string>$(EXECUTABLE_NAME)</string>
9
+ <key>CFBundleIdentifier</key>
10
+ <string>com.facebook.wda.integrationTests.tvOS</string>
11
+ <key>CFBundleInfoDictionaryVersion</key>
12
+ <string>6.0</string>
13
+ <key>CFBundleName</key>
14
+ <string>$(PRODUCT_NAME)</string>
15
+ <key>CFBundlePackageType</key>
16
+ <string>BNDL</string>
17
+ <key>CFBundleShortVersionString</key>
18
+ <string>1.0</string>
19
+ <key>CFBundleSignature</key>
20
+ <string>????</string>
21
+ <key>CFBundleVersion</key>
22
+ <string>1</string>
23
+ </dict>
24
+ </plist>
@@ -0,0 +1,27 @@
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 <Foundation/Foundation.h>
10
+
11
+ NS_ASSUME_NONNULL_BEGIN
12
+
13
+ /**
14
+ Minimal fake of the private `id<FBXCAccessibilityElement>` handle every
15
+ real snapshot carries, just enough for `FBElementUtils uidWithAccessibilityElement:`
16
+ to derive a stable, distinct `wdUID` per fake element id.
17
+ */
18
+ @interface FBXCAccessibilityElementDouble : NSObject
19
+
20
+ @property (nonatomic, readonly) id payload;
21
+ @property (nonatomic, readonly) int processIdentifier;
22
+
23
+ - (instancetype)initWithElementId:(unsigned long long)elementId;
24
+
25
+ @end
26
+
27
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,23 @@
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 "FBXCAccessibilityElementDouble.h"
10
+
11
+ @implementation FBXCAccessibilityElementDouble
12
+
13
+ - (instancetype)initWithElementId:(unsigned long long)elementId
14
+ {
15
+ self = [super init];
16
+ if (self) {
17
+ _payload = @{@"uid.elementID": @(elementId)};
18
+ _processIdentifier = 1;
19
+ }
20
+ return self;
21
+ }
22
+
23
+ @end
@@ -0,0 +1,43 @@
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 <Foundation/Foundation.h>
10
+
11
+ #import "FBXCAccessibilityElementDouble.h"
12
+
13
+ NS_ASSUME_NONNULL_BEGIN
14
+
15
+ /**
16
+ Fake `id<FBXCElementSnapshot>` leaf node. Deliberately does NOT declare
17
+ formal conformance to the (large, mostly-unrelated) `FBXCElementSnapshot`
18
+ protocol - it only implements the selectors
19
+ `FBTVNavigationTracker`'s `-directionTowardsTargetFromFocusedElementSnapshot:`
20
+ actually reads: `frame`, `hasFocus` and `accessibilityElement` (the latter
21
+ indirectly, via `FBXCElementSnapshotWrapper.wdUID`). Cast to
22
+ `id<FBXCElementSnapshot>` at the call site. Lets tests supply a fake focused
23
+ element snapshot without a live app/device.
24
+ */
25
+ @interface FBXCElementSnapshotDouble : NSObject
26
+
27
+ @property (nonatomic, assign) CGRect frame;
28
+ @property (nonatomic, assign) BOOL hasFocus;
29
+ @property (nonatomic, strong, nullable) FBXCAccessibilityElementDouble *accessibilityElement;
30
+
31
+ /**
32
+ @param elementId Fake AX element id, used to derive a distinct `wdUID`
33
+ @param frame The snapshot's frame
34
+ @param hasFocus Whether this node should report `hasFocus == YES`
35
+ @return A snapshot double
36
+ */
37
+ + (instancetype)snapshotWithElementId:(unsigned long long)elementId
38
+ frame:(CGRect)frame
39
+ hasFocus:(BOOL)hasFocus;
40
+
41
+ @end
42
+
43
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,24 @@
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 "FBXCElementSnapshotDouble.h"
10
+
11
+ @implementation FBXCElementSnapshotDouble
12
+
13
+ + (instancetype)snapshotWithElementId:(unsigned long long)elementId
14
+ frame:(CGRect)frame
15
+ hasFocus:(BOOL)hasFocus
16
+ {
17
+ FBXCElementSnapshotDouble *snapshot = [self new];
18
+ snapshot.accessibilityElement = [[FBXCAccessibilityElementDouble alloc] initWithElementId:elementId];
19
+ snapshot.frame = frame;
20
+ snapshot.hasFocus = hasFocus;
21
+ return snapshot;
22
+ }
23
+
24
+ @end
@@ -7,8 +7,10 @@
7
7
  */
8
8
 
9
9
  #import <XCTest/XCTest.h>
10
+ #import <WebDriverAgentLib/FBXCElementSnapshot.h>
10
11
 
11
12
  #import "XCUIElementDouble.h"
13
+ #import "FBXCElementSnapshotDouble.h"
12
14
  #import "FBTVNavigationTracker.h"
13
15
  #import "FBTVNavigationTracker-Private.h"
14
16
 
@@ -83,4 +85,50 @@
83
85
  XCTAssertEqual(FBTVDirectionNone, direction);
84
86
  }
85
87
 
88
+ #pragma mark - directionTowardsTargetFromFocusedElementSnapshot:
89
+
90
+ - (FBTVNavigationTracker *)trackerWithTargetFrame:(CGRect)targetFrame
91
+ {
92
+ XCUIElementDouble *targetElement = XCUIElementDouble.new;
93
+ targetElement.wdFrame = targetFrame;
94
+ return [FBTVNavigationTracker trackerWithTargetElement:(XCUIElement *)targetElement];
95
+ }
96
+
97
+ - (void)testDirectionTowardsTargetFromFocusedElementSnapshotShouldPointRight
98
+ {
99
+ // Target sits to the right of the currently focused element.
100
+ FBTVNavigationTracker *tracker = [self trackerWithTargetFrame:CGRectMake(100, 0, 0, 0)];
101
+ FBXCElementSnapshotDouble *focusedSnapshot = [FBXCElementSnapshotDouble snapshotWithElementId:1 frame:CGRectMake(0, 0, 0, 0) hasFocus:YES];
102
+
103
+ FBTVDirection direction = [tracker directionTowardsTargetFromFocusedElementSnapshot:(id<FBXCElementSnapshot>)focusedSnapshot];
104
+
105
+ XCTAssertEqual(FBTVDirectionRight, direction);
106
+ }
107
+
108
+ - (void)testDirectionTowardsTargetFromFocusedElementSnapshotShouldPointUp
109
+ {
110
+ // Target sits above the currently focused element.
111
+ FBTVNavigationTracker *tracker = [self trackerWithTargetFrame:CGRectMake(0, -100, 0, 0)];
112
+ FBXCElementSnapshotDouble *focusedSnapshot = [FBXCElementSnapshotDouble snapshotWithElementId:1 frame:CGRectMake(0, 0, 0, 0) hasFocus:YES];
113
+
114
+ FBTVDirection direction = [tracker directionTowardsTargetFromFocusedElementSnapshot:(id<FBXCElementSnapshot>)focusedSnapshot];
115
+
116
+ XCTAssertEqual(FBTVDirectionUp, direction);
117
+ }
118
+
119
+ - (void)testDirectionTowardsTargetFromFocusedElementSnapshotShouldNotSuggestTheSameDirectionTwiceInARow
120
+ {
121
+ // Same (unmoved) focused snapshot polled twice: the horizontal move gets
122
+ // suggested once, then withheld on the next call, per the "don't repeat a
123
+ // direction" bookkeeping in -directionWithItem:delta:positiveDirection:negativeDirection:.
124
+ FBTVNavigationTracker *tracker = [self trackerWithTargetFrame:CGRectMake(100, 0, 0, 0)];
125
+ FBXCElementSnapshotDouble *focusedSnapshot = [FBXCElementSnapshotDouble snapshotWithElementId:1 frame:CGRectMake(0, 0, 0, 0) hasFocus:YES];
126
+
127
+ FBTVDirection firstDirection = [tracker directionTowardsTargetFromFocusedElementSnapshot:(id<FBXCElementSnapshot>)focusedSnapshot];
128
+ XCTAssertEqual(FBTVDirectionRight, firstDirection);
129
+
130
+ FBTVDirection secondDirection = [tracker directionTowardsTargetFromFocusedElementSnapshot:(id<FBXCElementSnapshot>)focusedSnapshot];
131
+ XCTAssertEqual(FBTVDirectionNone, secondDirection);
132
+ }
133
+
86
134
  @end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-webdriveragent",
3
- "version": "16.1.2",
3
+ "version": "16.1.4",
4
4
  "description": "Package bundling WebDriverAgent",
5
5
  "keywords": [
6
6
  "Appium",