Skip to content

Commit

Permalink
Fix back button testID (#6357)
Browse files Browse the repository at this point in the history
`backButton.testID` option was broken. This PR fixes it.
  • Loading branch information
yogevbd authored Jul 5, 2020
1 parent be58276 commit 9676e9c
Show file tree
Hide file tree
Showing 13 changed files with 69 additions and 29 deletions.
10 changes: 8 additions & 2 deletions e2e/Buttons.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import Utils from './Utils';
import TestIDs from '../playground/src/testIDs';

const { elementById, elementByLabel } = Utils;
const {elementById, elementByLabel} = Utils;

describe('Buttons', () => {
beforeEach(async () => {
await device.launchApp({ newInstance: true });
await device.launchApp({newInstance: true});
await elementById(TestIDs.OPTIONS_TAB).tap();
await elementById(TestIDs.GOTO_BUTTONS_SCREEN).tap();
});
Expand Down Expand Up @@ -45,4 +45,10 @@ describe('Buttons', () => {
await elementById(TestIDs.CHANGE_BUTTON_PROPS).tap();
await expect(elementByLabel('Three')).toBeVisible();
});

it('pop using back button', async () => {
await elementById(TestIDs.PUSH_BTN).tap();
await elementById(TestIDs.BACK_BUTTON).tap();
await expect(elementByLabel('Buttons')).toBeVisible();
});
});
1 change: 1 addition & 0 deletions lib/ios/RNNStackPresenter.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ - (void)bindViewController:(UINavigationController *)boundViewController {

- (void)componentDidAppear {
[_topBarBackgroundReactView componentDidAppear];
[_topBarPresenter componentDidAppear];
}

- (void)componentDidDisappear {
Expand Down
22 changes: 16 additions & 6 deletions lib/ios/TopBarPresenter.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#import "UIImage+tint.h"
#import "RNNFontAttributesCreator.h"
#import "UIColor+RNNUtils.h"
#import "UIViewController+LayoutProtocol.h"
#import "UINavigationController+RNNOptions.h"

@implementation TopBarPresenter

Expand Down Expand Up @@ -112,27 +114,29 @@ - (void)setLargeTitleAttributes:(RNNLargeTitleOptions *)largeTitleOptions {
}
}

- (void)componentDidAppear {
NSString* backButtonTestID = [self.navigationController.topViewController.resolveOptionsWithDefault.topBar.backButton.testID getWithDefaultValue:nil];
[self.navigationController setBackButtonTestID:backButtonTestID];
}

- (void)setBackButtonOptions:(RNNBackButtonOptions *)backButtonOptions {
UIImage* icon = [backButtonOptions.icon getWithDefaultValue:nil];
UIColor* color = [backButtonOptions.color getWithDefaultValue:nil];
NSString* title = [backButtonOptions.title getWithDefaultValue:nil];
BOOL showTitle = [backButtonOptions.showTitle getWithDefaultValue:YES];
NSString* fontFamily = [backButtonOptions.fontFamily getWithDefaultValue:nil];
NSNumber* fontSize = [backButtonOptions.fontSize getWithDefaultValue:nil];
NSString* testID = [backButtonOptions.testID getWithDefaultValue:nil];

NSArray* stackChildren = self.navigationController.viewControllers;
UIViewController *lastViewControllerInStack = stackChildren.count > 1 ? stackChildren[stackChildren.count - 2] : self.navigationController.topViewController;
UIViewController *previousViewControllerInStack = self.previousViewControllerInStack;
UIBarButtonItem *backItem = [UIBarButtonItem new];
backItem.accessibilityIdentifier = testID;

icon = color
? [[icon withTintColor:color] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
: icon;
[self setBackIndicatorImage:icon withColor:color];

if (showTitle) {
backItem.title = title ? title : lastViewControllerInStack.navigationItem.title;
backItem.title = title ? title : previousViewControllerInStack.navigationItem.title;
} else {
backItem.title = @"";
}
Expand All @@ -145,7 +149,13 @@ - (void)setBackButtonOptions:(RNNBackButtonOptions *)backButtonOptions {
[backItem setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIFont fontWithName:fontFamily size:resolvedFontSize], NSFontAttributeName, nil] forState:UIControlStateHighlighted];
}

lastViewControllerInStack.navigationItem.backBarButtonItem = backItem;
previousViewControllerInStack.navigationItem.backBarButtonItem = backItem;
}

- (UIViewController *)previousViewControllerInStack {
NSArray* stackChildren = self.navigationController.viewControllers;
UIViewController *previousViewControllerInStack = stackChildren.count > 1 ? stackChildren[stackChildren.count - 2] : self.navigationController.topViewController;
return previousViewControllerInStack;
}

- (BOOL)transparent {
Expand Down
2 changes: 2 additions & 0 deletions lib/ios/UINavigationController+RNNOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@

- (void)setNavigationBarClipsToBounds:(BOOL)clipsToBounds;

- (void)setBackButtonTestID:(NSString *)testID;

@end
7 changes: 7 additions & 0 deletions lib/ios/UINavigationController+RNNOptions.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#import "UINavigationController+RNNOptions.h"
#import "RNNFontAttributesCreator.h"
#import "UIView+Utils.h"

const NSInteger BLUR_TOPBAR_TAG = 78264802;

Expand Down Expand Up @@ -58,6 +59,12 @@ - (void)setNavigationBarClipsToBounds:(BOOL)clipsToBounds {
self.navigationBar.clipsToBounds = clipsToBounds;
}

- (void)setBackButtonTestID:(NSString *)testID {
UIView* navigationBarContentView = [self.navigationBar findChildByClass:NSClassFromString(@"_UINavigationBarContentView")];
UIView* barButton = [navigationBarContentView findChildByClass:NSClassFromString(@"_UIButtonBarButton")];
if (barButton) barButton.accessibilityIdentifier = testID;
}

- (CGFloat)getTopBarHeight {
return self.navigationBar.frame.size.height;
}
Expand Down
2 changes: 0 additions & 2 deletions lib/ios/Utils/UIView+Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,4 @@ typedef NS_ENUM(NSInteger, ViewType) {

- (ViewType)viewType;

- (void)layout:(CGFloat)p;

@end
4 changes: 0 additions & 4 deletions lib/ios/Utils/UIView+Utils.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ - (UIView *)findChildByClass:(id)clazz {
return nil;
}

- (void)layout:(CGFloat)p {

}

- (ViewType)viewType {
if ([self isKindOfClass:[RCTImageView class]]) {
return ViewTypeImage;
Expand Down
12 changes: 12 additions & 0 deletions playground/ios/NavigationTests/RNNStackControllerTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#import <ReactNativeNavigation/RNNStackController.h>
#import <ReactNativeNavigation/RNNComponentViewController.h>
#import "RNNTestRootViewCreator.h"
#import "RNNComponentViewController+Utils.h"

@interface RNNStackControllerTest : XCTestCase

Expand Down Expand Up @@ -210,6 +211,17 @@ - (void)testMergeChildOptionsShouldNotUpdatePresenterForInvisibleChild {
[_presenter verify];
}

- (void)testOnChildWillAppear_shouldSetBackButtonTestID {
RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initEmptyOptions];
options.topBar.backButton.testID = [Text withValue:@"TestID"];
RNNComponentViewController* pushedController = [RNNComponentViewController createWithComponentId:@"pushedController"];
pushedController.options.topBar.backButton.testID = [Text withValue:@"TestID"];
[[[UIApplication sharedApplication] keyWindow] setRootViewController:_uut];
[_uut pushViewController:pushedController animated:NO];
[pushedController viewDidAppear:YES];
XCTAssertTrue([[[_uut.navigationBar.subviews[2] subviews][0] valueForKey:@"accessibilityIdentifier"] isEqualToString:@"TestID"]);
}

- (RNNStackController *)createNavigationControllerWithOptions:(RNNNavigationOptions *)options {
RNNStackController* nav = [[RNNStackController alloc] initWithLayoutInfo:nil creator:_creator options:options defaultOptions:nil presenter:[[RNNStackPresenter alloc] init] eventEmitter:nil childViewControllers:@[_vc1]];
return nav;
Expand Down
12 changes: 1 addition & 11 deletions playground/ios/NavigationTests/TopBarAppearancePresenterTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ @implementation TopBarAppearancePresenterTest {
- (void)setUp {
[super setUp];
_componentViewController = [RNNComponentViewController createWithComponentId:@"componentId"];
_stack = [[RNNStackController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:[[RNNNavigationOptions alloc] initEmptyOptions] presenter:_uut eventEmitter:nil childViewControllers:@[_componentViewController]];
_uut = [[TopBarAppearancePresenter alloc] initWithNavigationController:_stack];
_stack = [[RNNStackController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:[[RNNNavigationOptions alloc] initEmptyOptions] presenter:_uut eventEmitter:nil childViewControllers:@[_componentViewController]];
}

- (void)testMergeOptions_shouldMergeWithDefault {
Expand All @@ -36,14 +36,4 @@ - (void)testMergeOptions_shouldMergeWithDefault {
XCTAssertEqual(font.pointSize, 21);
}

- (void)testApplyOptions_shouldSetBackButtonTestID {
RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initEmptyOptions];
options.topBar.backButton.testID = [Text withValue:@"TestID"];

[_uut applyOptions:options.topBar];
XCTAssertTrue([_componentViewController.navigationItem.backBarButtonItem.accessibilityIdentifier isEqualToString:@"TestID"]);
}



@end
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ + (RNNComponentViewController *)createWithComponentId:(NSString *)componentId in
}

+ (RNNComponentViewController *)createWithComponentId:(NSString *)componentId {
return [self createWithComponentId:componentId initialOptions:nil];
return [self createWithComponentId:componentId initialOptions:RNNNavigationOptions.emptyOptions];
}

@end
4 changes: 4 additions & 0 deletions playground/src/screens/PushedScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const {
SET_STACK_ROOT_BUTTON,
PUSH_OPTIONS_BUTTON,
HIDE_PREVIOUS_SCREEN_TOP_BAR,
BACK_BUTTON,
} = testIDs;

interface Props extends NavigationComponentProps {
Expand All @@ -41,6 +42,9 @@ export default class PushedScreen extends React.Component<Props> {
text: 'single',
testID: TOP_BAR_BTN,
},
backButton: {
testID: BACK_BUTTON,
},
},
};
}
Expand Down
1 change: 1 addition & 0 deletions playground/src/testIDs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const testIDs = {
TOP_BAR_BTN: 'TOP_BAR_BUTTON',
CUSTOM_BACK_BTN: 'CUSTOM_BACK_BUTTON',
PUSH_CUSTOM_BACK_BTN: 'PUSH_CUSTOM_BACK_BTN',
BACK_BUTTON: 'BACK_BUTTON',
SWITCH_TAB_BY_INDEX_BTN: 'SWITCH_TAB_BY_INDEX_BTN',
SWITCH_TAB_BY_COMPONENT_ID_BTN: 'SWITCH_TAB_BY_COMPONENT_ID_BTN',
PUSHED_BOTTOM_TABS: 'PUSHED_BOTTOM_TABS',
Expand Down
19 changes: 16 additions & 3 deletions website/api/options-backButton.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,55 @@ Controls the back button styling.
```js
const options = {
topBar: {
backButton: {}
}
}
backButton: {},
},
};
```

### `color`

Change the back button color. This will change the text color as well.

| Type | Required | Platform |
| ----- | -------- | -------- |
| color | No | Both |

### `icon`

Change the default back button icon.

| Type | Required | Platform |
| ------ | -------- | -------- |
| number | No | Both |

### `showTitle`

Show or hide the text displayed next to the back button.

| Type | Required | Platform |
| ------ | -------- | -------- |
| number | No | iOS |

### `title`

Change the text displayed next to the title. Usually the back button shows the title of the previous screen.

| Type | Required | Platform |
| ------ | -------- | -------- |
| string | No | iOS |

### `visible`

Hide or show the back button.

| Type | Required | Platform |
| ------- | -------- | -------- |
| boolean | No | Both |

### `testID`

Used to interact with the back button in e2e tests.

| Type | Required | Platform |
| ------ | -------- | -------- |
| string | No | Both |

0 comments on commit 9676e9c

Please sign in to comment.