Skip to content

Commit e0950b2

Browse files
CodingItWronggrabbou
authored andcommitted
Added filtering to RNTester example screens (facebook#22777)
Summary: This PR adds filtering functionality to individual example screens of RNTester. This is useful for Detox testing of RNTester, since Detox requires elements to be visible on the screen before they can be interacted with. Instead of needing to scroll an arbitrary amount, the test can enter the name of the example to be tested, just as is done on the main screen. This will lead to simpler and more reliable E2E tests for long example screens. This PR doesn't add any automated tests using the filter; those will be added in a separate PR. This is implemented by extracting the existing filtering functionality out of `RNTesterExampleList` into a shared `RNTesterExampleFilter` component that can be used both within `RNTesterExampleList` (the main screen) and `RNTesterExampleContainer` (the example screen). ![simulator screen shot - iphone 8 - 2018-12-24 at 08 22 46](https://user-images.githubusercontent.com/15832198/50401564-4273a300-0755-11e9-9120-9bf8fbb70261.png) ![simulator screen shot - iphone 8 - 2018-12-24 at 08 22 51](https://user-images.githubusercontent.com/15832198/50401566-44d5fd00-0755-11e9-9637-6e5ddce1c476.png) Changelog: ---------- [General] [Added] - Added filtering to RNTester example screens Pull Request resolved: facebook#22777 Reviewed By: TheSavior Differential Revision: D13561744 Pulled By: rickhanlonii fbshipit-source-id: cb120626a8e2b8440f88b871557c0b92fbef5edc
1 parent 5668d81 commit e0950b2

File tree

3 files changed

+155
-77
lines changed

3 files changed

+155
-77
lines changed

RNTester/js/RNTesterExampleContainer.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
const React = require('react');
1313
const {Platform} = require('react-native');
1414
const RNTesterBlock = require('./RNTesterBlock');
15+
const RNTesterExampleFilter = require('./RNTesterExampleFilter');
1516
const RNTesterPage = require('./RNTesterPage');
1617

1718
class RNTesterExampleContainer extends React.Component {
@@ -37,9 +38,30 @@ class RNTesterExampleContainer extends React.Component {
3738
return <this.props.module />;
3839
}
3940

41+
if (this.props.module.examples.length === 1) {
42+
const Example = this.props.module.examples[0].render;
43+
return <Example />;
44+
}
45+
46+
const filter = ({example, filterRegex}) => filterRegex.test(example.title);
47+
48+
const sections = [
49+
{
50+
data: this.props.module.examples,
51+
title: 'EXAMPLES',
52+
key: 'e',
53+
},
54+
];
55+
4056
return (
4157
<RNTesterPage title={this.props.title}>
42-
{this.props.module.examples.map(this.renderExample)}
58+
<RNTesterExampleFilter
59+
sections={sections}
60+
filter={filter}
61+
render={({filteredSections}) =>
62+
filteredSections[0].data.map(this.renderExample)
63+
}
64+
/>
4365
</RNTesterPage>
4466
);
4567
}

RNTester/js/RNTesterExampleFilter.js

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
* @flow
9+
*/
10+
11+
'use strict';
12+
13+
const React = require('react');
14+
const StyleSheet = require('StyleSheet');
15+
const TextInput = require('TextInput');
16+
const View = require('View');
17+
18+
type Props = {
19+
filter: Function,
20+
render: Function,
21+
sections: Object,
22+
disableSearch?: boolean,
23+
};
24+
25+
type State = {
26+
filter: string,
27+
};
28+
29+
class RNTesterExampleFilter extends React.Component<Props, State> {
30+
state = {filter: ''};
31+
32+
render() {
33+
const filterText = this.state.filter;
34+
let filterRegex = /.*/;
35+
36+
try {
37+
filterRegex = new RegExp(String(filterText), 'i');
38+
} catch (error) {
39+
console.warn(
40+
'Failed to create RegExp: %s\n%s',
41+
filterText,
42+
error.message,
43+
);
44+
}
45+
46+
const filter = example =>
47+
this.props.disableSearch || this.props.filter({example, filterRegex});
48+
49+
const filteredSections = this.props.sections.map(section => ({
50+
...section,
51+
data: section.data.filter(filter),
52+
}));
53+
54+
return (
55+
<View>
56+
{this._renderTextInput()}
57+
{this.props.render({filteredSections})}
58+
</View>
59+
);
60+
}
61+
62+
_renderTextInput(): ?React.Element<any> {
63+
if (this.props.disableSearch) {
64+
return null;
65+
}
66+
return (
67+
<View style={styles.searchRow}>
68+
<TextInput
69+
autoCapitalize="none"
70+
autoCorrect={false}
71+
clearButtonMode="always"
72+
onChangeText={text => {
73+
this.setState(() => ({filter: text}));
74+
}}
75+
placeholder="Search..."
76+
underlineColorAndroid="transparent"
77+
style={styles.searchTextInput}
78+
testID="explorer_search"
79+
value={this.state.filter}
80+
/>
81+
</View>
82+
);
83+
}
84+
}
85+
86+
const styles = StyleSheet.create({
87+
searchRow: {
88+
backgroundColor: '#eeeeee',
89+
padding: 10,
90+
},
91+
searchTextInput: {
92+
backgroundColor: 'white',
93+
borderColor: '#cccccc',
94+
borderRadius: 3,
95+
borderWidth: 1,
96+
paddingLeft: 8,
97+
paddingVertical: 0,
98+
height: 35,
99+
},
100+
});
101+
102+
module.exports = RNTesterExampleFilter;

RNTester/js/RNTesterExampleList.js

Lines changed: 30 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ const React = require('react');
1515
const SectionList = require('SectionList');
1616
const StyleSheet = require('StyleSheet');
1717
const Text = require('Text');
18-
const TextInput = require('TextInput');
1918
const TouchableHighlight = require('TouchableHighlight');
2019
const RNTesterActions = require('./RNTesterActions');
20+
const RNTesterExampleFilter = require('./RNTesterExampleFilter');
2121
const View = require('View');
2222

2323
/* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found when
2424
* making Flow check .android.js files. */
2525
import type {RNTesterExample} from './RNTesterList.ios';
26-
import type {TextStyleProp, ViewStyleProp} from 'StyleSheet';
26+
import type {ViewStyleProp} from 'StyleSheet';
2727

2828
type Props = {
2929
onNavigate: Function,
@@ -69,58 +69,48 @@ const renderSectionHeader = ({section}) => (
6969
);
7070

7171
class RNTesterExampleList extends React.Component<Props, $FlowFixMeState> {
72-
state = {filter: ''};
73-
7472
render() {
75-
const filterText = this.state.filter;
76-
let filterRegex = /.*/;
77-
78-
try {
79-
filterRegex = new RegExp(String(filterText), 'i');
80-
} catch (error) {
81-
console.warn(
82-
'Failed to create RegExp: %s\n%s',
83-
filterText,
84-
error.message,
85-
);
86-
}
87-
88-
const filter = example =>
73+
const filter = ({example, filterRegex}) =>
8974
/* $FlowFixMe(>=0.68.0 site=react_native_fb) This comment suppresses an
90-
* error found when Flow v0.68 was deployed. To see the error delete this
91-
* comment and run Flow. */
92-
this.props.disableSearch ||
93-
(filterRegex.test(example.module.title) &&
94-
(!Platform.isTV || example.supportsTVOS));
75+
* error found when Flow v0.68 was deployed. To see the error delete this
76+
* comment and run Flow. */
77+
filterRegex.test(example.module.title) &&
78+
(!Platform.isTV || example.supportsTVOS);
9579

9680
const sections = [
9781
{
98-
data: this.props.list.ComponentExamples.filter(filter),
82+
data: this.props.list.ComponentExamples,
9983
title: 'COMPONENTS',
10084
key: 'c',
10185
},
10286
{
103-
data: this.props.list.APIExamples.filter(filter),
87+
data: this.props.list.APIExamples,
10488
title: 'APIS',
10589
key: 'a',
10690
},
10791
];
92+
10893
return (
10994
<View style={[styles.listContainer, this.props.style]}>
11095
{this._renderTitleRow()}
111-
{this._renderTextInput()}
112-
<SectionList
113-
ItemSeparatorComponent={ItemSeparator}
114-
contentContainerStyle={{backgroundColor: 'white'}}
115-
style={styles.list}
96+
<RNTesterExampleFilter
11697
sections={sections}
117-
renderItem={this._renderItem}
118-
enableEmptySections={true}
119-
itemShouldUpdate={this._itemShouldUpdate}
120-
keyboardShouldPersistTaps="handled"
121-
automaticallyAdjustContentInsets={false}
122-
keyboardDismissMode="on-drag"
123-
renderSectionHeader={renderSectionHeader}
98+
filter={filter}
99+
render={({filteredSections}) => (
100+
<SectionList
101+
ItemSeparatorComponent={ItemSeparator}
102+
contentContainerStyle={styles.sectionListContentContainer}
103+
style={styles.list}
104+
sections={filteredSections}
105+
renderItem={this._renderItem}
106+
enableEmptySections={true}
107+
itemShouldUpdate={this._itemShouldUpdate}
108+
keyboardShouldPersistTaps="handled"
109+
automaticallyAdjustContentInsets={false}
110+
keyboardDismissMode="on-drag"
111+
renderSectionHeader={renderSectionHeader}
112+
/>
113+
)}
124114
/>
125115
</View>
126116
);
@@ -162,32 +152,6 @@ class RNTesterExampleList extends React.Component<Props, $FlowFixMeState> {
162152
);
163153
}
164154

165-
_renderTextInput(): ?React.Element<any> {
166-
/* $FlowFixMe(>=0.68.0 site=react_native_fb) This comment suppresses an
167-
* error found when Flow v0.68 was deployed. To see the error delete this
168-
* comment and run Flow. */
169-
if (this.props.disableSearch) {
170-
return null;
171-
}
172-
return (
173-
<View style={styles.searchRow}>
174-
<TextInput
175-
autoCapitalize="none"
176-
autoCorrect={false}
177-
clearButtonMode="always"
178-
onChangeText={text => {
179-
this.setState(() => ({filter: text}));
180-
}}
181-
placeholder="Search..."
182-
underlineColorAndroid="transparent"
183-
style={styles.searchTextInput}
184-
testID="explorer_search"
185-
value={this.state.filter}
186-
/>
187-
</View>
188-
);
189-
}
190-
191155
_handleRowPress(exampleKey: string): void {
192156
this.props.onNavigate(RNTesterActions.ExampleAction(exampleKey));
193157
}
@@ -225,6 +189,9 @@ const styles = StyleSheet.create({
225189
height: StyleSheet.hairlineWidth,
226190
backgroundColor: 'rgb(217, 217, 217)',
227191
},
192+
sectionListContentContainer: {
193+
backgroundColor: 'white',
194+
},
228195
rowTitleText: {
229196
fontSize: 17,
230197
fontWeight: '500',
@@ -234,19 +201,6 @@ const styles = StyleSheet.create({
234201
color: '#888888',
235202
lineHeight: 20,
236203
},
237-
searchRow: {
238-
backgroundColor: '#eeeeee',
239-
padding: 10,
240-
},
241-
searchTextInput: {
242-
backgroundColor: 'white',
243-
borderColor: '#cccccc',
244-
borderRadius: 3,
245-
borderWidth: 1,
246-
paddingLeft: 8,
247-
paddingVertical: 0,
248-
height: 35,
249-
},
250204
});
251205

252206
module.exports = RNTesterExampleList;

0 commit comments

Comments
 (0)