Skip to content

Commit 5e50329

Browse files
authored
Merge branch 'master' into fix/attach-mode-initial-tab
2 parents 877a79d + 6439f68 commit 5e50329

File tree

15 files changed

+150
-17
lines changed

15 files changed

+150
-17
lines changed

e2e/Stack.test.js

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,28 @@
1+
import jestExpect from 'expect';
12
import Utils from './Utils';
23
import TestIDs from '../playground/src/testIDs';
34
import Android from './AndroidUtils';
45

56
const { elementByLabel, elementById, sleep } = Utils;
67

8+
const driver = {
9+
root: {
10+
navToTitleAndSubtitle: async () => {
11+
await elementById(TestIDs.PUSH_TITLE_WITH_SUBTITLE).tap();
12+
return driver.titleWithSubtitle;
13+
},
14+
},
15+
16+
titleWithSubtitle: {
17+
titleId: `${TestIDs.TOPBAR_ID}.title`,
18+
subtitleId: `${TestIDs.TOPBAR_ID}.subtitle`,
19+
title: () => elementById(driver.titleWithSubtitle.titleId),
20+
titleByLabel: () => elementByLabel('Title'),
21+
subtitle: () => elementById(driver.titleWithSubtitle.subtitleId),
22+
subtitleByLabel: () => elementByLabel('Subtitle'),
23+
},
24+
};
25+
726
describe('Stack', () => {
827
beforeEach(async () => {
928
await device.launchApp({ newInstance: true });
@@ -78,9 +97,25 @@ describe('Stack', () => {
7897
});
7998

8099
it('push title with subtitle', async () => {
81-
await elementById(TestIDs.PUSH_TITLE_WITH_SUBTITLE).tap();
82-
await expect(elementByLabel('Title')).toBeVisible();
83-
await expect(elementByLabel('Subtitle')).toBeVisible();
100+
const innerDriver = await driver.root.navToTitleAndSubtitle();
101+
await expect(innerDriver.titleByLabel()).toBeVisible();
102+
await expect(innerDriver.subtitleByLabel()).toBeVisible();
103+
});
104+
105+
it('push title & subtitle with derived test IDs', async () => {
106+
const innerDriver = await driver.root.navToTitleAndSubtitle();
107+
await expect(innerDriver.title()).toBeVisible();
108+
await expect(innerDriver.subtitle()).toBeVisible();
109+
});
110+
111+
it.e2e('push title & subtitle with derived test IDs (strict e2e)', async () => {
112+
const innerDriver = await driver.root.navToTitleAndSubtitle();
113+
114+
const titleAttr = await innerDriver.titleByLabel().getAttributes();
115+
jestExpect(titleAttr.identifier).toEqual(innerDriver.titleId);
116+
117+
const subtitleAttr = await innerDriver.subtitleByLabel().getAttributes();
118+
jestExpect(subtitleAttr.identifier).toEqual(innerDriver.subtitleId);
84119
});
85120

86121
it.e2e('screen lifecycle', async () => {

lib/Mock/Components/TopBar.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,16 @@ export const TopBar = class extends Component<TopBarProps> {
2626

2727
render() {
2828
const topBarOptions = this.props.topBarOptions;
29+
const topbarTestId = topBarOptions?.testID;
30+
const titleTestId = topbarTestId ? { testID: `${topbarTestId}.title` } : {};
31+
const subtitleTestId = topbarTestId ? { testID: `${topbarTestId}.subtitle` } : {};
2932
if (topBarOptions?.visible === false) return null;
3033
else {
3134
const component = topBarOptions?.title?.component;
3235
return (
33-
<View testID={topBarOptions?.testID}>
34-
<Text>{topBarOptions?.title?.text}</Text>
35-
<Text>{topBarOptions?.subtitle?.text}</Text>
36+
<View testID={topbarTestId}>
37+
<Text {...titleTestId}>{topBarOptions?.title?.text}</Text>
38+
<Text {...subtitleTestId}>{topBarOptions?.subtitle?.text}</Text>
3639
{this.renderButtons(topBarOptions?.leftButtons)}
3740
{this.renderButtons(topBarOptions?.rightButtons)}
3841
{component &&

lib/android/app/build.gradle

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def kotlinVersion = safeExtGet("RNNKotlinVersion", DEFAULT_KOTLIN_VERSION)
2121
def kotlinStdlib = safeExtGet('RNNKotlinStdlib',DEFAULT_KOTLIN_STDLIB )
2222
def kotlinCoroutinesCore = safeExtGet('RNNKotlinCoroutinesCore', '1.5.2')
2323
android {
24+
namespace 'com.reactnativenavigation'
2425
compileSdkVersion safeExtGetFallbackLowerBound('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
2526
buildToolsVersion = "34.0.0"
2627
defaultConfig {
@@ -62,8 +63,13 @@ android {
6263
}
6364
}
6465
compileOptions {
65-
sourceCompatibility JavaVersion.VERSION_1_8
66-
targetCompatibility JavaVersion.VERSION_1_8
66+
if (reactNativeMinorVersion() >= 73) {
67+
sourceCompatibility JavaVersion.VERSION_17
68+
targetCompatibility JavaVersion.VERSION_17
69+
} else {
70+
sourceCompatibility JavaVersion.VERSION_1_8
71+
targetCompatibility JavaVersion.VERSION_1_8
72+
}
6773
}
6874
kotlinOptions {
6975
if (reactNativeMinorVersion() >= 73) {

lib/android/app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2-
xmlns:tools="http://schemas.android.com/tools"
3-
package="com.reactnativenavigation">
2+
xmlns:tools="http://schemas.android.com/tools">
43

54
<application>
65
<activity

lib/android/app/src/main/java/com/reactnativenavigation/views/stack/topbar/TopBar.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ public void setSubtitleAlignment(Alignment alignment) {
181181

182182
public void setTestId(String testId) {
183183
setTag(testId);
184+
titleAndButtonsContainer.setTestId(testId);
184185
}
185186

186187
public void setTitleTextColor(@ColorInt int color) {

lib/android/app/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleAndButtonsContainer.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ class TitleAndButtonsContainer(context: Context) : ViewGroup(context) {
9999
clearComponent()
100100
}
101101

102+
fun setTestId(testId: String) {
103+
titleSubTitleBar.setTestId(testId)
104+
}
105+
102106
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
103107
val titleComponent = getTitleComponent()
104108
val isCenter = titleComponentAlignment == Alignment.Center

lib/android/app/src/main/java/com/reactnativenavigation/views/stack/topbar/titlebar/TitleSubTitleLayout.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ class TitleSubTitleLayout(context: Context) : LinearLayout(context) {
7575
}
7676
}
7777

78+
fun setTestId(testId: String) {
79+
if (testId.isEmpty()) {
80+
this.titleTextView.tag = null
81+
this.subTitleTextView.tag = null
82+
} else {
83+
this.titleTextView.tag = "$testId.title"
84+
this.subTitleTextView.tag = "$testId.subtitle"
85+
}
86+
}
87+
7888
fun getTitle() = (this.titleTextView.text ?: "").toString()
7989

8090
fun clear() {
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.reactnativenavigation.views
2+
3+
import android.app.Activity
4+
import android.view.ViewGroup
5+
import android.widget.FrameLayout
6+
import com.reactnativenavigation.BaseTest
7+
import com.reactnativenavigation.views.stack.topbar.titlebar.TitleSubTitleLayout
8+
import org.assertj.core.api.AssertionsForInterfaceTypes.*
9+
import org.junit.Test
10+
11+
private const val UUT_WIDTH = 1000
12+
private const val UUT_HEIGHT = 100
13+
14+
15+
class TitleSubTitleLayoutTest : BaseTest() {
16+
private val testId = "mock-testId"
17+
18+
lateinit var uut: TitleSubTitleLayout
19+
private lateinit var activity: Activity
20+
21+
override fun beforeEach() {
22+
super.beforeEach()
23+
setup()
24+
}
25+
26+
private fun setup() {
27+
activity = newActivity()
28+
29+
uut = TitleSubTitleLayout(activity)
30+
31+
activity.setContentView(FrameLayout(activity).apply {
32+
addView(uut, ViewGroup.LayoutParams(UUT_WIDTH, UUT_HEIGHT))
33+
})
34+
idleMainLooper()
35+
}
36+
37+
@Test
38+
fun `should set Test ID canonically`(){
39+
uut.setTestId(testId)
40+
assertThat(uut.getTitleTxtView().tag).isEqualTo("$testId.title")
41+
assertThat(uut.getSubTitleTxtView().tag).isEqualTo("$testId.subtitle")
42+
}
43+
44+
@Test
45+
fun `should clear test ID`() {
46+
uut.setTestId(testId)
47+
uut.setTestId("")
48+
assertThat(uut.getTitleTxtView().tag).isNull()
49+
assertThat(uut.getSubTitleTxtView().tag).isNull()
50+
}
51+
}

lib/ios/RNNTitleViewHelper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818

1919
@property(nonatomic, strong) RNNTitleOptions *titleOptions;
2020
@property(nonatomic, strong) RNNSubtitleOptions *subtitleOptions;
21+
@property(nonatomic, strong) Text *parentTestID;
2122

2223
- (instancetype)initWithTitleViewOptions:(RNNOptions *)titleOptions
2324
subTitleOptions:(RNNOptions *)subtitleOptions
25+
parentTestID:(Text *)parentTestID
2426
viewController:(UIViewController *)viewController;
2527

2628
- (void)setup;

lib/ios/RNNTitleViewHelper.m

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,14 @@ @implementation RNNTitleViewHelper
3838

3939
- (instancetype)initWithTitleViewOptions:(RNNTitleOptions *)titleOptions
4040
subTitleOptions:(RNNSubtitleOptions *)subtitleOptions
41+
parentTestID:(Text *)parentTestID
4142
viewController:(UIViewController *)viewController {
4243
self = [super init];
4344
if (self) {
4445
self.viewController = viewController;
4546
self.titleOptions = titleOptions;
4647
self.subtitleOptions = subtitleOptions;
48+
self.parentTestID = parentTestID;
4749
}
4850
return self;
4951
}
@@ -81,7 +83,7 @@ - (void)setup {
8183
if (self.title) {
8284
self.titleView.titleLabel = [self setupTitle];
8385
}
84-
86+
8587
[self centerTitleView:navigationBarBounds
8688
titleLabel:self.titleView.titleLabel
8789
subtitleLabel:self.titleView.subtitleLabel];
@@ -135,6 +137,11 @@ - (UILabel *)setupSubtitle {
135137
subtitleLabel.textColor = color;
136138
}
137139

140+
if (_parentTestID && _parentTestID.hasValue && ((NSString *)_parentTestID.get).length > 0) {
141+
subtitleLabel.accessibilityIdentifier =
142+
[NSString stringWithFormat:@"%@.subtitle", _parentTestID.get];
143+
}
144+
138145
[self.titleView addSubview:subtitleLabel];
139146

140147
return subtitleLabel;
@@ -174,6 +181,11 @@ - (UILabel *)setupTitle {
174181
titleLabel.textColor = color;
175182
}
176183

184+
if (_parentTestID && _parentTestID.hasValue && ((NSString *)_parentTestID.get).length > 0) {
185+
titleLabel.accessibilityIdentifier =
186+
[NSString stringWithFormat:@"%@.title", _parentTestID.get];
187+
}
188+
177189
[self.titleView addSubview:titleLabel];
178190

179191
return titleLabel;

lib/ios/TopBarTitlePresenter.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ - (void)setTitleViewWithSubtitle:(RNNTopBarOptions *)options {
4747
_titleViewHelper =
4848
[[RNNTitleViewHelper alloc] initWithTitleViewOptions:options.title
4949
subTitleOptions:options.subtitle
50+
parentTestID:options.testID
5051
viewController:self.boundViewController];
5152

5253
if (options.title.text.hasValue) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-navigation",
3-
"version": "7.39.2",
3+
"version": "7.40.0",
44
"description": "React Native Navigation - truly native navigation for iOS and Android",
55
"license": "MIT",
66
"nativePackage": true,

playground/ios/Podfile

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,18 @@ def all_pods
3535
end
3636

3737
post_install do |installer|
38-
react_native_post_install(
39-
installer,
40-
"../../node_modules/react-native",
41-
:mac_catalyst_enabled => false
42-
)
38+
__apply_Xcode_15_3_flipper_post_install_workaround(installer)
39+
40+
react_native_post_install(installer, "../../node_modules/react-native", :mac_catalyst_enabled => false)
41+
42+
__apply_Xcode_15_unary_binary_error_workaround(installer)
43+
44+
# This is to resolve "'shared_timed_mutex' is unavailable: introduced in iOS 10.0" error
45+
installer.pods_project.targets.each do |t|
46+
t.build_configurations.each do |config|
47+
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.4'
48+
end
49+
end
4350
end
4451

4552
def __apply_Xcode_15_3_flipper_post_install_workaround(installer)

playground/src/screens/StackScreen.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ export default class StackScreen extends React.Component<NavigationProps> {
121121
name: Screens.Pushed,
122122
options: {
123123
topBar: {
124+
testID: testIDs.TOPBAR_ID,
124125
title: {
125126
text: 'Title',
126127
},

playground/src/testIDs.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ const testIDs = {
7474
CUSTOM_BACK_BTN: 'CUSTOM_BACK_BUTTON',
7575
PUSH_CUSTOM_BACK_BTN: 'PUSH_CUSTOM_BACK_BTN',
7676
PUSH_TITLE_WITH_SUBTITLE: 'PUSH_TITLE_WITH_SUBTITLE',
77+
TOPBAR_ID: 'TOPBAR_ID',
7778
BACK_BUTTON: 'BACK_BUTTON',
7879
TOGGLE_BACK: 'TOGGLE_BACK',
7980
SWITCH_TAB_BY_INDEX_BTN: 'SWITCH_TAB_BY_INDEX_BTN',

0 commit comments

Comments
 (0)