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
@@ -13,6 +13,7 @@ interface AvatarProps extends React.InputHTMLAttributes<HTMLInputElement> {
icon?: JSX.Element | false;
title?: string;
nogradient?: boolean;
testClassId?: string;
}
const sizes = { xl: 24, lg: 14, md: 10, sm: 9, xs: 6 };
@@ -68,12 +69,13 @@ export default function Avatar(props: AvatarProps) {
className += ' ';
return (
<div
{...restProps}
{..._.omit(restProps, 'testClassId')}
style={style}
className={
className +
' text-white overflow-hidden flex items-center justify-center ' +
addedClassName
addedClassName + ' ' +
(props.testClassId ? `testid:${props.testClassId}` : '')
}
>
{props.icon}
@@ -83,18 +85,18 @@ export default function Avatar(props: AvatarProps) {
if (props.avatar) {
return (
<div {...restProps}>
<div {..._.omit(restProps, 'testClassId')}>
<img
alt={props.title}
src={props.avatar}
className={className + ' object-cover ' + addedClassName}
className={className + ' object-cover ' + addedClassName + ' ' + (props.testClassId ? `testid:${props.testClassId}` : '')}
/>
</div>
);
}
return (
<div className={className + ' ' + addedClassName} {...restProps} style={style}>
<div className={className + ' ' + addedClassName + ' ' + (props.testClassId ? `testid:${props.testClassId}` : '')} {..._.omit(restProps, 'testClassId')} style={style}>
<div className={lettersClass}>{letters.toUpperCase()}</div>
</div>
);
@@ -59,6 +59,8 @@ export const Button = (props: ButtonProps) => {
else className = className + ' w-9 !p-0 justify-center';
}
const testId = props.testClassId ? `testid:${props.testClassId}` : '';
return (
<button
type="button"
@@ -68,7 +70,7 @@ export const Button = (props: ButtonProps) => {
' ' +
props.className +
' ' +
`testid:${props.testClassId}`
testId
}
disabled={disabled}
{..._.omit(props, 'loading', 'children', 'className', 'icon', 'iconSize', 'testClassId')}
@@ -24,10 +24,9 @@ export const CheckboxSlider = (props: CheckboxSliderProps) => {
// @author https://tw-elements.com/docs/react/forms/switch/
className={[
"!bg-none mr-2 mt-[0.3rem] h-7 w-14 appearance-none rounded-[0.9rem] bg-neutral-300 before:pointer-events-none before:absolute before:h-7 before:w-5 before:rounded-full before:bg-transparent before:content-[''] after:absolute after:z-[2] after:mt-[0.2rem] after:ml-[0.2rem] after:h-5 after:w-5 after:rounded-full after:border-none after:bg-neutral-100 after:shadow-[0_0px_3px_0_rgb(0_0_0_/_7%),_0_2px_2px_0_rgb(0_0_0_/_4%)] after:transition-[background-color_0.2s,transform_0.2s] after:content-[''] checked:bg-primary checked:after:absolute checked:after:z-[2] checked:after:ml-[1.9625rem] checked:after:w-5 checked:after:rounded-full checked:after:border-none checked:after:bg-primary checked:after:shadow-[0_3px_1px_-2px_rgba(0,0,0,0.2),_0_2px_2px_0_rgba(0,0,0,0.14),_0_1px_5px_0_rgba(0,0,0,0.12)] checked:after:transition-[background-color_0.2s,transform_0.2s] checked:after:content-[''] hover:cursor-pointer dark:bg-neutral-600 dark:after:bg-white dark:checked:bg-primary dark:checked:after:bg-primary disabled:cursor-default disabled:opacity-25 !focus:shadow-none",
`testid:${props.testClassId}`
props.testClassId ? `testid:${props.testClassId}` : ''
].join(' ')}
checked={!!props.checked}
disabled={props.disabled}
data-checkbox-id={props.testClassId}
/>)
}
@@ -60,15 +60,16 @@ export const Input = (props: InputProps) => {
else inputClassName = inputClassName + ' h-9';
}
const testId = props.testClassId ? `testid:${props.testClassId}` : '';
return (
<>
{props.inputComponent ||
(props.multiline ? (
<textarea
ref={props.inputRef as React.Ref<HTMLTextAreaElement>}
className={inputClassName + ' ' + props.inputClassName + ' ' + props.className}
className={inputClassName + ' ' + props.inputClassName + ' ' + props.className + ' ' + testId}
{..._.omit(props as any, 'label', 'inputClassName', 'inputRef', 'className', 'value', 'size', 'testClassId')}
data-input-id={props.testClassId}
>
{props.value}
</textarea>
@@ -76,7 +77,7 @@ export const Input = (props: InputProps) => {
<input
ref={props.inputRef as React.Ref<HTMLInputElement>}
type="text"
className={`${inputClassName} ${props.inputClassName} ${props.className} testid:${props.testClassId}`}
className={`${inputClassName} ${props.inputClassName} ${props.className} ${props.testClassId ? `testid:${props.testClassId}` : ''}`}
{..._.omit(props, 'label', 'inputClassName', 'inputRef', 'className', 'size', 'testClassId')}
/>
))}
@@ -23,11 +23,14 @@ export default class Button extends React.Component {
) {
className += ' small';
}
const testId = this.props.testClassId ? `testid:${this.props.testClassId}` : '';
return (
<button
ref={this.props.refButton}
{...this.props}
className={'button no-tw ' + className + ` testid:${this.props.testClassId}`}
className={'button no-tw ' + className + ' ' + testId}
onClick={evt => {
evt.target.blur();
this.props.onClick && this.props.onClick(evt);
@@ -58,6 +58,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
}}
>
<Row
className="testid:pending-files-row"
justify="space-between"
align="middle"
wrap={false}
@@ -75,6 +76,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
maxWidth: isPendingFileStatusPause(pendingFile.status) ? 130 : 160,
verticalAlign: 'middle',
}}
className="testid:pending-file-name"
>
{capitalize(pendingFile?.originalFile.name)}
</Text>
@@ -156,6 +158,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
alignItems: 'center',
justifyContent: 'center',
}}
className="testid:pending-file-button-status"
/>
</Tooltip>
) : (
@@ -191,6 +194,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
icon={<Trash2 size={16} color={'var(--black)'} />}
onClick={() => cancelUpload(pendingFileState.id)}
style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}
className="testid:pending-file-button-cancel"
/>
</Tooltip>
) : (
@@ -198,7 +202,7 @@ export default ({ pendingFileState, pendingFile }: PropsType) => {
)}
</Col>
</Row>
<div className="file-progress-bar-container">
<div className="file-progress-bar-container testid:pending-file-progress-bar">
<Progress
type="line"
className="file-progress-bar"
@@ -63,6 +63,8 @@ export default class Input extends Component {
);
}
const testId = this.props.testClassId ? `testid:${this.props.testClassId}` : '';
return (
<input
ref={node => {
@@ -76,7 +78,7 @@ export default class Input extends Component {
}
this.onKeyDown(evt);
}}
className={'input ' + (className || '') + ` testid:${this.props.testClassId}`}
className={'input ' + (className || '') + ' ' + testId}
onBlur={this.props.onBlur}
onChange={this.props.onChange}
/>
@@ -58,7 +58,7 @@ export default class MenuComponent extends React.Component {
ref={node => (this.original_menu = node)}
className={
'menu-list ' + (this.props.withFrame ? 'as_frame text-black bg-white dark:bg-zinc-900 dark:text-white rounded-lg ' : '') + this.props.animationClass + ' ' +
`testid:${this.props.testClassId}`
`${this.props.testClassId ? `testid:${this.props.testClassId}` : ''}`
}
>
{(this.props.menu || [])
@@ -77,7 +77,7 @@ export default class MenuComponent extends React.Component {
<div
key={'menu_' + index}
ref={node => (item.ref = node)}
className={'menu-text ' + item.className}
className={'menu-text ' + item.className + ' testid:menu-item'}
onMouseEnter={evt => {
this.hoverMenu(item.ref, item);
}}
@@ -87,14 +87,14 @@ export default class MenuComponent extends React.Component {
{typeof item.icon === 'string' ? <Icon type={item.icon} /> : item.icon}
</div>
)}
<div className="text">{item.text}</div>
<div className={`text testid:menu-item-${item.id}`}>{item.text}</div>
</div>
);
} else if (item.type == 'react-element') {
return (
<div
key={'menu_' + index}
className={'menu-custom ' + item.className}
className={'menu-custom ' + item.className + ' testid:menu-item'}
onClick={item.onClick}
>
{typeof item.reactElement == 'function'
@@ -115,7 +115,8 @@ export default class MenuComponent extends React.Component {
this.last_hovered == item
? 'hovered '
: '') +
(item.selected ? 'selected ' : '')
(item.selected ? 'selected ' : '') +
' testid:menu-item'
}
onMouseEnter={evt => {
this.hoverMenu(item.ref, item);
@@ -134,7 +135,7 @@ export default class MenuComponent extends React.Component {
<Emojione type={item.emoji} />
</div>
)}
<div className="text">{item.text}</div>
<div className={`text testid:menu-item-${item.id}`}>{item.text}</div>
<div className="more">
{item.rightIcon && <Icon type={item.rightIcon} />}
{item.submenu && !item.submenu_replace && <Icon type="angle-right" />}
@@ -51,7 +51,7 @@ export default (props: { driveItem: DriveItem & { user?: UserType }}) => {
textToHighlight={name}
/>
</Text.Base>
<Text.Info className="block">
<Text.Info className="block testid:drive-item-file">
{extension?.toLocaleUpperCase()} {formatDate(parseInt(file?.last_modified))} {' '}
{formatSize(file?.size)}
</Text.Info>
@@ -69,6 +69,7 @@ export default (props: { driveItem: DriveItem & { user?: UserType }}) => {
theme="outline"
className="w-9 !p-0 flex items-center justify-center ml-2 rounded-full border-none"
onClick={() => onDriveItemDownloadClick(file)}
testClassId="drive-item-button-download"
>
<DownloadIcon className="text-blue-500 w-6 h-6" />
</Button>
@@ -4,7 +4,7 @@ import { UserType } from '@features/users/types/user';
export default ({ user }: { user?: UserType }) => {
return (
<div className="flex overflow-hidden whitespace-nowrap text-ellipsis">
<div className="flex overflow-hidden whitespace-nowrap text-ellipsis testid:result-context">
{!!user && <>{UsersService.getFullName(user)}</>}
</div>
);
@@ -38,6 +38,7 @@ export const SearchInput = () => {
value={input.query}
className={className}
placeholder={Languages.t('scenes.app.mainview.quick_search_placeholder')}
testClassId="search-input-quick-search"
/>
)}
/>
@@ -8,7 +8,7 @@ export default () => {
const { open, setOpen } = useSearchModal();
return (
<Modal open={open} onClose={() => setOpen(false)} className="sm:w-[80vw] sm:max-w-4xl">
<Modal open={open} onClose={() => setOpen(false)} className="sm:w-[80vw] sm:max-w-4xl testid:search-popup">
<SearchBox/>
</Modal>
);
@@ -16,7 +16,7 @@ export default () => {
return (
<div>
{!!isRecent && (
<Text.Subtitle className="block">
<Text.Subtitle className="block testid:drive-recent-files">
{Languages.t('components.searchpopup.recent_files')}
</Text.Subtitle>
)}
@@ -191,7 +191,7 @@ export default class UploadZone extends React.Component<PropsType, StateType> {
<div
ref={node => node && (this.node = node)}
style={this.props.style}
className={classNames('upload_drop_zone', this.props.className, `testid:${this.props.testClassId}`)}
className={classNames('upload_drop_zone', this.props.className, this.props.testClassId ? `testid:${this.props.testClassId}` : '')}
onClick={() => {
if (!this.props.disableClick) {
this.open();
@@ -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,