test: add data-testid to all context menu items

pull/3205/head
Audric Ackermann 7 months ago
parent 6c617de892
commit 9ddd50f82c
No known key found for this signature in database

@ -1,5 +1,5 @@
import { MouseEvent, useEffect, useState } from 'react';
import { contextMenu, Item, Menu } from 'react-contexify';
import { contextMenu, Menu } from 'react-contexify';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';
@ -10,6 +10,7 @@ import { getHasOngoingCallWithPubkey } from '../../state/selectors/call';
import { SessionIconButton } from '../icon';
import { DropDownAndToggleButton } from '../icon/DropDownAndToggleButton';
import { SessionContextMenuContainer } from '../SessionContextMenuContainer';
import { ItemWithDataTestId } from '../menu/items/MenuItemWithDataTestId';
const VideoInputMenu = ({
triggerId,
@ -23,14 +24,14 @@ const VideoInputMenu = ({
<Menu id={triggerId} animation="fade">
{camerasList.map(m => {
return (
<Item
<ItemWithDataTestId
key={m.deviceId}
onClick={() => {
void CallManager.selectCameraByDeviceId(m.deviceId);
}}
>
{m.label.substr(0, 40)}
</Item>
</ItemWithDataTestId>
);
})}
</Menu>
@ -96,14 +97,14 @@ const AudioInputMenu = ({
<Menu id={triggerId} animation="fade">
{audioInputsList.map(m => {
return (
<Item
<ItemWithDataTestId
key={m.deviceId}
onClick={() => {
void CallManager.selectAudioInputByDeviceId(m.deviceId);
}}
>
{m.label.substr(0, 40)}
</Item>
</ItemWithDataTestId>
);
})}
</Menu>
@ -165,14 +166,14 @@ const AudioOutputMenu = ({
<Menu id={triggerId} animation="fade">
{audioOutputsList.map(m => {
return (
<Item
<ItemWithDataTestId
key={m.deviceId}
onClick={() => {
void CallManager.selectAudioOutputByDeviceId(m.deviceId);
}}
>
{m.label.substr(0, 40)}
</Item>
</ItemWithDataTestId>
);
})}
</Menu>

@ -2,7 +2,7 @@
import { Dispatch, useCallback, useEffect, useRef, useState } from 'react';
import { isNumber } from 'lodash';
import { Item, ItemParams, Menu, useContextMenu } from 'react-contexify';
import { ItemParams, Menu, useContextMenu } from 'react-contexify';
import { useDispatch } from 'react-redux';
import useClickAway from 'react-use/lib/useClickAway';
import useMouse from 'react-use/lib/useMouse';
@ -51,6 +51,7 @@ import { MessageReactBar } from './MessageReactBar';
import { showCopyAccountIdAction } from '../../../menu/items/CopyAccountId';
import { CopyAccountIdMenuItem } from '../../../menu/items/CopyAccountId/CopyAccountIdMenuItem';
import { Localizer } from '../../../basic/Localizer';
import { ItemWithDataTestId } from '../../../menu/items/MenuItemWithDataTestId';
export type MessageContextMenuSelectorProps = Pick<
MessageRenderingProps,
@ -109,7 +110,7 @@ const DeleteItem = ({ messageId }: { messageId: string }) => {
return null;
}
return <Item onClick={onDelete}>{window.i18n('delete')}</Item>;
return <ItemWithDataTestId onClick={onDelete}>{window.i18n('delete')}</ItemWithDataTestId>;
};
type MessageId = { messageId: string };
@ -146,12 +147,16 @@ const AdminActionItems = ({ messageId }: MessageId) => {
return showAdminActions ? (
<>
<Item onClick={onBan}>{window.i18n('banUser')}</Item>
<Item onClick={onUnban}>{window.i18n('banUnbanUser')}</Item>
<ItemWithDataTestId onClick={onBan}>{window.i18n('banUser')}</ItemWithDataTestId>
<ItemWithDataTestId onClick={onUnban}>{window.i18n('banUnbanUser')}</ItemWithDataTestId>
{isSenderAdmin ? (
<Item onClick={removeModerator}>{window.i18n('adminRemoveAsAdmin')}</Item>
<ItemWithDataTestId onClick={removeModerator}>
{window.i18n('adminRemoveAsAdmin')}
</ItemWithDataTestId>
) : (
<Item onClick={addModerator}>{window.i18n('adminPromoteToAdmin')}</Item>
<ItemWithDataTestId onClick={addModerator}>
{window.i18n('adminPromoteToAdmin')}
</ItemWithDataTestId>
)}
</>
) : null;
@ -170,7 +175,9 @@ const RetryItem = ({ messageId }: MessageId) => {
await found.retrySend();
}
}, [messageId]);
return showRetry ? <Item onClick={onRetry}>{window.i18n('resend')}</Item> : null;
return showRetry ? (
<ItemWithDataTestId onClick={onRetry}>{window.i18n('resend')}</ItemWithDataTestId>
) : null;
};
export const showMessageInfoOverlay = async ({
@ -372,26 +379,28 @@ export const MessageContextMenu = (props: Props) => {
/>
)}
{attachments?.length && attachments.every(m => !m.pending && m.path) ? (
<Item onClick={saveAttachment}>{window.i18n('save')}</Item>
<ItemWithDataTestId onClick={saveAttachment}>{window.i18n('save')}</ItemWithDataTestId>
) : null}
<Item onClick={copyText}>{window.i18n('copy')}</Item>
{(isSent || !isOutgoing) && <Item onClick={onReply}>{window.i18n('reply')}</Item>}
<Item
<ItemWithDataTestId onClick={copyText}>{window.i18n('copy')}</ItemWithDataTestId>
{(isSent || !isOutgoing) && (
<ItemWithDataTestId onClick={onReply}>{window.i18n('reply')}</ItemWithDataTestId>
)}
<ItemWithDataTestId
onClick={() => {
void showMessageInfoOverlay({ messageId, dispatch });
}}
>
<Localizer token="info" />
</Item>
</ItemWithDataTestId>
{/* this is a message in the view, so always private */}
{sender && showCopyAccountIdAction({ isPrivate: true, pubkey: sender }) ? (
<CopyAccountIdMenuItem pubkey={sender} />
) : null}
<RetryItem messageId={messageId} />
{isDeletable ? (
<Item onClick={onSelect}>
<ItemWithDataTestId onClick={onSelect}>
<Localizer token="messageSelect" />
</Item>
</ItemWithDataTestId>
) : null}
<DeleteItem messageId={messageId} />
<AdminActionItems messageId={messageId} />

@ -86,7 +86,7 @@ export const BlockOrUnblockDialog = ({ pubkeys, action, onConfirmed }: NonNullab
return (
<SessionWrapperModal showExitIcon={true} title={localizedAction} onClose={closeModal}>
<StyledModalDescriptionContainer>
<StyledModalDescriptionContainer data-testid="block-unblock-modal-description">
<Localizer {...args} />
</StyledModalDescriptionContainer>
<Flex container={true} flexDirection="column" alignItems="center">
@ -97,12 +97,14 @@ export const BlockOrUnblockDialog = ({ pubkeys, action, onConfirmed }: NonNullab
buttonColor={SessionButtonColor.Danger}
onClick={onConfirm}
text={localizedAction}
dataTestId="session-confirm-ok-button"
/>
<SessionButton
buttonType={SessionButtonType.Simple}
buttonColor={SessionButtonColor.White}
onClick={closeModal}
text={window.i18n('cancel')}
dataTestId="session-cancel-ok-button"
/>
</div>
</Flex>

@ -1,4 +1,4 @@
import { Item, Menu } from 'react-contexify';
import { Menu } from 'react-contexify';
import { useSelector } from 'react-redux';
import { useConvoIdFromContext } from '../../contexts/ConvoIdContext';
@ -27,6 +27,7 @@ import {
} from './Menu';
import { CopyCommunityUrlMenuItem } from './items/CopyCommunityUrl/CopyCommunityUrlMenuItem';
import { CopyAccountIdMenuItem } from './items/CopyAccountId/CopyAccountIdMenuItem';
import { ItemWithDataTestId } from './items/MenuItemWithDataTestId';
export type PropsContextConversationItem = {
triggerId: string;
@ -92,7 +93,7 @@ export const PinConversationMenuItem = (): JSX.Element | null => {
};
const menuText = isPinned ? window.i18n('pinUnpin') : window.i18n('pin');
return <Item onClick={togglePinConversation}>{menuText}</Item>;
return <ItemWithDataTestId onClick={togglePinConversation}>{menuText}</ItemWithDataTestId>;
}
return null;
};

@ -1,4 +1,4 @@
import { Item, Submenu } from 'react-contexify';
import { Submenu } from 'react-contexify';
import { useDispatch, useSelector } from 'react-redux';
import { useConvoIdFromContext } from '../../contexts/ConvoIdContext';
import {
@ -57,6 +57,7 @@ import { getIsMessageSection } from '../../state/selectors/section';
import { useSelectedConversationKey } from '../../state/selectors/selectedConversation';
import type { LocalizerToken } from '../../types/localizer';
import { SessionButtonColor } from '../basic/SessionButton';
import { ItemWithDataTestId } from './items/MenuItemWithDataTestId';
/** Menu items standardized */
@ -66,13 +67,13 @@ export const InviteContactMenuItem = (): JSX.Element | null => {
if (isPublic) {
return (
<Item
<ItemWithDataTestId
onClick={() => {
showInviteContactByConvoId(convoId);
}}
>
{window.i18n('membersInvite')}
</Item>
</ItemWithDataTestId>
);
}
return null;
@ -91,7 +92,11 @@ export const MarkConversationUnreadMenuItem = (): JSX.Element | null => {
void conversation?.markAsUnread(true);
};
return <Item onClick={markUnread}>{window.i18n('messageMarkUnread')}</Item>;
return (
<ItemWithDataTestId onClick={markUnread}>
{window.i18n('messageMarkUnread')}
</ItemWithDataTestId>
);
}
return null;
};
@ -133,7 +138,7 @@ export const DeletePrivateContactMenuItem = () => {
);
};
return <Item onClick={showConfirmationModal}>{menuItemText}</Item>;
return <ItemWithDataTestId onClick={showConfirmationModal}>{menuItemText}</ItemWithDataTestId>;
}
return null;
};
@ -149,7 +154,7 @@ export const LeaveGroupOrCommunityMenuItem = () => {
if (!isKickedFromGroup && !isLeft && !isPrivate) {
return (
<Item
<ItemWithDataTestId
onClick={() => {
void showLeaveGroupByConvoId(convoId, username);
}}
@ -160,7 +165,7 @@ export const LeaveGroupOrCommunityMenuItem = () => {
lastMessage?.interactionStatus === ConversationInteractionStatus.Error
? window.i18n('conversationsDelete')
: window.i18n('groupLeave')}
</Item>
</ItemWithDataTestId>
);
}
@ -177,7 +182,7 @@ export const ShowUserDetailsMenuItem = () => {
if (isPrivate && !isBlinded) {
return (
<Item
<ItemWithDataTestId
onClick={() => {
dispatch(
updateUserDetailsModal({
@ -189,7 +194,7 @@ export const ShowUserDetailsMenuItem = () => {
}}
>
{window.i18n('contactUserDetails')}
</Item>
</ItemWithDataTestId>
);
}
@ -204,13 +209,13 @@ export const UpdateGroupNameMenuItem = () => {
if (!isKickedFromGroup && !left && weAreAdmin) {
return (
<Item
<ItemWithDataTestId
onClick={() => {
void showUpdateGroupNameByConvoId(convoId);
}}
>
{window.i18n('groupEdit')}
</Item>
</ItemWithDataTestId>
);
}
return null;
@ -224,13 +229,13 @@ export const RemoveModeratorsMenuItem = (): JSX.Element | null => {
if (!isKickedFromGroup && weAreAdmin && isPublic) {
return (
<Item
<ItemWithDataTestId
onClick={() => {
showRemoveModeratorsByConvoId(convoId);
}}
>
{window.i18n('adminRemove')}
</Item>
</ItemWithDataTestId>
);
}
return null;
@ -244,13 +249,13 @@ export const AddModeratorsMenuItem = (): JSX.Element | null => {
if (!isKickedFromGroup && weAreAdmin && isPublic) {
return (
<Item
<ItemWithDataTestId
onClick={() => {
showAddModeratorsByConvoId(convoId);
}}
>
{window.i18n('adminPromote')}
</Item>
</ItemWithDataTestId>
);
}
return null;
@ -264,13 +269,13 @@ export const UnbanMenuItem = (): JSX.Element | null => {
if (isPublic && !isKickedFromGroup && weAreAdmin) {
return (
<Item
<ItemWithDataTestId
onClick={() => {
showUnbanUserByConvoId(convoId);
}}
>
{window.i18n('banUnbanUser')}
</Item>
</ItemWithDataTestId>
);
}
return null;
@ -284,13 +289,13 @@ export const BanMenuItem = (): JSX.Element | null => {
if (isPublic && !isKickedFromGroup && weAreAdmin) {
return (
<Item
<ItemWithDataTestId
onClick={() => {
showBanUserByConvoId(convoId);
}}
>
{window.i18n('banUser')}
</Item>
</ItemWithDataTestId>
);
}
return null;
@ -302,9 +307,9 @@ export const MarkAllReadMenuItem = (): JSX.Element | null => {
if (!isIncomingRequest && !PubKey.isBlinded(convoId)) {
return (
// eslint-disable-next-line @typescript-eslint/no-misused-promises
<Item onClick={async () => markAllReadByConvoId(convoId)}>
<ItemWithDataTestId onClick={async () => markAllReadByConvoId(convoId)}>
{window.i18n('messageMarkRead')}
</Item>
</ItemWithDataTestId>
);
}
return null;
@ -323,7 +328,7 @@ export const BlockMenuItem = (): JSX.Element | null => {
? async () => unblockConvoById(convoId)
: async () => blockConvoById(convoId);
// eslint-disable-next-line @typescript-eslint/no-misused-promises
return <Item onClick={blockHandler}>{blockTitle}</Item>;
return <ItemWithDataTestId onClick={blockHandler}>{blockTitle}</ItemWithDataTestId>;
}
return null;
};
@ -341,9 +346,9 @@ export const ClearNicknameMenuItem = (): JSX.Element | null => {
return (
// eslint-disable-next-line @typescript-eslint/no-misused-promises
<Item onClick={async () => clearNickNameByConvoId(convoId)}>
<ItemWithDataTestId onClick={async () => clearNickNameByConvoId(convoId)}>
{window.i18n('nicknameRemove')}
</Item>
</ItemWithDataTestId>
);
};
@ -358,13 +363,13 @@ export const ChangeNicknameMenuItem = () => {
return null;
}
return (
<Item
<ItemWithDataTestId
onClick={() => {
dispatch(changeNickNameModal({ conversationId: convoId }));
}}
>
{window.i18n('nicknameSet')}
</Item>
</ItemWithDataTestId>
);
};
@ -380,14 +385,14 @@ export const DeleteMessagesMenuItem = () => {
return null;
}
return (
<Item
<ItemWithDataTestId
onClick={() => {
deleteAllMessagesByConvoIdWithConfirmation(convoId);
}}
>
{/* just more than 1 to have the string Delete Messages */}
{window.i18n('deleteMessage', { count: 2 })}
</Item>
</ItemWithDataTestId>
);
};
@ -407,13 +412,13 @@ export const DeletePrivateConversationMenuItem = () => {
}
return (
<Item
<ItemWithDataTestId
onClick={() => {
showLeavePrivateConversationbyConvoId(convoId);
}}
>
{isMe ? window.i18n('noteToSelfHide') : window.i18n('conversationsDelete')}
</Item>
</ItemWithDataTestId>
);
};
@ -425,7 +430,7 @@ export const AcceptMsgRequestMenuItem = () => {
if (isRequest && isPrivate) {
return (
<Item
<ItemWithDataTestId
// eslint-disable-next-line @typescript-eslint/no-misused-promises
onClick={async () => {
await convo.setDidApproveMe(true);
@ -434,7 +439,7 @@ export const AcceptMsgRequestMenuItem = () => {
}}
>
{window.i18n('accept')}
</Item>
</ItemWithDataTestId>
);
}
return null;
@ -448,7 +453,7 @@ export const DeclineMsgRequestMenuItem = () => {
if (isPrivate && isRequest) {
return (
<Item
<ItemWithDataTestId
onClick={() => {
declineConversationWithConfirm({
conversationId: convoId,
@ -459,7 +464,7 @@ export const DeclineMsgRequestMenuItem = () => {
}}
>
{window.i18n('decline')}
</Item>
</ItemWithDataTestId>
);
}
return null;
@ -473,7 +478,7 @@ export const DeclineAndBlockMsgRequestMenuItem = () => {
if (isRequest && isPrivate) {
return (
<Item
<ItemWithDataTestId
onClick={() => {
declineConversationWithConfirm({
conversationId: convoId,
@ -484,7 +489,7 @@ export const DeclineAndBlockMsgRequestMenuItem = () => {
}}
>
{window.i18n('block')}
</Item>
</ItemWithDataTestId>
);
}
return null;
@ -540,7 +545,7 @@ export const NotificationForConvoMenuItem = (): JSX.Element | null => {
const disabled = item.value === currentNotificationSetting;
return (
<Item
<ItemWithDataTestId
key={item.value}
onClick={() => {
void setNotificationForConvoId(convoId, item.value);
@ -548,7 +553,7 @@ export const NotificationForConvoMenuItem = (): JSX.Element | null => {
disabled={disabled}
>
{item.name}
</Item>
</ItemWithDataTestId>
);
})}
</Submenu>

@ -1,9 +1,10 @@
import { Item, Menu } from 'react-contexify';
import { Menu } from 'react-contexify';
import { useDispatch } from 'react-redux';
import { SessionContextMenuContainer } from '../SessionContextMenuContainer';
import { hideMessageRequestBanner } from '../../state/ducks/userConfig';
import { ItemWithDataTestId } from './items/MenuItemWithDataTestId';
export type PropsContextConversationItem = {
triggerId: string;
@ -12,13 +13,13 @@ export type PropsContextConversationItem = {
const HideBannerMenuItem = (): JSX.Element => {
const dispatch = useDispatch();
return (
<Item
<ItemWithDataTestId
onClick={() => {
dispatch(hideMessageRequestBanner());
}}
>
{window.i18n('hide')}
</Item>
</ItemWithDataTestId>
);
};

@ -1,8 +1,8 @@
import { Item } from 'react-contexify';
import { useIsPrivate } from '../../../../hooks/useParamSelector';
import { copyPublicKeyByConvoId } from '../../../../interactions/conversationInteractions';
import { Localizer } from '../../../basic/Localizer';
import { showCopyAccountIdAction } from '.';
import { ItemWithDataTestId } from '../MenuItemWithDataTestId';
/**
* Can be used to copy the conversation AccountID or the message's author sender'id.
@ -15,13 +15,13 @@ export const CopyAccountIdMenuItem = ({ pubkey }: { pubkey: string }): JSX.Eleme
if (showCopyAccountIdAction({ isPrivate, pubkey })) {
return (
<Item
<ItemWithDataTestId
onClick={() => {
void copyPublicKeyByConvoId(pubkey);
}}
>
<Localizer token="accountIDCopy" />
</Item>
</ItemWithDataTestId>
);
}
return null;

@ -1,8 +1,8 @@
import { Item } from 'react-contexify';
import { showCopyCommunityUrlMenuItem } from '.';
import { useIsPublic } from '../../../../hooks/useParamSelector';
import { copyPublicKeyByConvoId } from '../../../../interactions/conversationInteractions';
import { Localizer } from '../../../basic/Localizer';
import { ItemWithDataTestId } from '../MenuItemWithDataTestId';
export const CopyCommunityUrlMenuItem = ({ convoId }: { convoId: string }): JSX.Element | null => {
const isPublic = useIsPublic(convoId);
@ -11,13 +11,13 @@ export const CopyCommunityUrlMenuItem = ({ convoId }: { convoId: string }): JSX.
if (showCopyCommunityUrlMenuItem({ isPublic })) {
return (
<Item
<ItemWithDataTestId
onClick={() => {
void copyPublicKeyByConvoId(convoId);
}}
>
<Localizer token="communityUrlCopy" />
</Item>
</ItemWithDataTestId>
);
}
return null;

@ -0,0 +1,9 @@
import { Item, ItemProps } from 'react-contexify';
export function ItemWithDataTestId({ children, ...props }: ItemProps) {
return (
<Item data-testid="context-menu-item" {...props}>
{children}
</Item>
);
}
Loading…
Cancel
Save