Add detox tests

This commit is contained in:
Danish 2022-08-25 00:39:54 +05:30
parent 83f0edefcc
commit 8390a4c582
6 changed files with 130 additions and 56 deletions

View File

@ -39,7 +39,7 @@ const EmojiCategory = ({ baseUrl, onEmojiSelected, emojis, width, tabsCount }: I
<Pressable
key={typeof emoji === 'string' ? emoji : emoji.content}
onPress={() => onEmojiSelected(emoji)}
testID={`reaction-picker-${typeof emoji === 'string' ? emoji : emoji.content}`}
testID={`emoji-${typeof emoji === 'string' ? emoji : emoji.content}`}
android_ripple={{ color: colors.bannerBackground, borderless: true, radius: emojiSize / 2 }}
style={({ pressed }: { pressed: boolean }) => ({
backgroundColor: isIOS && pressed ? colors.bannerBackground : 'transparent'

View File

@ -15,11 +15,18 @@ const Footer = ({ onSearchPressed, onBackspacePressed }: IFooterProps): React.Re
<Pressable
onPress={onSearchPressed}
hitSlop={BUTTON_HIT_SLOP}
style={({ pressed }) => [[styles.footerButtonsContainer, { opacity: pressed ? 0.7 : 1 }]]}>
style={({ pressed }) => [[styles.footerButtonsContainer, { opacity: pressed ? 0.7 : 1 }]]}
testID='emoji-picker-search'
>
<CustomIcon color={colors.auxiliaryTintColor} size={24} name='search' />
</Pressable>
<Pressable onPress={onBackspacePressed} hitSlop={BUTTON_HIT_SLOP} style={({ pressed }) => [{ opacity: pressed ? 0.7 : 1 }]}>
<Pressable
onPress={onBackspacePressed}
hitSlop={BUTTON_HIT_SLOP}
style={({ pressed }) => [{ opacity: pressed ? 0.7 : 1 }]}
testID='emoji-picker-backspace'
>
<CustomIcon color={colors.auxiliaryTintColor} size={24} name='backspace' />
</Pressable>
</View>

View File

@ -16,14 +16,15 @@ const TabBar = ({ activeTab, tabs, goToPage }: ITabBarProps): React.ReactElement
<Pressable
key={tab}
onPress={() => goToPage?.(i)}
testID={`reaction-picker-${tab}`}
testID={`emoji-picker-tab-${tab}`}
android_ripple={{ color: colors.bannerBackground }}
style={({ pressed }: { pressed: boolean }) => [
styles.tab,
{
backgroundColor: isIOS && pressed ? colors.bannerBackground : 'transparent'
}
]}>
]}
>
<CustomIcon name={tab} size={24} color={activeTab === i ? colors.tintColor : colors.auxiliaryTintColor} />
<View style={activeTab === i ? [styles.activeTabLine, { backgroundColor: colors.tintColor }] : styles.tabLine} />
</Pressable>

View File

@ -43,7 +43,7 @@ const Emoji = ({ emoji, baseUrl }: { emoji: IEmoji | string; baseUrl: string }):
const ListItem = ({ emoji, onEmojiSelected, baseUrl }: IListItem): React.ReactElement => {
const key = typeof emoji === 'string' ? emoji : emoji?.name || emoji?.content;
return (
<View style={[styles.emojiContainer]} key={key}>
<View style={[styles.emojiContainer]} key={key} testID={`searched-emoji-${key}`}>
<Pressable onPress={() => onEmojiSelected(emoji)}>
<Emoji emoji={emoji} baseUrl={baseUrl} />
</Pressable>
@ -83,7 +83,7 @@ const EmojiSearchBar = React.forwardRef<TextInput, IEmojiSearchBarProps>(
renderItem={({ item }) => <ListItem emoji={item} onEmojiSelected={onEmojiSelected} baseUrl={baseUrl} />}
showsHorizontalScrollIndicator={false}
ListEmptyComponent={() => (
<View style={styles.listEmptyComponent}>
<View style={styles.listEmptyComponent} testID='no-results-found'>
<Text style={{ color: colors.auxiliaryText }}>{I18n.t('No_results_found')}</Text>
</View>
)}
@ -97,6 +97,7 @@ const EmojiSearchBar = React.forwardRef<TextInput, IEmojiSearchBarProps>(
style={({ pressed }: { pressed: boolean }) => [styles.openEmojiKeyboard, { opacity: pressed ? 0.7 : 1 }]}
onPress={openEmoji}
hitSlop={BUTTON_HIT_SLOP}
testID='openback-emoji-keyboard'
>
<CustomIcon name='chevron-left' size={30} color={colors.collapsibleChevron} />
</Pressable>
@ -115,6 +116,7 @@ const EmojiSearchBar = React.forwardRef<TextInput, IEmojiSearchBarProps>(
value={searchText}
onClearInput={() => handleTextChange('')}
iconRight={'search'}
testID='emoji-searchbar-input'
/>
</View>
</View>

View File

@ -87,6 +87,7 @@ const ReactionPicker = ({ onEmojiSelected, message, reactionClose }: IReactionPi
value={searchText}
onClearInput={() => handleTextChange('')}
iconRight={'search'}
testID='reaction-picker-searchbar'
/>
</View>
<EmojiPicker onItemClicked={handleEmojiSelect} searching={searching} searchedEmojis={searchedEmojis} />

View File

@ -60,9 +60,7 @@ describe('Room screen', () => {
});
it('should have open emoji button', async () => {
if (device.getPlatform() === 'android') {
await expect(element(by.id('messagebox-open-emoji'))).toExist();
}
});
it('should have message input', async () => {
@ -87,7 +85,6 @@ describe('Room screen', () => {
});
it('should show/hide emoji keyboard', async () => {
if (device.getPlatform() === 'android') {
await element(by.id('messagebox-open-emoji')).tap();
await waitFor(element(by.id('messagebox-keyboard-emoji')))
.toExist()
@ -96,14 +93,69 @@ describe('Room screen', () => {
await expect(element(by.id('messagebox-open-emoji'))).toBeNotVisible();
await element(by.id('messagebox-close-emoji')).tap();
await waitFor(element(by.id('messagebox-keyboard-emoji')))
.toBeNotVisible()
.not.toBeVisible()
.withTimeout(10000);
await expect(element(by.id('messagebox-close-emoji'))).toBeNotVisible();
await expect(element(by.id('messagebox-open-emoji'))).toExist();
}
});
it('should clear the emoji', async () => {
await element(by.id('messagebox-open-emoji')).tap();
await waitFor(element(by.id('messagebox-keyboard-emoji')))
.toExist()
.withTimeout(10000);
await expect(element(by.id('emoji-picker-tab-emoji'))).toExist();
await element(by.id('emoji-picker-tab-emoji')).tap();
await expect(element(by.id('emoji-smiley'))).toExist();
await element(by.id('emoji-smiley')).tap();
await waitFor(element(by.id('emoji-picker-backspace')))
.toExist()
.withTimeout(4000);
await expect(element(by.id('messagebox-input'))).toHaveText('😃');
await expect(element(by.id('emoji-picker-backspace'))).toExist();
await element(by.id('emoji-picker-backspace')).tap();
await expect(element(by.id('messagebox-input'))).toHaveText('');
await element(by.id('messagebox-close-emoji')).tap();
await waitFor(element(by.id('messagebox-keyboard-emoji')))
.not.toBeVisible()
.withTimeout(10000);
});
it('should search emojis, go back to EmojiKeyboard and then close the EmojiKeyboard', async () => {
await element(by.id('messagebox-open-emoji')).tap();
await waitFor(element(by.id('emoji-picker-search')))
.toExist()
.withTimeout(4000);
await element(by.id('emoji-picker-search')).tap();
await waitFor(element(by.id('emoji-searchbar-input')))
.toExist()
.withTimeout(2000);
await element(by.id('emoji-searchbar-input')).typeText('smiley');
await waitFor(element(by.id('searched-emoji-smiley')))
.toExist()
.withTimeout(2000);
await element(by.id('searched-emoji-smiley')).tap();
await expect(element(by.id('messagebox-input'))).toHaveText('😃');
await element(by.id('emoji-searchbar-input')).clearText();
await element(by.id('emoji-searchbar-input')).typeText('random-text');
await waitFor(element(by.id('no-results-found')))
.toExist()
.withTimeout(2000);
await element(by.id('emoji-searchbar-input')).clearText();
await expect(element(by.id('openback-emoji-keyboard'))).toExist();
await element(by.id('openback-emoji-keyboard')).tap();
await waitFor(element(by.id('emoji-searchbar-input')))
.not.toBeVisible()
.withTimeout(2000);
await expect(element(by.id('messagebox-close-emoji'))).toExist();
await element(by.id('messagebox-close-emoji')).tap();
await waitFor(element(by.id('messagebox-keyboard-emoji')))
.not.toBeVisible()
.withTimeout(10000);
});
it('should show/hide emoji autocomplete', async () => {
await element(by.id('messagebox-input')).clearText();
await element(by.id('messagebox-input')).typeText(':joy');
await sleep(300);
await waitFor(element(by.id('messagebox-container')))
@ -220,10 +272,8 @@ describe('Room screen', () => {
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
await element(by[textMatcher]('Permalink')).atIndex(0).tap();
// TODO: test clipboard
});
it('should copy message', async () => {
await element(by[textMatcher](`${data.random}message`))
.atIndex(0)
@ -234,13 +284,10 @@ describe('Room screen', () => {
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
await element(by[textMatcher]('Copy')).atIndex(0).tap();
// TODO: test clipboard
});
it('should star message', async () => {
await starMessage('message');
await sleep(1000); // https://github.com/RocketChat/Rocket.Chat.ReactNative/issues/2324
await element(by[textMatcher](`${data.random}message`))
.atIndex(0)
@ -255,7 +302,6 @@ describe('Room screen', () => {
.withTimeout(6000);
await element(by.id('action-sheet-handle')).swipe('down', 'fast', 0.8);
});
it('should react to message', async () => {
await waitFor(element(by[textMatcher](`${data.random}message`)))
.toExist()
@ -272,19 +318,41 @@ describe('Room screen', () => {
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
await element(by.id('add-reaction')).tap();
await waitFor(element(by.id('reaction-picker')))
.toBeVisible()
await waitFor(element(by.id('emoji-picker-tab-emoji')))
.toExist()
.withTimeout(2000);
await element(by.id('reaction-picker-😃')).tap();
await waitFor(element(by.id('reaction-picker-grinning')))
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 1);
await element(by.id('emoji-picker-tab-emoji')).tap();
await waitFor(element(by.id('emoji-grinning')))
.toExist()
.withTimeout(10000);
await element(by.id('reaction-picker-grinning')).tap();
await element(by.id('emoji-grinning')).tap();
await waitFor(element(by.id('message-reaction-:grinning:')))
.toExist()
.withTimeout(60000);
});
it('should search emojis in the reaction picker and react', async () => {
await element(by[textMatcher](`${data.random}message`))
.atIndex(0)
.longPress();
await waitFor(element(by.id('action-sheet')))
.toExist()
.withTimeout(2000);
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
await element(by.id('add-reaction')).tap();
await waitFor(element(by.id('reaction-picker-searchbar')))
.toExist()
.withTimeout(2000);
await element(by.id('reaction-picker-searchbar')).typeText('smile');
await waitFor(element(by.id('emoji-smile')))
.toExist()
.withTimeout(4000);
await element(by.id('emoji-smile')).tap();
await waitFor(element(by.id('message-reaction-:smile:')))
.toExist()
.withTimeout(60000);
});
it('should react to message with frequently used emoji', async () => {
await element(by[textMatcher](`${data.random}message`))
.atIndex(0)
@ -302,36 +370,37 @@ describe('Room screen', () => {
.toBeVisible()
.withTimeout(60000);
});
it('should show reaction picker on add reaction button pressed and have frequently used emoji, and dismiss review nag', async () => {
await element(by.id('message-add-reaction')).tap();
await waitFor(element(by.id('reaction-picker')))
await waitFor(element(by.id('action-sheet')))
.toExist()
.withTimeout(2000);
await waitFor(element(by.id('reaction-picker-grinning')))
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 1);
await waitFor(element(by.id('emoji-grinning')))
.toExist()
.withTimeout(4000);
await waitFor(element(by.id('emoji-picker-tab-emoji')))
.toExist()
.withTimeout(2000);
await element(by.id('reaction-picker-😃')).tap();
await waitFor(element(by.id('reaction-picker-grimacing')))
await element(by.id('emoji-picker-tab-emoji')).tap();
await waitFor(element(by.id('emoji-wink')))
.toExist()
.withTimeout(2000);
await element(by.id('reaction-picker-grimacing')).tap();
await waitFor(element(by.id('message-reaction-:grimacing:')))
.withTimeout(10000);
await element(by.id('emoji-wink')).tap();
await waitFor(element(by.id('message-reaction-:wink:')))
.toExist()
.withTimeout(60000);
});
it('should remove reaction', async () => {
await element(by.id('message-reaction-:grinning:')).tap();
await waitFor(element(by.id('message-reaction-:grinning:')))
.toBeNotVisible()
await element(by.id('message-reaction-:smile:')).tap();
await waitFor(element(by.id('message-reaction-:smile:')))
.not.toExist()
.withTimeout(60000);
});
it('should ask for review', async () => {
await dismissReviewNag(); // TODO: Create a proper test for this elsewhere.
});
it('should edit message', async () => {
await mockMessage('edit');
await element(by[textMatcher](`${data.random}edit`))
@ -352,7 +421,6 @@ describe('Room screen', () => {
.toExist()
.withTimeout(60000);
});
it('should quote message', async () => {
await mockMessage('quote');
await element(by[textMatcher](`${data.random}quote`))
@ -369,14 +437,11 @@ describe('Room screen', () => {
.toExist()
.withTimeout(2000);
await element(by.id('messagebox-send-message')).tap();
// TODO: test if quote was sent
});
it('should pin message', async () => {
await mockMessage('pin');
await pinMessage('pin');
await waitFor(element(by[textMatcher](`${data.random}pin`)).atIndex(0))
.toExist()
.withTimeout(5000);
@ -396,7 +461,6 @@ describe('Room screen', () => {
.withTimeout(2000);
await element(by.id('action-sheet-handle')).swipe('down', 'fast', 0.8);
});
it('should delete message', async () => {
await mockMessage('delete');
await waitFor(element(by[textMatcher](`${data.random}delete`)).atIndex(0)).toBeVisible();
@ -412,7 +476,6 @@ describe('Room screen', () => {
.toExist()
.withTimeout(1000);
await element(by[textMatcher]('Delete')).atIndex(0).tap();
const deleteAlertMessage = 'You will not be able to recover this message!';
await waitFor(element(by[textMatcher](deleteAlertMessage)).atIndex(0))
.toExist()