Add more test id to elements based on test case e2e

This commit is contained in:
lethemanh
2024-12-10 21:59:55 +07:00
parent 217e683269
commit 86e3661508
36 changed files with 128 additions and 55 deletions
@@ -40,11 +40,14 @@ export const AccessLevelDropdown = ({
}) => {
const createOption = (level: DriveFileAccessLevelOrRemove) =>
!hiddenLevels?.includes(level) && <option value={level}>{(labelOverrides || {})[level] || translateAccessLevel(level)}</option>;
const testId = testClassId ? `testid:${testClassId}` : '';
return (
<Select
disabled={disabled}
size={size}
className={className + ' w-auto' + ` testid:${testClassId}`}
className={className + ' w-auto' + ' ' + testId}
theme={(!noRedWhenLevelNone && level === 'none') ? 'rose' : 'outline'}
value={level || 'none'}
onChange={e => onChange(e.target.value as DriveFileAccessLevel & 'remove')}
@@ -85,6 +85,7 @@ export const useOnBuildContextMenu = (
!FeatureTogglesService.isActiveFeatureName(FeatureNames.COMPANY_MANAGE_ACCESS);
const newMenuActions = [
{
id: 'share',
type: 'menu',
icon: 'share-alt',
text: Languages.t('components.item_context_menu.share'),
@@ -92,6 +93,7 @@ export const useOnBuildContextMenu = (
onClick: () => setPublicLinkModalState({ open: true, id: item.id }),
},
{
id: 'manage-access',
type: 'menu',
icon: 'users-alt',
text: Languages.t('components.item_context_menu.manage_access'),
@@ -99,6 +101,7 @@ export const useOnBuildContextMenu = (
onClick: () => setAccessModalState({ open: true, id: item.id }),
},
{
id: 'rescan-document',
type: 'menu',
icon: 'shield-check',
text: Languages.t('components.item_context_menu.rescan_document'),
@@ -115,6 +118,7 @@ export const useOnBuildContextMenu = (
(notSafe && !(item.av_status === 'scan_failed')),
},
{
id: 'download',
type: 'menu',
icon: 'download-alt',
text: Languages.t('components.item_context_menu.download'),
@@ -141,6 +145,7 @@ export const useOnBuildContextMenu = (
}, // */
{ type: 'separator', hide: notSafe },
{
id: 'move',
type: 'menu',
icon: 'folder-question',
text: Languages.t('components.item_context_menu.move'),
@@ -166,6 +171,7 @@ export const useOnBuildContextMenu = (
}),
},
{
id: 'rename',
type: 'menu',
icon: 'file-edit-alt',
text: Languages.t('components.item_context_menu.rename'),
@@ -173,6 +179,7 @@ export const useOnBuildContextMenu = (
onClick: () => setPropertiesModalState({ open: true, id: item.id, inPublicSharing }),
},
{
id: 'copy-link',
type: 'menu',
icon: 'link',
text: Languages.t('components.item_context_menu.copy_link'),
@@ -189,6 +196,7 @@ export const useOnBuildContextMenu = (
},
},
{
id: 'version',
type: 'menu',
icon: 'history',
text: Languages.t('components.item_context_menu.versions'),
@@ -197,6 +205,7 @@ export const useOnBuildContextMenu = (
},
{ type: 'separator', hide: access !== 'manage' || inTrash || notSafe },
{
id: 'move-to-trash',
type: 'menu',
icon: 'trash',
text: Languages.t('components.item_context_menu.move_to_trash'),
@@ -205,6 +214,7 @@ export const useOnBuildContextMenu = (
onClick: () => setConfirmTrashModalState({ open: true, items: [item] }),
},
{
id: 'restore',
type: 'menu',
text: Languages.t('components.item_context_menu.restore'),
className: 'error',
@@ -215,6 +225,7 @@ export const useOnBuildContextMenu = (
},
},
{
id: 'delete',
type: 'menu',
text: Languages.t('components.item_context_menu.delete'),
className: 'error',
@@ -231,6 +242,7 @@ export const useOnBuildContextMenu = (
// Add selected items related menus
const newMenuActions: any[] = [
{
id: 'move-multiple',
type: 'menu',
text: Languages.t('components.item_context_menu.move_multiple'),
hide: parent.access === 'read' || inTrash,
@@ -255,6 +267,7 @@ export const useOnBuildContextMenu = (
}),
},
{
id: 'download-multiple',
type: 'menu',
text: Languages.t('components.item_context_menu.download_multiple'),
hide: inTrash,
@@ -272,12 +285,14 @@ export const useOnBuildContextMenu = (
},
},
{
id: 'clear-selection',
type: 'menu',
text: Languages.t('components.item_context_menu.clear_selection'),
onClick: () => setChecked({}),
},
{ type: 'separator', hide: parent.access === 'read' || notSafe },
{
id: 'delete-multiple',
type: 'menu',
text: Languages.t('components.item_context_menu.delete_multiple'),
hide: !inTrash || parent.access !== 'manage',
@@ -290,6 +305,7 @@ export const useOnBuildContextMenu = (
},
},
{
id: 'move-to-trash-multiple',
type: 'menu',
text: Languages.t('components.item_context_menu.to_trash_multiple'),
hide: inTrash || parent.access !== 'manage',
@@ -310,6 +326,7 @@ export const useOnBuildContextMenu = (
const newMenuActions: any[] = inTrash
? [
{
id: 'empty-trash',
type: 'menu',
text: Languages.t('components.item_context_menu.trash.empty'),
className: 'error',
@@ -324,6 +341,7 @@ export const useOnBuildContextMenu = (
]
: [
{
id: 'add-documents',
type: 'menu',
text: Languages.t('components.item_context_menu.add_documents'),
hide: inTrash || parent.access === 'read',
@@ -332,6 +350,7 @@ export const useOnBuildContextMenu = (
setUploadModalState({ open: true, parent_id: parent?.item?.id }),
},
{
id: 'download-folder',
type: 'menu',
text: Languages.t('components.item_context_menu.download_folder'),
hide: inTrash,
@@ -349,6 +368,7 @@ export const useOnBuildContextMenu = (
},
},
{
id: 'copy-link',
type: 'menu',
text: Languages.t('components.item_context_menu.copy_link'),
hide: !hasAnyPublicLinkAccess(item),
@@ -361,6 +381,7 @@ export const useOnBuildContextMenu = (
},
{ type: 'separator', hide: parent.item!.id != 'root' },
{
id: 'manage-users',
type: 'menu',
text: Languages.t('components.item_context_menu.manage_users'),
hide: parent.item!.id != 'root',
@@ -419,6 +440,7 @@ export const useOnBuildFileTypeContextMenu = () => {
return useCallback(() => {
const menuItems = mimeTypes.map(item => {
return {
id: item.key,
type: 'menu',
text: item.key,
onClick: () => {
@@ -444,6 +466,7 @@ export const useOnBuildPeopleContextMenu = () => {
return useCallback(() => {
const menuItems = userList.map(user => {
return {
id: user.first_name,
type: 'menu',
text: user.first_name,
onClick: () => {
@@ -466,6 +489,7 @@ export const useOnBuildDateContextMenu = () => {
return useCallback(() => {
const menuItems = [
{
id: 'all-date',
type: 'menu',
text: Languages.t('components.item_context_menu.all'),
onClick: () => {
@@ -482,6 +506,7 @@ export const useOnBuildDateContextMenu = () => {
},
},
{
id: 'today',
type: 'menu',
text: Languages.t('components.item_context_menu.today'),
onClick: () => {
@@ -498,6 +523,7 @@ export const useOnBuildDateContextMenu = () => {
},
},
{
id: 'last-week',
type: 'menu',
text: Languages.t('components.item_context_menu.last_week'),
onClick: () => {
@@ -514,6 +540,7 @@ export const useOnBuildDateContextMenu = () => {
},
},
{
id: 'last-month',
type: 'menu',
text: Languages.t('components.item_context_menu.last_month'),
onClick: () => {
@@ -540,11 +567,13 @@ export const useOnBuildFileContextMenu = () => {
(item: DriveItem) => {
const menuItems = [
{
id: 'preview',
type: 'menu',
text: Languages.t('components.item_context_menu.preview'),
onClick: () => preview(item),
},
{
id: 'download',
type: 'menu',
text: Languages.t('components.item_context_menu.download'),
onClick: () => {
@@ -563,6 +592,7 @@ export const useOnBuildSortContextMenu = () => {
return useCallback(() => {
const menuItems = [
{
id: 'sorting-by-date',
type: 'menu',
text: Languages.t('components.item_context_menu.sorting.by.date'),
icon: sortItem.by === 'date' ? 'check' : 'sort-check',
@@ -578,6 +608,7 @@ export const useOnBuildSortContextMenu = () => {
},
},
{
id: 'sorting-by-name',
type: 'menu',
text: Languages.t('components.item_context_menu.sorting.by.name'),
icon: sortItem.by === 'name' ? 'check' : 'sort-check',
@@ -592,6 +623,7 @@ export const useOnBuildSortContextMenu = () => {
},
},
{
id: 'sorting-by-size',
type: 'menu',
text: Languages.t('components.item_context_menu.sorting.by.size'),
icon: sortItem.by === 'size' ? 'check' : 'sort-check',
@@ -607,6 +639,7 @@ export const useOnBuildSortContextMenu = () => {
},
{type:"separator"},
{
id: 'sorting-order-asc',
type: 'menu',
text: Languages.t('components.item_context_menu.sorting.order.asc'),
icon: sortItem.order === 'asc' ? 'check' : 'sort-check',
@@ -621,6 +654,7 @@ export const useOnBuildSortContextMenu = () => {
},
},
{
id: 'sorting-order-desc',
type: 'menu',
text: Languages.t('components.item_context_menu.sorting.order.desc'),
icon: sortItem.order === 'desc' ? 'check' : 'sort-check',
@@ -45,6 +45,8 @@ export const DocumentRow = ({
// history.push(RouterServices.generateRouteFromState({ companyId: company, itemId: item.id }));
};
const testId = testClassId ? `testid:${testClassId}` : '';
return (
<div
className={
@@ -52,8 +54,8 @@ export const DocumentRow = ({
(checked
? (notSafe ? 'bg-rose-500' : 'bg-blue-500') + ' bg-opacity-10 hover:bg-opacity-25'
: 'hover:bg-zinc-500 hover:bg-opacity-10 ') +
(className || '') +
` testid:${testClassId}`
(className || '') + ' ' +
testId
}
id={`DR-${item.id}`}
onMouseEnter={() => setHover(true)}
@@ -21,6 +21,8 @@ export const FolderRow = ({
}: DriveItemProps) => {
const [hover, setHover] = useState(false);
const testId = testClassId ? ` testid:${testClassId}` : '';
return (
<div
className={
@@ -29,8 +31,8 @@ export const FolderRow = ({
(checked
? 'bg-blue-500 bg-opacity-10 hover:bg-opacity-25 '
: 'hover:bg-zinc-500 hover:bg-opacity-10 ') +
(className || '') +
` testid:${testClassId}`
(className || '') + ' ' +
testId
}
onMouseEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}
@@ -27,7 +27,7 @@ export const ConfirmDeleteModal = () => {
return (
<>
{state.items.length > 0 && (
<Modal open={state.open} onClose={() => setState({ ...state, open: false })}>
<Modal className="testid:confirm-delete-modal" open={state.open} onClose={() => setState({ ...state, open: false })}>
<ConfirmDeleteModalContent items={state.items} />
</Modal>
)}
@@ -68,7 +68,7 @@ export const ConfirmModal = () => {
};
return (
<Modal open={state.open} onClose={handleClose}>
<Modal className="testid:confirm-modal" open={state.open} onClose={handleClose}>
<ConfirmModalContent key={state.parent_id} />
</Modal>
);
@@ -28,7 +28,7 @@ export const ConfirmTrashModal = () => {
const [state, setState] = useRecoilState(ConfirmTrashModalAtom);
return (
<Modal open={state.open} onClose={() => setState({ ...state, open: false })}>
<Modal className="confirm-trash-modal" open={state.open} onClose={() => setState({ ...state, open: false })}>
{!!state.items.length && <ConfirmTrashModalContent items={state.items} />}
</Modal>
);
@@ -46,7 +46,7 @@ export const CreateModal = ({
<Modal
open={state.open}
onClose={() => setState({ ...state, open: false })}
className="!max-w-sm"
className="!max-w-sm testid:create-modal"
>
<ModalContent
title={
@@ -171,10 +171,12 @@ export const CreateModal = ({
};
const CreateModalOption = (props: { testClassId?: string; icon: ReactNode; text: string; onClick: () => void }) => {
const testId = props.testClassId ? `testid:${props.testClassId}` : '';
return (
<div
onClick={props.onClick}
className={`flex flex-row p-4 dark:bg-zinc-900 dark:text-white bg-zinc-100 hover:bg-opacity-75 cursor-pointer rounded-md m-2 testid:${props.testClassId}`}
className={`flex flex-row p-4 dark:bg-zinc-900 dark:text-white bg-zinc-100 hover:bg-opacity-75 cursor-pointer rounded-md m-2 ${testId}`}
>
<div className="flex items-center justify-center">{props.icon}</div>
<div className="grow flex items-center ml-2">
@@ -27,7 +27,7 @@ export const PropertiesModal = () => {
const [state, setState] = useRecoilState(PropertiesModalAtom);
return (
<Modal open={state.open} onClose={() => setState({ ...state, open: false })}>
<Modal className="testid:properties-modal" open={state.open} onClose={() => setState({ ...state, open: false })}>
{!!state.id && (
<PropertiesModalContent
id={state.id}
@@ -41,6 +41,7 @@ export const PublicLinkModal = () => {
setIsOnAdvancedScreen(false);
setState({ ...state, open: false });
}}
className="testid:public-link-modal"
>
{!!state.id &&
<PublicLinkModalContent
@@ -155,6 +156,7 @@ const PublicLinkModalContent = (props: {
<Modal
open={props.isOnAdvancedScreen}
onClose={() => { props.onShowAdvancedScreen(false); }}
className="testid:public-link-advance-setting-modal"
>
<ModalContent
title={
@@ -28,7 +28,7 @@ export const AccessModal = () => {
return (
<Modal
open={state.open}
className='!overflow-visible'
className='!overflow-visible testid:access-modal'
onClose={closeModal}
>
{!!state.id && <AccessModalContent id={state.id} onCloseModal={closeModal} />}
@@ -181,7 +181,7 @@ export const InternalUsersAccessManager = ({
size="sm"
className='text-center'
onClick={onCloseModal}
testClassId="access-management-public-link-security-field-confirm-edit"
testClassId="public-link-button-confirm-edit"
>
{Languages.t('components.public-link-security_field_confirm_edit')}
</Button>
@@ -40,7 +40,7 @@ export const UploadModal = ({
<Modal
open={state.open}
onClose={() => setState({ ...state, open: false })}
className="!max-w-sm"
className="!max-w-sm testid:upload-modal"
>
<ModalContent
title={
@@ -29,7 +29,7 @@ export const VersionsModal = () => {
const [state, setState] = useRecoilState(VersionsModalAtom);
return (
<Modal open={state.open} onClose={() => setState({ ...state, open: false })}>
<Modal className="testid:version-modal" open={state.open} onClose={() => setState({ ...state, open: false })}>
{!!state.id && <VersionModalContent id={state.id} />}
</Modal>
);
@@ -29,7 +29,7 @@ export const SharedFilesTable = () => {
return formattedDate;
};
return (
<div>
<div className="testid:shared-file-table">
<Title className="mb-4 block">{Languages.t('scenes.app.shared_with_me.shared_with_me')}</Title>
{/* Filters */}
<div className="flex items-center space-x-4 mb-6">
@@ -69,7 +69,7 @@ export default () => {
<div className="flex flex-row items-center justify-center bg-blue-500 px-4 py-2">
<div className="grow flex flex-row items-center">
{group.logo && (
<Avatar avatar={group.logo} className="inline-block mr-3" size="sm" type="square" />
<Avatar avatar={group.logo} className="inline-block mr-3" size="sm" type="square" testClassId="shared-view-avatar" />
)}
<span className="text-white font-semibold" style={{ lineHeight: '32px' }}>
Twake Drive
@@ -162,6 +162,7 @@ const AccessChecker = ({
className="-mr-px rounded-r-none border-r-none"
value={password}
onChange={e => setPassword(e.target.value)}
testClassId="access-checker-input-password"
/>
<Button
className="rounded-l-none"
@@ -170,6 +171,7 @@ const AccessChecker = ({
await setPublicToken(token || '', password);
await refresh(folderId);
}}
testClassId="access-checker-button-submit"
>
Submit
</Button>
@@ -23,11 +23,13 @@ export default (): JSX.Element => {
menu={[
// user name / email
{
id: 'username',
type: 'text',
className: "username",
text: currentUserService.getFullName(user),
},
{
id: 'email',
type: 'text',
text: user.email,
className: 'email',
@@ -36,6 +38,7 @@ export default (): JSX.Element => {
},
{ type: 'separator' },
{
id: 'account-setting',
type: 'menu',
className: 'account-menu',
icon: <Icon type="user-circle" className="text-black dark:text-white" />,
@@ -46,6 +49,7 @@ export default (): JSX.Element => {
},
},
{
id: 'logout',
type: 'menu',
className: 'account-menu',
icon: <Icon type="sign-out-alt" className="text-black dark:text-white" />,
@@ -61,6 +65,7 @@ export default (): JSX.Element => {
className="shrink-0 border-0"
avatar={user.thumbnail}
title={currentUserService.getFullName(user)}
testClassId="account-avatar"
/>
</Menu>
);
@@ -27,7 +27,7 @@ export default ({ className }: { className?: string }): JSX.Element => {
target="_blank"
rel="noreferrer"
href={app.url}
className="inline-block flex flex-col items-center justify-center cursor-pointer hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-md p-2 pb-1"
className={`inline-block flex flex-col items-center justify-center cursor-pointer hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-md p-2 pb-1 testid:app-${app.name}`}
>
<img src={app.logo} className="w-11 h-11 mb-1" />
<Base style={{
@@ -47,6 +47,7 @@ export default ({ className }: { className?: string }): JSX.Element => {
size="md"
className={'!rounded-full border-0 ' + className}
icon={() => <ViewGridIcon className="w-6 h-6 text-blue-500" />}
testClassId="app-grid-button"
/>
</Menu>
);
@@ -44,19 +44,19 @@ const DiskUsage = () => {
<div className="w-full">
<div className="overflow-hidden h-4 mb-4 text-xs flex rounded bg-emerald-200">
{used > 90 && (
<div style={{ width: used + '%',}} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-red-500"></div>
<div style={{ width: used + '%',}} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-red-500 testid:disk-usage-over-90"></div>
)}
{used < 80 && (
<div style={{ width: used + '%',}} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-green-500"></div>
<div style={{ width: used + '%',}} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-green-500 testid:disk-usage-less-than-80"></div>
)}
{ (used >= 80 && used <= 90 )&& (
<div style={{ width: used + '%',}} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-yellow-500"></div>
<div style={{ width: used + '%',}} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-yellow-500 testid:disk-usage-80-to-90"></div>
)}
<div style={{ width: (100 - used) + '%' }} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-grey-500"></div>
<div style={{ width: (100 - used) + '%' }} className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-grey-500 testid:disk-usage-100"></div>
</div>
{/*<div className="bg-blue-600 h-1.5 rounded-full dark:bg-blue-500" style={usedStyle}></div>*/}
<Base>
<Base className="testid:disk-usage-text">
{formatBytesToInt(usedBytes)}
<Base> { Languages.t('components.disk_usage.of')} </Base>
{formatBytesToInt(totalBytes || 0)}
@@ -69,7 +69,7 @@ const DiskUsage = () => {
{!FeatureTogglesService.isActiveFeatureName(FeatureNames.COMPANY_USER_QUOTA) && (
<div className="bg-zinc-500 dark:bg-zinc-900 bg-opacity-10 rounded-md p-4 w-auto max-w-md">
<div className="w-full">
<Base>
<Base className="testid:disk-usage-text">
{formatBytesToInt(usedBytes)}
<Base> { Languages.t('components.disk_usage.used')} </Base>
</Base>
@@ -170,7 +170,7 @@ export default () => {
theme="primary"
className="w-full mb-2 justify-center"
style={{ boxShadow: '0 0 10px 0 rgba(0, 122, 255, 0.5)' }}
testClassId="sidebar-action-button-empty-trash"
testClassId="sidebar-action-button-upload"
>
<UploadIcon className="w-5 h-5 mr-2" /> {Languages.t('components.side_menu.buttons.upload')}
</Button>
@@ -179,7 +179,7 @@ export default () => {
size="lg"
theme="secondary"
className="w-full mb-2 justify-center"
testClassId="sidebar-action-button-open-modal"
testClassId="sidebar-action-button-open-create-modal"
>
<PlusIcon className="w-5 h-5 mr-2" /> {Languages.t('components.side_menu.buttons.create')}
</Button>
@@ -86,6 +86,7 @@ export default () => {
? activeClass
: '')
}
testClassId="sidebar-menu-my-drive"
>
<UserIcon className="w-5 h-5 mr-4" /> {Languages.t('components.side_menu.my_drive')}
</Button>
@@ -107,6 +108,7 @@ export default () => {
className={
'w-full mb-1 ' + (folderType === 'home' && viewId == 'root' ? activeClass : '')
}
testClassId="sidebar-menu-shared-drive"
>
<CloudIcon className="w-5 h-5 mr-4" /> {Languages.t('components.side_menu.home')}
</Button>
@@ -130,6 +132,7 @@ export default () => {
'w-full mb-1 ' +
(folderType === 'shared' && viewId == 'shared_with_me' ? activeClass : '')
}
testClassId="sidebar-menu-share-with-me"
>
<UserGroupIcon className="w-5 h-5 mr-4" />{' '}
{Languages.t('components.side_menu.shared_with_me')}
@@ -168,6 +171,7 @@ export default () => {
size="lg"
theme="white"
className={'w-full mb-1 ' + (viewId?.includes('trash') ? activeClass : '')}
testClassId="sidebar-menu-trash"
>
<TrashIcon className="w-5 h-5 mr-4 text-rose-500" />{' '}
{Languages.t('components.side_menu.trash')}
@@ -102,12 +102,12 @@ export const DrivePreview: React.FC<DrivePreviewProps> = ({ items }) => {
<Modal
open={isOpen}
closable={false}
className="bg-black bg-opacity-50 !sm:max-w-none !w-full !rounded-none !p-0"
className="bg-black bg-opacity-50 !sm:max-w-none !w-full !rounded-none !p-0 testid:preview-modal"
style={{ maxWidth: 'none', margin: 0, left: 0, top: 0, height: '100vh' }}
positioned={false}
>
<XIcon
className="z-10 cursor-pointer absolute right-5 top-5 w-20 h-20 text-white hover:text-black rounded-full p-1 bg-gray-500 hover:bg-white bg-opacity-25"
className="z-10 cursor-pointer absolute right-5 top-5 w-20 h-20 text-white hover:text-black rounded-full p-1 bg-gray-500 hover:bg-white bg-opacity-25 testid:preview-button-close"
onClick={() => {
close();
// small delay to allow the modal to close
@@ -135,10 +135,10 @@ export const DrivePreview: React.FC<DrivePreviewProps> = ({ items }) => {
</div>
<div className="z-10 p-5 bg-black w-full flex text-white">
<div className="grow overflow-hidden text-ellipsis">
<Text.Base noColor className="w-full block text-white whitespace-nowrap">
<Text.Base noColor className="w-full block text-white whitespace-nowrap testid:preview-file-name">
{name}
</Text.Base>
<Text.Info className="whitespace-nowrap">
<Text.Info className="whitespace-nowrap testid:preview-file-info">
{formatDate(
+(status.details?.item.added || '') ||
status.details?.item.last_version_cache.date_added,