...
 
Commits (2)
......@@ -144,6 +144,7 @@ exports[`Activity component renders correctly 1`] = `
},
}
}
testID=""
/>
<RemindAction
entity={
......
......@@ -210,6 +210,7 @@ exports[`Activity component renders correctly 1`] = `
}
}
onTranslate={[Function]}
testID=""
toggleEdit={[Function]}
/>
</View>
......
......@@ -7,6 +7,7 @@ exports[`cature poster component should renders correctly 1`] = `
"flex": 1,
}
}
testID="capturePosterView"
>
<View
style={
......
......@@ -127,6 +127,7 @@ exports[`Messenger setup component should render correctly for unlock 1`] = `
"padding": 16,
}
}
testID="MessengerSetupText"
underlineColorAndroid="transparent"
/>
</View>
......
import login from "./login";
import { waitForElement, tapElement, waitForAndTap } from "../helpers/waitFor";
export const capturePoster = async () => {
await waitForElement(by.id('usernameInput'));
await login(process.env.loginUser, process.env.loginPass);
await waitForElement(by.id('NewsfeedScreen'));
await tapElement(by.id('captureFab'));
}
export const deletePost = async () => {
await waitForAndTap(by.id('ActivityMoreButton'));
await waitForAndTap(by.id('deleteOption'));
await waitForAndTap(by.text('Ok'));
await waitForAndTap(by.text('Ok'));
}
import sleep from '../src/common/helpers/sleep';
import { waitForElement, waitForAndType, tapElement, waitForAndTap } from './helpers/waitFor';
import { capturePoster, deletePost } from './actions/capturePoster';
describe('Comment Flow', () => {
beforeEach(async () => {
await device.launchApp({
newInstance: true,
permissions: {
notifications: 'YES',
camera: 'YES',
medialibrary: 'YES',
photos: 'YES',
},
});
await capturePoster();
});
it('should be able to create post and comment', async () => {
const text = 'e2eTest';
const commentText = 'commentE2ETest';
const replyText = 'replyE2ETest';
// create post
await waitForAndType(by.id('PostInput'), text);
await tapElement(by.id('CapturePostButton'));
// wait for newsfeed
await waitForElement(by.id('NewsfeedScreen'));
// add comment
await waitForAndTap(by.id('ActivityCommentButton'));
await waitForAndType(by.id('CommentText'), commentText);
await tapElement(by.id('PostCommentButton'));
// add reply
await waitForAndTap(by.id('ReplyCommentButton'));
await waitForAndType(by.id('CommentText').withAncestor(by.id('CommentParentView')), replyText);
await tapElement(by.id('PostCommentButton').withAncestor(by.id('CommentParentView')));
// check reply
await waitForElement(by.label(`@${process.env.loginUser} ${replyText}`));
// finish
await deletePost();
});
});
export const TIME = 10000;
export const waitForElement = async (e) => {
await waitFor(element(e)).toBeVisible().withTimeout(TIME);
}
export const tapElement = async (e) => {
await element(e).tap();
}
export const typeText = async (e, text) => {
await element(e).typeText(text);
}
export const waitForAndTap = async (e) => {
await waitForElement(e);
await tapElement(e);
}
export const waitForAndType = async (e, text) => {
await waitForElement(e);
await typeText(e, text);
}
\ No newline at end of file
import sleep from '../src/common/helpers/sleep';
import { waitForElement, waitForAndType, tapElement, waitForAndTap } from './helpers/waitFor';
import login from './actions/login';
describe('Messenger Flow', () => {
beforeEach(async () => {
await device.launchApp({
newInstance: true,
permissions: {
notifications: 'YES',
camera: 'YES',
medialibrary: 'YES',
photos: 'YES',
},
});
await waitFor(element(by.id('usernameInput'))).toBeVisible().withTimeout(5000);
await login(process.env.loginUser, process.env.loginPass);
await expect(element(by.id('NewsfeedScreen'))).toBeVisible();
});
it('should be able to open messenger, unblock and send message', async () => {
const userName = 'JUANMSOLARO_TEST5';
const messageText = 'This is an auto generated message for testing purpose';
// wait for newsfeed
await waitForElement(by.id('NewsfeedScreen'));
await tapElement(by.id('MessengerTabButton'));
await waitForAndType(by.id('MessengerContactText'), userName);
await waitForAndTap(by.id(userName));
await tapElement(by.id(userName));
await waitForAndType(by.id('MessengerSetupText'), process.env.messengerpass);
await tapElement(by.id('NavNextButton'));
await waitForAndType(by.id('ConversationTextInput'), messageText);
await tapElement(by.id('ConversationSendButton'));
await waitForElement(by.label(messageText));
});
});
import sleep from '../src/common/helpers/sleep';
import { waitForElement, waitForAndType, tapElement, waitForAndTap } from './helpers/waitFor';
import { deletePost, capturePoster } from './actions/capturePoster';
describe('Post Flow', () => {
beforeEach(async () => {
await device.launchApp({
newInstance: true,
permissions: {
notifications: 'YES',
camera: 'YES',
medialibrary: 'YES',
photos: 'YES',
},
});
await capturePoster();
});
it('should be able to create a text only post', async () => {
const text = 'e2eTest';
// create post
await waitForAndType(by.id('PostInput'), text);
await tapElement(by.id('CapturePostButton'));
// wait for newsfeed
await waitForElement(by.id('NewsfeedScreen'));
await deletePost();
});
it('should be able to create a nsfw post with text', async () => {
const text = 'e2eTest';
// create post
await waitForAndType(by.id('PostInput'), text);
await tapElement(by.id('NsfwToggle'));
await tapElement(by.id('NsfwToggle'));
await waitForAndTap(by.id('NsfwReasonNudity'));
await tapElement(by.id('NsfwToggle'));
await tapElement(by.id('CapturePostButton'));
// wait for newsfeed
await waitForElement(by.id('NewsfeedScreen'));
await deletePost();
});
it('should be able to create a text and image post', async () => {
const text = 'e2eTest';
// create post
await waitForAndType(by.id('PostInput'), text);
await tapElement(by.id('GalleryImage0'));
await tapElement(by.id('GalleryImage0'));
await waitFor(element(by.id('CapturePostButton'))).toBeVisible().withTimeout(120000);
await tapElement(by.id('CapturePostButton'));
// wait for newsfeed
await waitForElement(by.id('NewsfeedScreen'));
await deletePost();
});
it('should be able to cancel image upload and then post', async () => {
const text = 'e2eTest';
// create post
await waitForAndType(by.id('PostInput'), text);
await tapElement(by.id('GalleryImage0'));
await tapElement(by.id('GalleryImage0'));
await waitForAndTap(by.id('AttachmentDeleteButton'));
await tapElement(by.id('CapturePostButton'));
// wait for newsfeed
await waitForElement(by.id('NewsfeedScreen'));
await deletePost();
});
});
......@@ -360,7 +360,7 @@ DEPENDENCIES:
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
trunk:
- boost-for-react-native
- JitsiMeetSDK
- libwebp
......@@ -539,4 +539,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 1f47b505eab73a09e6446d8196944df88cfdecc2
COCOAPODS: 1.7.5
COCOAPODS: 1.8.4
......@@ -35,7 +35,7 @@ export default class CaptureFab extends Component {
size={32}
containerStyle={ settingsStore.leftHanded ? styles.leftSide : styles.rightSide }
onPress={() => this.navToCapture()}
{...testID('CaptureButton')}
testID={this.props.testID}
/>
);
......
......@@ -159,7 +159,7 @@ export default class CaptureGallery extends PureComponent {
});
}
}
{...testID(`Gallery ${node.type}`)}
testID={`GalleryImage${item.index}`}
>
<Image
source={{ uri : node.image.uri }}
......
......@@ -46,7 +46,7 @@ class CapturePostButton extends Component {
: CS.borderGreyed,
CS.border,
]}
{...testID('Capture Post Button')}
testID={this.props.testID}
>
<Text style={[styles.buttonText, connectivityService.isConnected ? CS.colorPrimary : CS.colorGreyed]}>{text}</Text>
</TouchableOpacity>
......
......@@ -73,6 +73,7 @@ export default class CapturePoster extends Component {
headerRight: <CapturePostButton
onPress={() => !params.isRemind ? this.submit() : this.remind()}
text={params.isRemind ? i18n.t('capture.remind').toUpperCase() : i18n.t('capture.post').toUpperCase()}
testID="CapturePostButton"
/>
});
}
......@@ -186,7 +187,7 @@ export default class CapturePoster extends Component {
multiline={true}
selectTextOnFocus={false}
onSelectionChange={this.onSelectionChanges}
{...testID('PostInput')}
testID="PostInput"
/>
</View>
{showAttachmentFeatures && this.getAttachFeature()}
......@@ -212,7 +213,7 @@ export default class CapturePoster extends Component {
const params = navigation.state.params || {};
return (
<View style={CS.flexContainer}>
<View style={CS.flexContainer} testID="capturePosterView">
<CaptureGallery
onSelected={this.onAttachedMedia}
header={this.getHeader(true)}
......@@ -292,7 +293,7 @@ export default class CapturePoster extends Component {
uri={attachment.uri}
type={attachment.type}
/>
<Icon raised name="md-close" type="ionicon" color='#fff' size={22} containerStyle={styles.deleteAttachment} onPress={() => this.deleteAttachment()} {...testID('Attachment Delete Button')} />
<Icon raised name="md-close" type="ionicon" color='#fff' size={22} containerStyle={styles.deleteAttachment} onPress={() => this.deleteAttachment()} testID="AttachmentDeleteButton" />
</View>}
<CaptureTabs onSelectedMedia={this.onAttachedMedia} />
</React.Fragment>
......
......@@ -361,7 +361,7 @@ export default class CapturePosterFlags extends Component {
}
renderNsfw() {
if (GOOGLE_PLAY_STORE || Platform.OS === 'ios') return null;
//if (GOOGLE_PLAY_STORE || Platform.OS === 'ios') return null;
return (
<NsfwToggle
containerStyle={styles.cell}
......
......@@ -337,7 +337,7 @@ class CommentList extends React.Component<PropsType, StateType> {
return (
<View>
<View style={[CS.rowJustifyCenter, CS.margin, CS.padding, CS.backgroundWhite, CS.borderRadius12x, CS.borderGreyed, CS.borderHair]}>
<View style={[CS.rowJustifyCenter, CS.margin, CS.padding, CS.backgroundWhite, CS.borderRadius12x, CS.borderGreyed, CS.borderHair]} testID={this.props.parent ? 'CommentParentView' : ''}>
<Image source={avatarImg} style={CmpStyle.posterAvatar} />
<TextInput
style={[CS.flexContainer, CS.marginLeft, inputStyle, {paddingVertical: 2}]}
......@@ -352,6 +352,7 @@ class CommentList extends React.Component<PropsType, StateType> {
maxHeight={110}
value={comments.text}
onSelectionChange={this.onSelectionChanges}
testID='CommentText'
/>
{ attachment.uploading ?
<Progress.Pie progress={attachment.progress} size={36} /> :
......@@ -359,7 +360,7 @@ class CommentList extends React.Component<PropsType, StateType> {
<ActivityIndicator size={'large'} /> :
<View style={[CS.rowJustifyEnd, CS.centered]}>
<TouchableOpacity onPress={this.showAttachment} style={CS.paddingRight2x}><Icon name="md-attach" size={24} style={CS.paddingRight2x} /></TouchableOpacity>
<TouchableOpacity onPress={this.postComment} style={CS.paddingRight2x}><Icon name="md-send" size={24} /></TouchableOpacity>
<TouchableOpacity onPress={this.postComment} style={CS.paddingRight2x} testID='PostCommentButton'><Icon name="md-send" size={24} /></TouchableOpacity>
</View>
}
</View>
......
......@@ -49,7 +49,7 @@ export default class ReplyAction extends Component {
const textStyle = {color};
return (
<TouchableOpacityCustom style={[CommonStyle.flexContainer, CommonStyle.centered, CommonStyle.paddingRight2x, this.props.orientation == 'column' ? CommonStyle.columnAlignCenter : CommonStyle.rowJustifyCenter ]} onPress={this.toggleExpand}>
<TouchableOpacityCustom style={[CommonStyle.flexContainer, CommonStyle.centered, CommonStyle.paddingRight2x, this.props.orientation == 'column' ? CommonStyle.columnAlignCenter : CommonStyle.rowJustifyCenter ]} onPress={this.toggleExpand} testID='ReplyCommentButton'>
<Icon color={color} name={this.iconName} size={this.props.size} />
<Text style={textStyle}>{i18n.t('reply')}</Text>
<Counter size={this.props.size * 0.75} count={entity.replies_count} orientation={this.props.orientation}/>
......
......@@ -42,6 +42,7 @@ export default class NavNextButton extends Component {
style.button,
this.props.style,
]}
testID="NavNextButton"
>
<View style={style.row}>
{submitContent}
......
......@@ -50,6 +50,7 @@ export default class SearchView extends PureComponent {
'transparent'
}
style={styles.input}
testID="MessengerContactText"
/>
{rIcon}
</View>
......
......@@ -58,7 +58,7 @@ export default class NsfwToggle extends Component {
render() {
const isActive = Boolean(this.props.value && this.props.value.length);
const button = (
<Touchable style={this.props.containerStyle} onPress={this.showDropdown} {...testID('NSFW button')}>
<Touchable style={this.props.containerStyle} onPress={this.showDropdown} testID="NsfwToggle">
<MdIcon
name="explicit"
color={isActive ? Colors.explicit : Colors.darkGreyed}
......@@ -80,7 +80,7 @@ export default class NsfwToggle extends Component {
key={i}
onPress={() => this.toggleDropdownOption(reason)}
textStyle={[styles.menuItemText, this.isReasonActive(reason) && styles.menuItemTextActive]}
{...testID(`NSFW ${reason.label}`)}
testID={`NsfwReason${reason.label}`}
>{this.isReasonActive(reason) && <MdIcon name="check" />} {reason.label}</MenuItem>
))}
</Menu>
......
......@@ -210,8 +210,9 @@ export default class ConversationScreen extends Component {
autogrow={true}
maxHeight={110}
value={this.state.text}
testID='ConversationTextInput'
/>
<TouchableOpacity onPress={this.send} style={styles.sendicon}><Icon name="md-send" size={24} style={{ color: '#444' }}/></TouchableOpacity>
<TouchableOpacity onPress={this.send} style={styles.sendicon} testID='ConversationSendButton'><Icon name="md-send" size={24} style={{ color: '#444' }}/></TouchableOpacity>
</View>
</KeyboardAvoidingView>
);
......
......@@ -158,6 +158,7 @@ export default class MessengerScreen extends Component {
refreshing={messengerList.refreshing}
style={styles.listView}
ListEmptyComponent={empty}
testID="MessengerList"
/>
</View>
);
......@@ -210,6 +211,7 @@ export default class MessengerScreen extends Component {
item={row.item}
styles={styles}
navigation={this.props.navigation}
testID={row.item.username.toUpperCase()}
/>
);
}
......
......@@ -112,6 +112,7 @@ export default class MessengerSetup extends Component {
placeholder={i18n.t('passwordPlaceholder')}
secureTextEntry={true}
onChangeText={(password) => this.password = password}
testID="MessengerSetupText"
/>
</View>
......
......@@ -44,7 +44,7 @@ export default class ConversationView extends Component {
}
return (
<TouchableOpacity style={styles.row} onPress={this._navToConversation}>
<TouchableOpacity style={styles.row} onPress={this._navToConversation} testID={this.props.testID}>
<Image source={avatarImg} style={styles.avatar} />
<Text style={styles.body}>{item.username.toUpperCase()}</Text>
{unread}
......
......@@ -115,7 +115,7 @@ export default class NewsfeedScreen extends Component {
header={header}
navigation={this.props.navigation}
/>
<CaptureFab navigation={this.props.navigation}/>
<CaptureFab navigation={this.props.navigation} testID="captureFab"/>
</View>
);
}
......@@ -127,7 +127,7 @@ export default class NewsfeedScreen extends Component {
header={header}
navigation={this.props.navigation}
/>
<CaptureFab navigation={this.props.navigation}/>
<CaptureFab navigation={this.props.navigation} testID="captureFab"/>
</View>
);
}
......
......@@ -37,7 +37,7 @@ export default class Actions extends PureComponent {
<ThumbUpAction entity={entity} me={this.props.user.me}/>
<ThumbDownAction entity={entity} me={this.props.user.me}/>
{!isOwner && hasCrypto && <WireAction owner={entity.ownerObj} navigation={this.props.navigation}/>}
<CommentsAction entity={entity} navigation={this.props.navigation}/>
<CommentsAction entity={entity} navigation={this.props.navigation} testID={this.props.entity.text==='e2eTest' ? 'ActivityCommentButton' : ''}/>
<RemindAction entity={entity} navigation={this.props.navigation}/>
{isOwner && hasCrypto && !isScheduled && <BoostAction entity={entity} navigation={this.props.navigation}/>}
</View> }
......
......@@ -179,6 +179,7 @@ export default class Activity extends Component {
entity={this.props.entity}
navigation={this.props.navigation}
onTranslate={this.showTranslate}
testID={this.props.entity.text==='e2eTest' ? 'ActivityMoreButton' : ''}
/>
</View>
)
......@@ -219,6 +220,7 @@ export default class Activity extends Component {
entity={this.props.entity}
navigation={this.props.navigation}
onTranslate={this.showTranslate}
testID={this.props.entity.text==='e2eTest' ? 'ActivityMoreButton' : ''}
/>}
</View>
</View>
......
......@@ -38,7 +38,7 @@ export default class ActivityActionSheet extends Component {
*/
constructor(props) {
super(props);
this.deleteOption = <Text style={[CS.colorDanger, CS.fontXL]}>{i18n.t('delete')}</Text>
this.deleteOption = <Text testID='deleteOption' style={[CS.colorDanger, CS.fontXL]}>{i18n.t('delete')}</Text>
}
/**
......@@ -310,7 +310,7 @@ export default class ActivityActionSheet extends Component {
onPress={() => this.showActionSheet()}
size={26}
style={CS.colorDarkGreyed}
{...testID('Activity Menu button')}
testID={this.props.testID}
/>
<ActionSheet
ref={o => this.ActionSheet = o}
......
......@@ -39,7 +39,7 @@ class CommentsAction extends Component {
const color = canComment ? (this.props.entity['comments:count'] > 0 ? CS.colorPrimary : CS.colorAction) : CS.colorLightGreyed;
return (
<TouchableOpacityCustom style={[CS.flexContainer, CS.centered, CS.rowJustifyCenter]} onPress={this.openComments}>
<TouchableOpacityCustom style={[CS.flexContainer, CS.centered, CS.rowJustifyCenter]} onPress={this.openComments} testID={this.props.testID}>
<Icon style={[color, CS.marginRight]} name={icon} size={this.props.size} />
<Counter size={this.props.size * 0.70} count={this.props.entity['comments:count']} />
</TouchableOpacityCustom>
......
......@@ -43,7 +43,7 @@ let screens = {
Messenger: {
screen: withErrorBoundaryScreen(MessengerScreen),
navigationOptions: {
tabBarTestID:'Messenger tab button',
tabBarTestID:'MessengerTabButton',
tabBarAccessibilityLabel: 'Messenger tab button',
},
},
......