Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detox #283

Merged
merged 28 commits into from
May 23, 2018
Merged

Detox #283

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,52 @@ jobs:
command: |
npx codecov

e2e-test:
macos:
xcode: "9.0"

environment:
BASH_ENV: "~/.nvm/nvm.sh"

steps:
- checkout

- run:
name: Install Node 8
command: |
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh | bash
source ~/.nvm/nvm.sh
# https://github.com/creationix/nvm/issues/1394
set +e
nvm install 8

- run:
name: Install appleSimUtils
command: |
brew update
brew tap wix/brew
brew install applesimutils

- run:
name: Install NPM modules
command: |
rm -rf node_modules
npm install
npm install -g detox-cli

- run:
name: Build
command: |
detox build

- run:
name: Test
command: |
detox test

- store_artifacts:
path: /tmp/screenshots

android-build:
<<: *defaults
docker:
Expand Down Expand Up @@ -215,10 +261,14 @@ workflows:
build-and-test:
jobs:
- lint-testunit
- e2e-test:
requires:
- lint-testunit

- ios-build:
requires:
- lint-testunit
- e2e-test
- ios-testflight:
requires:
- ios-build
Expand All @@ -235,3 +285,4 @@ workflows:
- android-build:
requires:
- lint-testunit
- e2e-test
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
__tests__
node_modules
coverage
e2e
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ Follow the [React Native Getting Started Guide](https://facebook.github.io/react
$ npm run android
```

# Detox (end-to-end tests)
- Build your app

```bash
$ detox build
```

- Run tests

```bash
$ detox test
```

# Storybook
- General requirements
- Install storybook
Expand Down
3 changes: 2 additions & 1 deletion app/ReactotronConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ if (__DEV__) {
.connect();
// Running on android device
// $ adb reverse tcp:9090 tcp:9090
console.warn = Reactotron.log;
// Reactotron.clear();
// console.warn = Reactotron.log;
}
3 changes: 2 additions & 1 deletion app/containers/Button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,15 @@ export default class Button extends React.PureComponent {

render() {
const {
title, type, onPress, disabled
title, type, onPress, disabled, ...otherProps
} = this.props;
return (
<Touch
onPress={onPress}
accessibilityTraits='button'
style={Platform.OS === 'ios' && styles.margin}
disabled={disabled}
{...otherProps}
>
<View
style={[
Expand Down
6 changes: 5 additions & 1 deletion app/containers/CloseModalButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ export default class CloseModalButton extends React.PureComponent {

render() {
return (
<TouchableOpacity onPress={() => this.props.navigation.dispatch(NavigationActions.back())} style={styles.button}>
<TouchableOpacity
onPress={() => this.props.navigation.dispatch(NavigationActions.back())}
style={styles.button}
testID='close-modal-button'
>
<Icon
style={styles.icon}
name='close'
Expand Down
1 change: 1 addition & 0 deletions app/containers/EmojiPicker/EmojiCategory.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export default class EmojiCategory extends React.Component {
activeOpacity={0.7}
key={emoji.isCustom ? emoji.content : emoji}
onPress={() => this.props.onEmojiSelected(emoji)}
testID={`reaction-picker-${ emoji.isCustom ? emoji.content : emoji }`}
>
{renderEmoji(emoji, size)}
</TouchableOpacity>);
Expand Down
1 change: 1 addition & 0 deletions app/containers/EmojiPicker/TabBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default class TabBar extends React.PureComponent {
key={tab}
onPress={() => this.props.goToPage(i)}
style={styles.tab}
testID={`reaction-picker-${ tab }`}
>
<Text style={[styles.tabEmoji, this.props.tabEmojiStyle]}>{tab}</Text>
{this.props.activeTab === i ? <View style={styles.activeTabLine} /> : <View style={styles.tabLine} />}
Expand Down
1 change: 1 addition & 0 deletions app/containers/MessageActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ export default class MessageActions extends React.Component {
<ActionSheet
ref={o => this.ActionSheet = o}
title='Messages actions'
testID='message-actions'
options={this.options}
cancelButtonIndex={this.CANCEL_INDEX}
destructiveButtonIndex={this.DELETE_INDEX}
Expand Down
2 changes: 1 addition & 1 deletion app/containers/MessageBox/EmojiKeyboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default class EmojiKeyboard extends React.PureComponent {
render() {
return (
<Provider store={store}>
<View style={styles.emojiKeyboardContainer}>
<View style={styles.emojiKeyboardContainer} testID='messagebox-keyboard-emoji'>
<EmojiPicker onEmojiSelected={emoji => this.onEmojiSelected(emoji)} />
</View>
</Provider>
Expand Down
3 changes: 2 additions & 1 deletion app/containers/MessageBox/Recording.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ export default class extends React.PureComponent {
render() {
return (
<SafeAreaView
key='messagebox'
key='messagebox-recording'
testID='messagebox-recording'
style={styles.textBox}
>
<View style={[styles.textArea, { backgroundColor: '#F6F7F9' }]}>
Expand Down
32 changes: 22 additions & 10 deletions app/containers/MessageBox/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ export default class MessageBox extends React.PureComponent {
const regexp = /(#|@|:)([a-z0-9._-]+)$/im;

const result = lastNativeText.substr(0, cursor).match(regexp);

if (!result) {
return this.stopTrackingMention();
}
Expand All @@ -111,6 +110,7 @@ export default class MessageBox extends React.PureComponent {
accessibilityLabel='Cancel editing'
accessibilityTraits='button'
onPress={() => this.editCancel()}
testID='messagebox-cancel-editing'
/>);
}
return !this.state.showEmojiKeyboard ? (<Icon
Expand All @@ -119,12 +119,14 @@ export default class MessageBox extends React.PureComponent {
accessibilityLabel='Open emoji selector'
accessibilityTraits='button'
name='mood'
testID='messagebox-open-emoji'
/>) : (<Icon
onPress={() => this.closeEmoji()}
style={styles.actionButtons}
accessibilityLabel='Close emoji selector'
accessibilityTraits='button'
name='keyboard'
testID='messagebox-close-emoji'
/>);
}
get rightButtons() {
Expand All @@ -138,6 +140,7 @@ export default class MessageBox extends React.PureComponent {
accessibilityLabel='Send message'
accessibilityTraits='button'
onPress={() => this.submit(this.state.text)}
testID='messagebox-send-message'
/>);
return icons;
}
Expand All @@ -148,6 +151,7 @@ export default class MessageBox extends React.PureComponent {
accessibilityLabel='Send audio message'
accessibilityTraits='button'
onPress={() => this.recordAudioMessage()}
testID='messagebox-send-audio'
/>);
icons.push(<MyIcon
style={[styles.actionButtons, { color: '#2F343D', fontSize: 16 }]}
Expand All @@ -156,6 +160,7 @@ export default class MessageBox extends React.PureComponent {
accessibilityLabel='Message actions'
accessibilityTraits='button'
onPress={() => this.addFile()}
testID='messagebox-actions'
/>);
return icons;
}
Expand Down Expand Up @@ -438,6 +443,7 @@ export default class MessageBox extends React.PureComponent {
<TouchableOpacity
style={styles.mentionItem}
onPress={() => this._onPressMention(item)}
testID={`mention-item-${ this.state.trackingType === MENTIONS_TRACKING_TYPE_EMOJIS ? item.name || item : item.username || item.name }`}
>
{this.state.trackingType === MENTIONS_TRACKING_TYPE_EMOJIS ?
[
Expand All @@ -463,14 +469,15 @@ export default class MessageBox extends React.PureComponent {
return null;
}
return (
<FlatList
key='messagebox-container'
style={styles.mentionList}
data={mentions}
renderItem={({ item }) => this.renderMentionItem(item)}
keyExtractor={item => item._id || item}
keyboardShouldPersistTaps='always'
/>
<View key='messagebox-container' testID='messagebox-container'>
<FlatList
style={styles.mentionList}
data={mentions}
renderItem={({ item }) => this.renderMentionItem(item)}
keyExtractor={item => item._id || item}
keyboardShouldPersistTaps='always'
/>
</View>
);
};

Expand All @@ -481,7 +488,11 @@ export default class MessageBox extends React.PureComponent {
return (
[
this.renderMentions(),
<View key='messagebox' style={[styles.textArea, this.props.editing && styles.editing]}>
<View
key='messagebox'
style={[styles.textArea, this.props.editing && styles.editing]}
testID='messagebox'
>
{this.leftButtons}
<TextInput
ref={component => this.component = component}
Expand All @@ -496,6 +507,7 @@ export default class MessageBox extends React.PureComponent {
defaultValue=''
multiline
placeholderTextColor='#9EA2A8'
testID='messagebox-input'
/>
{this.rightButtons}
</View>
Expand Down
21 changes: 17 additions & 4 deletions app/containers/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default class Sidebar extends Component {

onPressItem = (item) => {
this.props.selectServer(item.id);
this.props.navigation.dispatch(DrawerActions.closeDrawer());
this.closeDrawer();
}

getState = () => ({
Expand All @@ -78,12 +78,17 @@ export default class Sidebar extends Component {
this.setState(this.getState());
}

closeDrawer = () => {
this.props.navigation.dispatch(DrawerActions.closeDrawer());
}

renderItem = ({ item, separators }) => (

<TouchableHighlight
onShowUnderlay={separators.highlight}
onHideUnderlay={separators.unhighlight}
onPress={() => { this.onPressItem(item); }}
testID={`sidebar-${ item.id }`}
>
<View style={[styles.serverItem, (item.id === this.props.server ? styles.selectedServer : null)]}>
<Text>
Expand All @@ -96,14 +101,18 @@ export default class Sidebar extends Component {
render() {
return (
<ScrollView style={styles.scrollView}>
<View style={{ paddingBottom: 20 }}>
<View style={{ paddingBottom: 20 }} testID='sidebar'>
<FlatList
data={this.state.servers}
renderItem={this.renderItem}
keyExtractor={keyExtractor}
/>
<TouchableHighlight
onPress={() => { this.props.logout(); }}
onPress={() => {
this.closeDrawer();
this.props.logout();
}}
testID='sidebar-logout'
>
<View style={styles.serverItem}>
<Text>
Expand All @@ -112,7 +121,11 @@ export default class Sidebar extends Component {
</View>
</TouchableHighlight>
<TouchableHighlight
onPress={() => { this.props.navigation.navigate({ key: 'AddServer', routeName: 'AddServer' }); }}
onPress={() => {
this.closeDrawer();
this.props.navigation.navigate({ key: 'AddServer', routeName: 'AddServer' });
}}
testID='sidebar-add-server'
>
<View style={styles.serverItem}>
<Text>
Expand Down
Loading