Merge branch 'appium-v2' of github.com:RocketChat/Rocket.Chat.ReactNative into appium-v2

This commit is contained in:
Diego Mello 2022-04-08 15:05:15 -03:00
commit 31a02d3db3
38 changed files with 113 additions and 61 deletions

View File

@ -18,6 +18,7 @@ import { Handle } from './Handle';
import { IActionSheetItem, Item } from './Item';
import { TActionSheetOptions, TActionSheetOptionsItem } from './Provider';
import styles, { ITEM_HEIGHT } from './styles';
import { testProps } from '../../lib/methods/testProps';
const getItemLayout = (data: TActionSheetOptionsItem[] | null | undefined, index: number) => ({
length: ITEM_HEIGHT,
@ -152,7 +153,7 @@ const ActionSheet = React.memo(
<>
<TapGestureHandler onHandlerStateChange={onBackdropPressed}>
<Animated.View
testID='action-sheet-backdrop'
{...testProps('action-sheet-backdrop')}
style={[
styles.backdrop,
{
@ -163,7 +164,7 @@ const ActionSheet = React.memo(
/>
</TapGestureHandler>
<ScrollBottomSheet<TActionSheetOptionsItem>
testID='action-sheet'
{...testProps('action-sheet')}
ref={bottomSheetRef}
componentType='FlatList'
snapPoints={snaps}

View File

@ -4,11 +4,12 @@ import { View } from 'react-native';
import styles from './styles';
import { themes } from '../../lib/constants';
import { useTheme } from '../../theme';
import { testProps } from '../../lib/methods/testProps';
export const Handle = React.memo(() => {
const { theme } = useTheme();
return (
<View style={[styles.handle, { backgroundColor: themes[theme].focusedBackground }]} testID='action-sheet-handle'>
<View style={[styles.handle, { backgroundColor: themes[theme].focusedBackground }]} {...testProps('action-sheet-handle')}>
<View style={[styles.handleIndicator, { backgroundColor: themes[theme].auxiliaryText }]} />
</View>
);

View File

@ -3,6 +3,7 @@ import { Text, View } from 'react-native';
import { themes } from '../../lib/constants';
import { CustomIcon } from '../../lib/Icons';
import { testProps } from '../../lib/methods/testProps';
import { useTheme } from '../../theme';
import { Button } from './Button';
import styles from './styles';
@ -31,7 +32,7 @@ export const Item = React.memo(({ item, hide }: IActionSheetItem) => {
onPress={onPress}
style={[styles.item, { backgroundColor: themes[theme].focusedBackground }]}
theme={theme}
testID={item.testID}>
{...testProps(item.testID || '')}>
<CustomIcon name={item.icon} size={20} color={item.danger ? themes[theme].dangerColor : themes[theme].bodyText} />
<View style={styles.titleContainer}>
<Text

View File

@ -9,6 +9,7 @@ import { SubscriptionType } from '../../definitions/ISubscription';
import Emoji from '../markdown/Emoji';
import { IAvatar } from './interfaces';
import { useTheme } from '../../theme';
import { testProps } from '../../lib/methods/testProps';
const Avatar = React.memo(
({
@ -88,7 +89,7 @@ const Avatar = React.memo(
}
return (
<View style={[avatarStyle, style]} testID='avatar'>
<View style={[avatarStyle, style]} {...testProps('avatar')}>
{image}
{children}
</View>

View File

@ -3,6 +3,7 @@ import { ButtonProps, StyleSheet, Text } from 'react-native';
import Touchable from 'react-native-platform-touchable';
import { themes } from '../../lib/constants';
import { testProps } from '../../lib/methods/testProps';
import sharedStyles from '../../views/Styles';
import ActivityIndicator from '../ActivityIndicator';
@ -49,8 +50,21 @@ export default class Button extends React.PureComponent<Partial<IButtonProps>, a
};
render() {
const { title, type, onPress, disabled, backgroundColor, color, loading, style, theme, fontSize, styleText, ...otherProps } =
this.props;
const {
title,
type,
onPress,
disabled,
backgroundColor,
color,
loading,
style,
theme,
fontSize,
styleText,
testID,
...otherProps
} = this.props;
const isPrimary = type === 'primary';
let textColor = isPrimary ? themes[theme!].buttonText : themes[theme!].bodyText;
@ -70,8 +84,8 @@ export default class Button extends React.PureComponent<Partial<IButtonProps>, a
disabled && styles.disabled,
style
]}
accessibilityLabel={title}
{...otherProps}>
{...otherProps}
{...testProps((testID || title) as string)}>
{loading ? (
<ActivityIndicator color={textColor} />
) : (

View File

@ -7,6 +7,7 @@ import RoomTypeIcon from '../RoomTypeIcon';
import styles, { ROW_HEIGHT } from './styles';
import { themes } from '../../lib/constants';
import { useTheme } from '../../theme';
import { testProps } from '../../lib/methods/testProps';
export { ROW_HEIGHT };
@ -49,7 +50,7 @@ const DirectoryItem = ({
}: IDirectoryItem): React.ReactElement => {
const { theme } = useTheme();
return (
<Touch onPress={onPress} style={{ backgroundColor: themes[theme].backgroundColor }} testID={testID} theme={theme}>
<Touch onPress={onPress} style={{ backgroundColor: themes[theme].backgroundColor }} {...testProps(testID)} theme={theme}>
<View style={[styles.directoryItemContainer, styles.directoryItemButton, style]}>
<Avatar text={avatar} size={30} type={type} rid={rid} style={styles.directoryItemAvatar} />
<View style={styles.directoryItemTextContainer}>

View File

@ -6,6 +6,7 @@ import styles from './styles';
import CustomEmoji from './CustomEmoji';
import scrollPersistTaps from '../../utils/scrollPersistTaps';
import { IEmoji, IEmojiCategory } from '../../definitions/IEmoji';
import { testProps } from '../../lib/methods/testProps';
const EMOJI_SIZE = 50;
@ -34,7 +35,7 @@ class EmojiCategory extends React.Component<Partial<IEmojiCategory>> {
activeOpacity={0.7}
key={emoji && emoji.isCustom ? emoji.content : emoji}
onPress={() => onEmojiSelected!(emoji)}
testID={`reaction-picker-${emoji && emoji.isCustom ? emoji.content : emoji}`}>
{...testProps(`reaction-picker-${emoji && emoji.isCustom ? emoji.content : emoji}`)}>
{renderEmoji(emoji, EMOJI_SIZE, baseUrl!)}
</TouchableOpacity>
);

View File

@ -3,6 +3,7 @@ import { Text, TouchableOpacity, View } from 'react-native';
import styles from './styles';
import { themes } from '../../lib/constants';
import { testProps } from '../../lib/methods/testProps';
interface ITabBarProps {
goToPage: Function;
@ -35,7 +36,7 @@ export default class TabBar extends React.Component<Partial<ITabBarProps>> {
key={tab}
onPress={() => goToPage!(i)}
style={styles.tab}
testID={`reaction-picker-${tab}`}>
{...testProps(`reaction-picker-${tab}`)}>
<Text style={[styles.tabEmoji, tabEmojiStyle]}>{tab}</Text>
{activeTab === i ? (
<View style={[styles.activeTabLine, { backgroundColor: themes[theme!].tintColor }]} />

View File

@ -10,6 +10,7 @@ import StatusBar from './StatusBar';
import AppVersion from './AppVersion';
import { isTablet } from '../utils/deviceInfo';
import SafeAreaView from './SafeAreaView';
import { testProps } from '../lib/methods/testProps';
interface IFormContainer extends ScrollViewProps {
testID: string;
@ -40,7 +41,7 @@ const FormContainer = ({ children, testID, ...props }: IFormContainer) => {
contentContainerStyle={[sharedStyles.containerScrollView, styles.scrollView]}
{...scrollPersistTaps}
{...props}>
<SafeAreaView testID={testID} style={{ backgroundColor: themes[theme].backgroundColor }}>
<SafeAreaView {...testProps(testID)} style={{ backgroundColor: themes[theme].backgroundColor }}>
{children}
<AppVersion theme={theme} />
</SafeAreaView>

View File

@ -4,6 +4,7 @@ import { isIOS } from '../../utils/deviceInfo';
import I18n from '../../i18n';
import Container from './HeaderButtonContainer';
import Item from './HeaderButtonItem';
import { testProps } from '../../lib/methods/testProps';
interface IHeaderButtonCommon {
navigation?: any; // TODO: Evaluate proper type
@ -15,7 +16,7 @@ interface IHeaderButtonCommon {
export const Drawer = React.memo(
({ navigation, testID, onPress = () => navigation?.toggleDrawer(), ...props }: IHeaderButtonCommon) => (
<Container left>
<Item iconName='hamburguer' onPress={onPress} testID={testID} {...props} />
<Item iconName='hamburguer' onPress={onPress} {...testProps(testID as string as string)} {...props} />
</Container>
)
);
@ -23,7 +24,7 @@ export const Drawer = React.memo(
export const CloseModal = React.memo(
({ navigation, testID, onPress = () => navigation?.pop(), ...props }: IHeaderButtonCommon) => (
<Container left>
<Item iconName='close' onPress={onPress} testID={testID} {...props} />
<Item iconName='close' onPress={onPress} {...testProps(testID as string)} {...props} />
</Container>
)
);
@ -31,9 +32,9 @@ export const CloseModal = React.memo(
export const CancelModal = React.memo(({ onPress, testID }: Partial<IHeaderButtonCommon>) => (
<Container left>
{isIOS ? (
<Item title={I18n.t('Cancel')} onPress={onPress} testID={testID} />
<Item title={I18n.t('Cancel')} onPress={onPress} {...testProps(testID as string)} />
) : (
<Item iconName='close' onPress={onPress} testID={testID} />
<Item iconName='close' onPress={onPress} {...testProps(testID as string)} />
)}
</Container>
));
@ -41,24 +42,24 @@ export const CancelModal = React.memo(({ onPress, testID }: Partial<IHeaderButto
// Right
export const More = React.memo(({ onPress, testID }: Partial<IHeaderButtonCommon>) => (
<Container>
<Item iconName='kebab' onPress={onPress} testID={testID} />
<Item iconName='kebab' onPress={onPress} {...testProps(testID as string)} />
</Container>
));
export const Download = React.memo(({ onPress, testID, ...props }: IHeaderButtonCommon) => (
<Container>
<Item iconName='download' onPress={onPress} testID={testID} {...props} />
<Item iconName='download' onPress={onPress} {...testProps(testID as string)} {...props} />
</Container>
));
export const Preferences = React.memo(({ onPress, testID, ...props }: IHeaderButtonCommon) => (
<Container>
<Item iconName='settings' onPress={onPress} testID={testID} {...props} />
<Item iconName='settings' onPress={onPress} {...testProps(testID as string)} {...props} />
</Container>
));
export const Legal = React.memo(
({ navigation, testID, onPress = () => navigation?.navigate('LegalView') }: IHeaderButtonCommon) => (
<More onPress={onPress} testID={testID} />
<More onPress={onPress} {...testProps(testID as string)} />
)
);

View File

@ -6,6 +6,7 @@ import { CustomIcon } from '../../lib/Icons';
import { useTheme } from '../../theme';
import { themes } from '../../lib/constants';
import sharedStyles from '../../views/Styles';
import { testProps } from '../../lib/methods/testProps';
interface IHeaderButtonItem {
title?: string;
@ -42,7 +43,7 @@ const styles = StyleSheet.create({
const Item = ({ title, iconName, onPress, testID, badge }: IHeaderButtonItem): React.ReactElement => {
const { theme } = useTheme();
return (
<Touchable onPress={onPress} testID={testID} hitSlop={BUTTON_HIT_SLOP} style={styles.container}>
<Touchable onPress={onPress} {...testProps(testID as string)} hitSlop={BUTTON_HIT_SLOP} style={styles.container}>
<>
{iconName ? (
<CustomIcon name={iconName} size={24} color={themes[theme].headerTintColor} />

View File

@ -1,6 +1,7 @@
import React from 'react';
import { ScrollView, StyleSheet } from 'react-native';
import { testProps } from '../../lib/methods/testProps';
import { withTheme } from '../../theme';
import scrollPersistTaps from '../../utils/scrollPersistTaps';
@ -19,7 +20,8 @@ const ListContainer = React.memo(({ children, ...props }: IListContainer) => (
contentContainerStyle={styles.container}
scrollIndicatorInsets={{ right: 1 }} // https://github.com/facebook/react-native/issues/26610#issuecomment-539843444
{...scrollPersistTaps}
{...props}>
{...props}
{...testProps(props.testID || '')}>
{children}
</ScrollView>
));

View File

@ -3,6 +3,7 @@ import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
import { themes } from '../../lib/constants';
import { CustomIcon } from '../../lib/Icons';
import { testProps } from '../../lib/methods/testProps';
import { useTheme } from '../../theme';
import { ICON_SIZE } from './constants';
@ -25,7 +26,7 @@ const ListIcon = React.memo(({ name, color, style, testID }: IListIcon) => {
return (
<View style={[styles.icon, style]}>
<CustomIcon name={name} color={color ?? themes[theme].auxiliaryText} size={ICON_SIZE} testID={testID} />
<CustomIcon name={name} color={color ?? themes[theme].auxiliaryText} size={ICON_SIZE} {...testProps(testID || '')} />
</View>
);
});

View File

@ -10,6 +10,7 @@ import { Icon } from '.';
import { BASE_HEIGHT, ICON_SIZE, PADDING_HORIZONTAL } from './constants';
import { useDimensions } from '../../dimensions';
import { CustomIcon } from '../../lib/Icons';
import { testProps } from '../../lib/methods/testProps';
const styles = StyleSheet.create({
container: {
@ -86,7 +87,9 @@ const Content = React.memo(
const { fontScale } = useDimensions();
return (
<View style={[styles.container, disabled && styles.disabled, { height: BASE_HEIGHT * fontScale }]} testID={testID}>
<View
style={[styles.container, disabled && styles.disabled, { height: BASE_HEIGHT * fontScale }]}
{...testProps(testID || '')}>
{left ? <View style={styles.leftContainer}>{left()}</View> : null}
<View style={styles.textContainer}>
<View style={styles.textAlertContainer}>

View File

@ -3,6 +3,7 @@ import { Animated, Modal, StyleSheet, View } from 'react-native';
import { withTheme } from '../theme';
import { themes } from '../lib/constants';
import { testProps } from '../lib/methods/testProps';
const styles = StyleSheet.create({
container: {
@ -108,7 +109,7 @@ class Loading extends React.PureComponent<ILoadingProps, ILoadingState> {
return (
<Modal visible={visible} transparent onRequestClose={() => {}}>
<View style={styles.container} testID='loading'>
<View style={styles.container} {...testProps('loading')}>
<Animated.View
style={[
{

View File

@ -13,6 +13,7 @@ import sharedStyles from '../../views/Styles';
import { TFrequentlyUsedEmojiModel } from '../../definitions/IFrequentlyUsedEmoji';
import { TAnyMessageModel } from '../../definitions';
import { IEmoji } from '../../definitions/IEmoji';
import { testProps } from '../../lib/methods/testProps';
type TItem = TFrequentlyUsedEmojiModel | string;
@ -78,7 +79,7 @@ const HeaderItem = ({ item, onReaction, server, theme }: THeaderItem) => {
const emoji = (emojiModel.id ? emojiModel.content : item) as string;
return (
<Button
testID={`message-actions-emoji-${emoji}`}
{...testProps(`message-actions-emoji-${emoji}`)}
onPress={() => onReaction({ emoji: `:${emoji}:` })}
style={[styles.headerItem, { backgroundColor: themes[theme].auxiliaryBackground }]}
theme={theme}>
@ -93,7 +94,7 @@ const HeaderItem = ({ item, onReaction, server, theme }: THeaderItem) => {
const HeaderFooter = ({ onReaction, theme }: THeaderFooter) => (
<Button
testID='add-reaction'
{...testProps('add-reaction')}
onPress={onReaction}
style={[styles.headerItem, { backgroundColor: themes[theme].auxiliaryBackground }]}
theme={theme}>

View File

@ -4,6 +4,7 @@ import { TouchableOpacity } from 'react-native';
import { themes } from '../../../lib/constants';
import { CustomIcon } from '../../../lib/Icons';
import { testProps } from '../../../lib/methods/testProps';
import { useTheme } from '../../../theme';
import ActivityIndicator from '../../ActivityIndicator';
import MessageboxContext from '../Context';
@ -27,7 +28,7 @@ const Item = ({ item }: IMessageBoxCommandsPreviewItem) => {
<TouchableOpacity
style={styles.commandPreview}
onPress={() => onPressCommandPreview(item)}
testID={`command-preview-item${item.id}`}>
{...testProps(`command-preview-item${item.id}`)}>
{item.type === 'image' ? (
<FastImage
style={styles.commandPreviewImage}

View File

@ -7,6 +7,7 @@ import { IPreviewItem } from '../../../definitions';
import { useTheme } from '../../../theme';
import styles from '../styles';
import Item from './Item';
import { testProps } from '../../../lib/methods/testProps';
interface IMessageBoxCommandsPreview {
commandPreview: IPreviewItem[];
@ -21,7 +22,7 @@ const CommandsPreview = React.memo(
const { theme } = useTheme();
return (
<FlatList
testID='commandbox-container'
{...testProps('commandbox-container')}
style={[styles.mentionList, { backgroundColor: themes[theme].messageboxBackground }]}
data={commandPreview}
renderItem={({ item }) => <Item item={item} />}

View File

@ -8,6 +8,7 @@ import styles from './styles';
import { themes } from '../../lib/constants';
import { withTheme } from '../../theme';
import { IEmoji } from '../../definitions/IEmoji';
import { testProps } from '../../lib/methods/testProps';
interface IMessageBoxEmojiKeyboard {
theme: string;
@ -31,7 +32,7 @@ export default class EmojiKeyboard extends React.PureComponent<IMessageBoxEmojiK
return (
<View
style={[styles.emojiKeyboardContainer, { borderTopColor: themes[theme].borderColor }]}
testID='messagebox-keyboard-emoji'>
{...testProps('messagebox-keyboard-emoji')}>
<EmojiPicker onEmojiSelected={this.onEmojiSelected} baseUrl={this.baseUrl} />
</View>
);

View File

@ -10,6 +10,7 @@ import MessageboxContext from '../Context';
import styles from '../styles';
import FixedMentionItem from './FixedMentionItem';
import MentionEmoji from './MentionEmoji';
import { testProps } from '../../../lib/methods/testProps';
interface IMessageBoxMentionItem {
item: {
@ -95,7 +96,7 @@ const MentionItem = ({ item, trackingType }: IMessageBoxMentionItem) => {
}
]}
onPress={() => onPressMention(item)}
testID={testID}>
{...testProps(testID)}>
<MentionItemContent item={item} trackingType={trackingType} />
</TouchableOpacity>
);

View File

@ -7,6 +7,7 @@ import styles from '../styles';
import MentionItem from './MentionItem';
import { themes } from '../../../lib/constants';
import { useTheme } from '../../../theme';
import { testProps } from '../../../lib/methods/testProps';
interface IMessageBoxMentions {
mentions: any[];
@ -21,7 +22,7 @@ const Mentions = React.memo(
}
const { theme } = useTheme();
return (
<View testID='messagebox-container'>
<View {...testProps('messagebox-container')}>
<FlatList
style={[styles.mentionList, { backgroundColor: themes[theme].auxiliaryBackground }]}
ListHeaderComponent={() => (

View File

@ -10,6 +10,7 @@ import I18n from '../../i18n';
import { themes } from '../../lib/constants';
import { CustomIcon } from '../../lib/Icons';
import { events, logEvent } from '../../utils/log';
import { testProps } from '../../lib/methods/testProps';
interface IMessageBoxRecordAudioProps {
theme: string;
@ -197,9 +198,8 @@ export default class RecordAudio extends React.PureComponent<IMessageBoxRecordAu
<BorderlessButton
onPress={this.startRecordingAudio}
style={styles.actionButton}
testID='messagebox-send-audio'
{...testProps('messagebox-send-audio')}
// @ts-ignore
accessibilityLabel={I18n.t('Send_audio_message')}
accessibilityTraits='button'>
<CustomIcon name='microphone' size={24} color={themes[theme].auxiliaryTintColor} />
</BorderlessButton>

View File

@ -2,10 +2,10 @@ import { BorderlessButton } from 'react-native-gesture-handler';
import React from 'react';
import styles from '../styles';
import i18n from '../../../i18n';
import { CustomIcon } from '../../../lib/Icons';
import { useTheme } from '../../../theme';
import { themes } from '../../../lib/constants';
import { testProps } from '../../../lib/methods/testProps';
interface IBaseButton {
onPress(): void;
@ -22,8 +22,8 @@ const BaseButton = ({ accessibilityLabel, icon, color, ...props }: Partial<IBase
{...props}
style={styles.actionButton}
// @ts-ignore
accessibilityLabel={i18n.t(accessibilityLabel)}
accessibilityTraits='button'>
accessibilityTraits='button'
{...testProps(props.testID)}>
<CustomIcon name={icon} size={24} color={color || themes[theme].auxiliaryTintColor} />
</BorderlessButton>
);

View File

@ -52,6 +52,7 @@ import { IMessage } from '../../definitions/IMessage';
import { forceJpgExtension } from './forceJpgExtension';
import { IBaseScreen, IPreviewItem, IUser, TSubscriptionModel, TThreadModel } from '../../definitions';
import { MasterDetailInsideStackParamList } from '../../stacks/MasterDetailStack/types';
import { testProps } from '../../lib/methods/testProps';
if (isAndroid) {
require('./EmojiKeyboard');
@ -1002,7 +1003,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
<TouchableWithoutFeedback
style={[styles.sendToChannelButton, { backgroundColor: themes[theme].messageboxBackground }]}
onPress={this.onPressSendToChannel}
testID='messagebox-send-to-channel'>
{...testProps('messagebox-send-to-channel')}>
<CustomIcon name={tshow ? 'checkbox-checked' : 'checkbox-unchecked'} size={24} color={themes[theme].auxiliaryText} />
<Text style={[styles.sendToChannelText, { color: themes[theme].auxiliaryText }]}>
{I18n.t('Messagebox_Send_to_channel')}
@ -1123,7 +1124,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
{ backgroundColor: themes[theme].messageboxBackground },
!recording && editing && { backgroundColor: themes[theme].chatComponentBackground }
]}
testID='messagebox'>
{...testProps('messagebox')}>
{textInputAndButtons}
{recordAudio}
</View>

View File

@ -8,6 +8,7 @@ import { themes } from '../lib/constants';
import TextInput from '../presentation/TextInput';
import { isIOS, isTablet } from '../utils/deviceInfo';
import { useOrientation } from '../dimensions';
import { testProps } from '../lib/methods/testProps';
const styles = StyleSheet.create({
container: {
@ -40,7 +41,7 @@ const SearchHeader = ({ onSearchChangeText, testID }: ISearchHeaderProps): JSX.E
placeholder={I18n.t('Search')}
onChangeText={onSearchChangeText}
theme={theme}
testID={testID}
{...testProps(testID || '')}
/>
</View>
);

View File

@ -7,6 +7,7 @@ import TextInput from '../presentation/TextInput';
import { themes } from '../lib/constants';
import { CustomIcon } from '../lib/Icons';
import ActivityIndicator from './ActivityIndicator';
import { testProps } from '../lib/methods/testProps';
const styles = StyleSheet.create({
error: {
@ -84,7 +85,7 @@ export default class RCTextInput extends React.PureComponent<IRCTextInputProps,
return (
<CustomIcon
name={iconLeft}
testID={testID ? `${testID}-icon-left` : null}
{...testProps(testID ? `${testID}-icon-left` : '')}
style={[styles.iconContainer, styles.iconLeft, { color: themes[theme].bodyText }]}
size={20}
/>
@ -107,7 +108,7 @@ export default class RCTextInput extends React.PureComponent<IRCTextInputProps,
<Touchable onPress={this.tooglePassword} style={[styles.iconContainer, styles.iconRight]}>
<CustomIcon
name={showPassword ? 'unread-on-top' : 'unread-on-top-disabled'}
testID={testID ? `${testID}-icon-right` : null}
{...testProps(testID ? `${testID}-icon-right` : '')}
style={{ color: themes[theme].auxiliaryText }}
size={20}
/>
@ -170,7 +171,7 @@ export default class RCTextInput extends React.PureComponent<IRCTextInputProps,
autoCapitalize='none'
underlineColorAndroid='transparent'
secureTextEntry={secureTextEntry && !showPassword}
testID={testID}
{...testProps(testID || '')}
accessibilityLabel={placeholder}
placeholder={placeholder}
theme={theme}

View File

@ -8,6 +8,7 @@ import { formatText } from './formatText';
import { useTheme } from '../../theme';
import styles from './styles';
import { formatHyperlink } from './formatHyperlink';
import { testProps } from '../../lib/methods/testProps';
interface IMarkdownPreview {
msg?: string;
@ -35,7 +36,7 @@ const MarkdownPreview = ({ msg, numberOfLines = 1, testID, style = [] }: IMarkdo
accessibilityLabel={m}
style={[styles.text, { color: themes[theme].bodyText }, ...style]}
numberOfLines={numberOfLines}
testID={testID}>
{...testProps(testID)}>
{m}
</Text>
);

View File

@ -10,6 +10,7 @@ import { themes } from '../../lib/constants';
import MessageContext from './Context';
import { IMessageBroadcast } from './interfaces';
import { useTheme } from '../../theme';
import { testProps } from '../../lib/methods/testProps';
const Broadcast = React.memo(({ author, broadcast }: IMessageBroadcast) => {
const { user, replyBroadcast } = useContext(MessageContext);
@ -24,7 +25,7 @@ const Broadcast = React.memo(({ author, broadcast }: IMessageBroadcast) => {
background={Touchable.Ripple(themes[theme].bannerBackground)}
style={[styles.button, { backgroundColor: themes[theme].tintColor }]}
hitSlop={BUTTON_HIT_SLOP}
testID='message-broadcast-reply'>
{...testProps('message-broadcast-reply')}>
<>
<CustomIcon name='arrow-back' size={20} style={styles.buttonIcon} color={themes[theme].buttonText} />
<Text style={[styles.buttonText, { color: themes[theme].buttonText }]}>{I18n.t('Reply')}</Text>

View File

@ -13,6 +13,7 @@ import Markdown from '../../../markdown';
import MessageContext from '../../Context';
import Touchable from '../../Touchable';
import { BUTTON_HIT_SLOP } from '../../utils';
import { testProps } from '../../../../lib/methods/testProps';
const styles = StyleSheet.create({
button: {
@ -90,7 +91,9 @@ const Fields = React.memo(
<>
{attachment.fields.map(field => (
<View key={field.title} style={[styles.fieldContainer, { width: field.short ? '50%' : '100%' }]}>
<Text testID='collapsibleQuoteTouchableFieldTitle' style={[styles.fieldTitle, { color: themes[theme].bodyText }]}>
<Text
{...testProps('collapsibleQuoteTouchableFieldTitle')}
style={[styles.fieldTitle, { color: themes[theme].bodyText }]}>
{field.title}
</Text>
<Markdown
@ -144,7 +147,7 @@ const CollapsibleQuote = React.memo(
return (
<>
<Touchable
testID={`collapsibleQuoteTouchable-${attachment.title}`}
{...testProps(`collapsibleQuoteTouchable-${attachment.title}`)}
onPress={onPress}
style={[
styles.button,

View File

@ -10,6 +10,7 @@ import { themes } from '../../lib/constants';
import { useTheme } from '../../theme';
import MessageContext from './Context';
import { TGetCustomEmoji } from '../../definitions/IEmoji';
import { testProps } from '../../lib/methods/testProps';
interface IReaction {
_id: string;
@ -34,7 +35,7 @@ const AddReaction = React.memo(({ theme }: { theme: string }) => {
<Touchable
onPress={reactionInit}
key='message-add-reaction'
testID='message-add-reaction'
{...testProps('message-add-reaction')}
style={[styles.reactionButton, { backgroundColor: themes[theme].backgroundColor }]}
background={Touchable.Ripple(themes[theme].bannerBackground)}
hitSlop={BUTTON_HIT_SLOP}>
@ -53,7 +54,7 @@ const Reaction = React.memo(({ reaction, getCustomEmoji, theme }: IMessageReacti
onPress={() => onReactionPress(reaction.emoji)}
onLongPress={onReactionLongPress}
key={reaction.emoji}
testID={`message-reaction-${reaction.emoji}`}
{...testProps(`message-reaction-${reaction.emoji}`)}
style={[
styles.reactionButton,
{ backgroundColor: reacted ? themes[theme].bannerBackground : themes[theme].backgroundColor }

View File

@ -8,6 +8,7 @@ import I18n from '../../i18n';
import { MarkdownPreview } from '../markdown';
import { IMessageRepliedThread } from './interfaces';
import { useTheme } from '../../theme';
import { testProps } from '../../lib/methods/testProps';
const RepliedThread = memo(({ tmid, tmsg, isHeader, fetchThreadName, id, isEncrypted }: IMessageRepliedThread) => {
const { theme } = useTheme();
@ -33,7 +34,7 @@ const RepliedThread = memo(({ tmid, tmsg, isHeader, fetchThreadName, id, isEncry
}
return (
<View style={styles.repliedThread} testID={`message-thread-replied-on-${msg}`}>
<View style={styles.repliedThread} {...testProps(`message-thread-replied-on-${msg}`)}>
<CustomIcon name='threads' size={20} style={styles.repliedThreadIcon} color={themes[theme].tintColor} />
<MarkdownPreview msg={msg} style={[styles.repliedThreadName, { color: themes[theme].tintColor }]} />
<View style={styles.repliedThreadDisclosure}>

View File

@ -8,6 +8,7 @@ import ThreadDetails from '../ThreadDetails';
import I18n from '../../i18n';
import { IMessageThread } from './interfaces';
import { useTheme } from '../../theme';
import { testProps } from '../../lib/methods/testProps';
const Thread = React.memo(
({ msg, tcount, tlm, isThreadRoom, id }: IMessageThread) => {
@ -20,7 +21,9 @@ const Thread = React.memo(
const { threadBadgeColor, toggleFollowThread, user, replies } = useContext(MessageContext);
return (
<View style={styles.buttonContainer}>
<View style={[styles.button, { backgroundColor: themes[theme].tintColor }]} testID={`message-thread-button-${msg}`}>
<View
style={[styles.button, { backgroundColor: themes[theme].tintColor }]}
{...testProps(`message-thread-button-${msg}`)}>
<Text style={[styles.buttonText, { color: themes[theme].buttonText }]}>{I18n.t('Reply')}</Text>
</View>
<ThreadDetails

View File

@ -0,0 +1,4 @@
export const testProps = (testID?: string): { testID?: string; accessibilityLabel?: string } => ({
testID,
accessibilityLabel: testID
});

View File

@ -1,4 +0,0 @@
export const withTest = (testID: string): { testID: string; accessibilityLabel: string } => ({
testID,
accessibilityLabel: testID
});

View File

@ -3,6 +3,7 @@ import { I18nManager, StyleProp, StyleSheet, TextInput, TextStyle } from 'react-
import { IRCTextInputProps } from '../containers/TextInput';
import { themes } from '../lib/constants';
import { testProps } from '../lib/methods/testProps';
const styles = StyleSheet.create({
input: {
@ -22,6 +23,7 @@ const ThemedTextInput = React.forwardRef<TextInput, IThemedTextInput>(({ style,
placeholderTextColor={themes[theme].auxiliaryText}
keyboardAppearance={theme === 'light' ? 'light' : 'dark'}
{...props}
{...testProps(props.testID)}
/>
));

View File

@ -7,7 +7,7 @@ import { themes } from '../../../lib/constants';
import I18n from '../../../i18n';
import { TServerHistoryModel } from '../../../definitions/IServerHistory';
import Item from './Item';
import { withTest } from '../../../lib/methods/withTest';
import { testProps } from '../../../lib/methods/testProps';
const styles = StyleSheet.create({
container: {
@ -64,7 +64,7 @@ const ServerInput = ({
theme={theme}
onFocus={() => setFocused(true)}
onBlur={() => setFocused(false)}
{...withTest('new-server-view-input')}
{...testProps('new-server-view-input')}
/>
{focused && serversHistory?.length ? (
<View

View File

@ -1,5 +1,5 @@
module.exports = {
deviceName: 'iPhone 11 Pro',
platformVersion: '14.5',
deviceName: 'iPhone 11 Pro', // pass the udid or device name
platformVersion: '14.5', // pass the platform version
app: 'chat.rocket.reactnative'
};

View File

@ -36,7 +36,7 @@ exports.config = {
// and 30 processes will get spawned. The property handles how many capabilities
// from the same test should run tests.
//
// maxInstances: 10,
maxInstances: 1,
//
// If you have trouble getting all important capabilities together, check out the
// Sauce Labs platform configurator - a great tool to configure your capabilities: