appium-webdriveragent 16.1.3 → 16.1.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 +13 -0
- package/WebDriverAgent.xcodeproj/project.pbxproj +297 -0
- package/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/IntegrationApp_tvOS.xcscheme +78 -0
- package/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/IntegrationTests_tvOS.xcscheme +86 -0
- package/WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m +2 -2
- package/WebDriverAgentLib/Categories/XCUIElement+FBClassChain.m +1 -1
- package/WebDriverAgentLib/Categories/XCUIElement+FBTVFocuse.m +4 -4
- package/WebDriverAgentLib/Categories/XCUIElement+FBTyping.h +33 -0
- package/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m +23 -0
- package/WebDriverAgentLib/Commands/FBElementCommands.m +8 -3
- package/WebDriverAgentLib/FBAlert.m +10 -2
- package/WebDriverAgentLib/Info.plist +2 -2
- package/WebDriverAgentLib/Utilities/FBTVNavigationTracker-Private.h +10 -0
- package/WebDriverAgentLib/Utilities/FBTVNavigationTracker.h +29 -4
- package/WebDriverAgentLib/Utilities/FBTVNavigationTracker.m +62 -27
- package/WebDriverAgentTests/IntegrationApp_tvOS/AppDelegate.h +13 -0
- package/WebDriverAgentTests/IntegrationApp_tvOS/AppDelegate.m +26 -0
- package/WebDriverAgentTests/IntegrationApp_tvOS/Info.plist +41 -0
- package/WebDriverAgentTests/IntegrationApp_tvOS/SceneDelegate.h +15 -0
- package/WebDriverAgentTests/IntegrationApp_tvOS/SceneDelegate.m +22 -0
- package/WebDriverAgentTests/IntegrationApp_tvOS/ViewController.h +13 -0
- package/WebDriverAgentTests/IntegrationApp_tvOS/ViewController.m +79 -0
- package/WebDriverAgentTests/IntegrationApp_tvOS/main.m +17 -0
- package/WebDriverAgentTests/IntegrationTests_tvOS/FBTVFocusIntegrationTests.m +84 -0
- package/WebDriverAgentTests/IntegrationTests_tvOS/Info.plist +24 -0
- package/WebDriverAgentTests/UnitTests_tvOS/Doubles/FBXCAccessibilityElementDouble.h +27 -0
- package/WebDriverAgentTests/UnitTests_tvOS/Doubles/FBXCAccessibilityElementDouble.m +23 -0
- package/WebDriverAgentTests/UnitTests_tvOS/Doubles/FBXCElementSnapshotDouble.h +43 -0
- package/WebDriverAgentTests/UnitTests_tvOS/Doubles/FBXCElementSnapshotDouble.m +24 -0
- package/WebDriverAgentTests/UnitTests_tvOS/FBTVNavigationTrackerTests.m +48 -0
- package/package.json +1 -1
|
@@ -0,0 +1,79 @@
|
|
|
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 "ViewController.h"
|
|
10
|
+
|
|
11
|
+
static NSInteger const FBGridSize = 3;
|
|
12
|
+
static CGFloat const FBCellSide = 200;
|
|
13
|
+
static CGFloat const FBCellSpacing = 60;
|
|
14
|
+
|
|
15
|
+
@interface ViewController ()
|
|
16
|
+
@property (nonatomic, strong) UILabel *lastSelectedLabel;
|
|
17
|
+
@end
|
|
18
|
+
|
|
19
|
+
@implementation ViewController
|
|
20
|
+
|
|
21
|
+
- (void)viewDidLoad
|
|
22
|
+
{
|
|
23
|
+
[super viewDidLoad];
|
|
24
|
+
self.view.backgroundColor = UIColor.whiteColor;
|
|
25
|
+
|
|
26
|
+
UIStackView *rows = [UIStackView new];
|
|
27
|
+
rows.axis = UILayoutConstraintAxisVertical;
|
|
28
|
+
rows.spacing = FBCellSpacing;
|
|
29
|
+
rows.alignment = UIStackViewAlignmentCenter;
|
|
30
|
+
rows.translatesAutoresizingMaskIntoConstraints = NO;
|
|
31
|
+
[self.view addSubview:rows];
|
|
32
|
+
|
|
33
|
+
for (NSInteger row = 0; row < FBGridSize; row++) {
|
|
34
|
+
UIStackView *columns = [UIStackView new];
|
|
35
|
+
columns.axis = UILayoutConstraintAxisHorizontal;
|
|
36
|
+
columns.spacing = FBCellSpacing;
|
|
37
|
+
for (NSInteger column = 0; column < FBGridSize; column++) {
|
|
38
|
+
UIButton *cell = [self newCellWithIdentifier:[NSString stringWithFormat:@"cell_%ld_%ld", (long)row, (long)column]];
|
|
39
|
+
[columns addArrangedSubview:cell];
|
|
40
|
+
}
|
|
41
|
+
[rows addArrangedSubview:columns];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
UIButton *disabledButton = [self newCellWithIdentifier:@"disabledButton"];
|
|
45
|
+
disabledButton.enabled = NO;
|
|
46
|
+
[rows addArrangedSubview:disabledButton];
|
|
47
|
+
|
|
48
|
+
self.lastSelectedLabel = [UILabel new];
|
|
49
|
+
self.lastSelectedLabel.accessibilityIdentifier = @"lastSelectedLabel";
|
|
50
|
+
self.lastSelectedLabel.text = @"none";
|
|
51
|
+
self.lastSelectedLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
|
52
|
+
[self.view addSubview:self.lastSelectedLabel];
|
|
53
|
+
|
|
54
|
+
[NSLayoutConstraint activateConstraints:@[
|
|
55
|
+
[rows.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
|
|
56
|
+
[rows.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
|
|
57
|
+
[self.lastSelectedLabel.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
|
|
58
|
+
[self.lastSelectedLabel.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor constant:-FBCellSpacing],
|
|
59
|
+
]];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
- (UIButton *)newCellWithIdentifier:(NSString *)identifier
|
|
63
|
+
{
|
|
64
|
+
UIButton *cell = [UIButton buttonWithType:UIButtonTypeSystem];
|
|
65
|
+
cell.accessibilityIdentifier = identifier;
|
|
66
|
+
[cell setTitle:identifier forState:UIControlStateNormal];
|
|
67
|
+
cell.translatesAutoresizingMaskIntoConstraints = NO;
|
|
68
|
+
[cell.widthAnchor constraintEqualToConstant:FBCellSide].active = YES;
|
|
69
|
+
[cell.heightAnchor constraintEqualToConstant:FBCellSide].active = YES;
|
|
70
|
+
[cell addTarget:self action:@selector(didSelectCell:) forControlEvents:UIControlEventPrimaryActionTriggered];
|
|
71
|
+
return cell;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
- (void)didSelectCell:(UIButton *)cell
|
|
75
|
+
{
|
|
76
|
+
self.lastSelectedLabel.text = cell.accessibilityIdentifier;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@end
|
|
@@ -0,0 +1,17 @@
|
|
|
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 <UIKit/UIKit.h>
|
|
10
|
+
|
|
11
|
+
#import "AppDelegate.h"
|
|
12
|
+
|
|
13
|
+
int main(int argc, char * argv[]) {
|
|
14
|
+
@autoreleasepool {
|
|
15
|
+
return UIApplicationMain(argc, argv, nil, NSStringFromClass(AppDelegate.class));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -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
|