diff --git a/web/src/components/auto-keywords-form-field.tsx b/web/src/components/auto-keywords-form-field.tsx index 9b8b9da73d..33373b1e1d 100644 --- a/web/src/components/auto-keywords-form-field.tsx +++ b/web/src/components/auto-keywords-form-field.tsx @@ -13,6 +13,8 @@ export function AutoKeywordsFormField() { min={0} tooltip={t('autoKeywordsTip')} layout={FormLayout.Horizontal} + sliderTestId="ds-settings-parser-auto-keyword-slider" + numberInputTestId="ds-settings-parser-auto-keyword-input" > ); } @@ -28,6 +30,8 @@ export function AutoQuestionsFormField() { min={0} tooltip={t('autoQuestionsTip')} layout={FormLayout.Horizontal} + sliderTestId="ds-settings-parser-auto-question-slider" + numberInputTestId="ds-settings-parser-auto-question-input" > ); } diff --git a/web/src/components/avatar-upload.tsx b/web/src/components/avatar-upload.tsx index bee9c85f0c..95e9d9c3a7 100644 --- a/web/src/components/avatar-upload.tsx +++ b/web/src/components/avatar-upload.tsx @@ -18,10 +18,25 @@ type AvatarUploadProps = { value?: string; onChange?: (value: string) => void; tips?: string; + uploadInputTestId?: string; + removeButtonTestId?: string; + cropModalTestId?: string; + cropModalOkButtonTestId?: string; }; export const AvatarUpload = forwardRef( - function AvatarUpload({ value, onChange, tips }, ref) { + function AvatarUpload( + { + value, + onChange, + tips, + uploadInputTestId, + removeButtonTestId, + cropModalTestId, + cropModalOkButtonTestId, + }, + ref, + ) { const { t } = useTranslation(); const [avatarBase64Str, setAvatarBase64Str] = useState(''); // Avatar Image base64 const [isCropModalOpen, setIsCropModalOpen] = useState(false); @@ -285,6 +300,7 @@ export const AvatarUpload = forwardRef( className="border-background focus-visible:border-background absolute -top-2 -right-2 size-6 rounded-full border-2 shadow-none z-10" aria-label="Remove image" type="button" + data-testid={removeButtonTestId} > @@ -299,6 +315,7 @@ export const AvatarUpload = forwardRef( className="absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer" onChange={handleChange} ref={ref} + data-testid={uploadInputTestId} />
@@ -318,6 +335,8 @@ export const AvatarUpload = forwardRef( size="small" onCancel={handleCancelCrop} onOk={handleCrop} + testId={cropModalTestId} + okButtonTestId={cropModalOkButtonTestId} // footer={ //
//
@@ -99,7 +100,10 @@ export function ChildrenDelimiterForm() {
- +
diff --git a/web/src/components/confirm-delete-dialog.tsx b/web/src/components/confirm-delete-dialog.tsx index 616ff7a072..eacbb83986 100644 --- a/web/src/components/confirm-delete-dialog.tsx +++ b/web/src/components/confirm-delete-dialog.tsx @@ -27,6 +27,9 @@ interface IProps { }; okButtonText?: string; cancelButtonText?: string; + testId?: string; + confirmButtonTestId?: string; + cancelButtonTestId?: string; } export function ConfirmDeleteDialog({ @@ -41,6 +44,9 @@ export function ConfirmDeleteDialog({ content, okButtonText, cancelButtonText, + testId, + confirmButtonTestId, + cancelButtonTestId, }: IProps & DialogProps) { const { t } = useTranslation(); @@ -60,6 +66,7 @@ export function ConfirmDeleteDialog({ onSelect={(e) => e.preventDefault()} onClick={(e) => e.stopPropagation()} className="bg-bg-base " + data-testid={testId ?? 'confirm-delete-dialog'} > @@ -86,12 +93,20 @@ export function ConfirmDeleteDialog({ )} - + {cancelButtonText || t('common.cancel')} {okButtonText || t('common.delete')} diff --git a/web/src/components/edit-tag/index.tsx b/web/src/components/edit-tag/index.tsx index decfbb968b..cadd34ee8c 100644 --- a/web/src/components/edit-tag/index.tsx +++ b/web/src/components/edit-tag/index.tsx @@ -13,10 +13,15 @@ interface EditTagsProps { value?: string[]; onChange?: (tags: string[]) => void; disabled?: boolean; + addButtonTestId?: string; + inputTestId?: string; } const EditTag = React.forwardRef( - function EditTag({ value = [], onChange, disabled }, ref) { + function EditTag( + { value = [], onChange, disabled, addButtonTestId, inputTestId }, + ref, + ) { const [inputVisible, setInputVisible] = useState(false); const [inputValue, setInputValue] = useState(''); const inputRef = useRef(null); @@ -92,6 +97,7 @@ const EditTag = React.forwardRef( onChange={handleInputChange} onBlur={handleInputConfirm} disabled={disabled} + data-testid={inputTestId} onKeyDown={(e) => { if (e?.key === 'Enter') { handleInputConfirm(); @@ -107,6 +113,7 @@ const EditTag = React.forwardRef( className="w-fit flex items-center justify-center gap-2 bg-bg-card border-border-button border" onClick={showInput} disabled={disabled} + data-testid={addButtonTestId} > diff --git a/web/src/components/entity-types-form-field.tsx b/web/src/components/entity-types-form-field.tsx index 0cc6b9f071..6838ce8ac1 100644 --- a/web/src/components/entity-types-form-field.tsx +++ b/web/src/components/entity-types-form-field.tsx @@ -11,9 +11,13 @@ import { type EntityTypesFormFieldProps = { name?: string; + addButtonTestId?: string; + inputTestId?: string; }; export function EntityTypesFormField({ name = 'parser_config.entity_types', + addButtonTestId, + inputTestId, }: EntityTypesFormFieldProps) { const { t } = useTranslate('knowledgeConfiguration'); const form = useFormContext(); @@ -31,7 +35,11 @@ export function EntityTypesFormField({
- +
diff --git a/web/src/components/excel-to-html-form-field.tsx b/web/src/components/excel-to-html-form-field.tsx index 13ff8b821e..7e4bca3032 100644 --- a/web/src/components/excel-to-html-form-field.tsx +++ b/web/src/components/excel-to-html-form-field.tsx @@ -37,6 +37,7 @@ export function ExcelToHtmlFormField() { diff --git a/web/src/components/layout-recognize-form-field.tsx b/web/src/components/layout-recognize-form-field.tsx index e122055e4c..7b6a077fb3 100644 --- a/web/src/components/layout-recognize-form-field.tsx +++ b/web/src/components/layout-recognize-form-field.tsx @@ -6,8 +6,8 @@ import { camelCase } from 'lodash'; import { ReactNode, useMemo } from 'react'; import { useFormContext } from 'react-hook-form'; import { MinerUOptionsFormField } from './mineru-options-form-field'; -import { PaddleOCROptionsFormField } from './paddleocr-options-form-field'; import { SelectWithSearch } from './originui/select-with-search'; +import { PaddleOCROptionsFormField } from './paddleocr-options-form-field'; import { FormControl, FormField, @@ -30,6 +30,7 @@ export function LayoutRecognizeFormField({ label, showMineruOptions = true, showPaddleocrOptions = true, + testId, }: { name?: string; horizontal?: boolean; @@ -37,6 +38,7 @@ export function LayoutRecognizeFormField({ label?: ReactNode; showMineruOptions?: boolean; showPaddleocrOptions?: boolean; + testId?: string; }) { const form = useFormContext(); @@ -106,6 +108,7 @@ export function LayoutRecognizeFormField({ diff --git a/web/src/components/max-token-number-from-field.tsx b/web/src/components/max-token-number-from-field.tsx index b01598d934..c9ed7212c9 100644 --- a/web/src/components/max-token-number-from-field.tsx +++ b/web/src/components/max-token-number-from-field.tsx @@ -5,9 +5,16 @@ import { SliderInputFormField } from './slider-input-form-field'; interface IProps { initialValue?: number; max?: number; + sliderTestId?: string; + numberInputTestId?: string; } -export function MaxTokenNumberFormField({ max = 2048, initialValue }: IProps) { +export function MaxTokenNumberFormField({ + max = 2048, + initialValue, + sliderTestId, + numberInputTestId, +}: IProps) { const { t } = useTranslate('knowledgeConfiguration'); return ( @@ -18,6 +25,8 @@ export function MaxTokenNumberFormField({ max = 2048, initialValue }: IProps) { max={max} defaultValue={initialValue ?? 0} layout={FormLayout.Horizontal} + sliderTestId={sliderTestId} + numberInputTestId={numberInputTestId} > ); } diff --git a/web/src/components/page-rank-form-field.tsx b/web/src/components/page-rank-form-field.tsx index ea7d345905..42c6d00a24 100644 --- a/web/src/components/page-rank-form-field.tsx +++ b/web/src/components/page-rank-form-field.tsx @@ -14,6 +14,8 @@ export function PageRankFormField() { max={100} min={0} layout={FormLayout.Horizontal} + sliderTestId="ds-settings-parser-page-rank-slider" + numberInputTestId="ds-settings-parser-page-rank-input" > ); } diff --git a/web/src/components/parse-configuration/graph-rag-form-fields.tsx b/web/src/components/parse-configuration/graph-rag-form-fields.tsx index 8f1fcdb434..1c41877392 100644 --- a/web/src/components/parse-configuration/graph-rag-form-fields.tsx +++ b/web/src/components/parse-configuration/graph-rag-form-fields.tsx @@ -147,7 +147,11 @@ const GraphRagItems = ({ > {useRaptor && ( <> - + @@ -200,6 +205,7 @@ const GraphRagItems = ({ @@ -229,6 +235,7 @@ const GraphRagItems = ({ diff --git a/web/src/components/parse-configuration/raptor-form-fields.tsx b/web/src/components/parse-configuration/raptor-form-fields.tsx index dc089cdb0a..110493009f 100644 --- a/web/src/components/parse-configuration/raptor-form-fields.tsx +++ b/web/src/components/parse-configuration/raptor-form-fields.tsx @@ -129,8 +129,18 @@ const RaptorFormFields = ({
- {t('scopeDataset')} - {t('scopeSingleFile')} + + {t('scopeDataset')} + + + {t('scopeSingleFile')} +
@@ -167,6 +177,7 @@ const RaptorFormFields = ({ onChange={(e) => { field.onChange(e?.target?.value); }} + data-testid="ds-settings-raptor-prompt-textarea" /> @@ -186,6 +197,8 @@ const RaptorFormFields = ({ max={2048} min={0} layout={FormLayout.Horizontal} + sliderTestId="ds-settings-raptor-max-token-slider" + numberInputTestId="ds-settings-raptor-max-token-input" > } diff --git a/web/src/components/slider-input-form-field.tsx b/web/src/components/slider-input-form-field.tsx index 2b9980eb12..f45290eb07 100644 --- a/web/src/components/slider-input-form-field.tsx +++ b/web/src/components/slider-input-form-field.tsx @@ -27,6 +27,8 @@ type SliderInputFormFieldProps = { className?: string; numberInputClassName?: string; percentage?: boolean; + sliderTestId?: string; + numberInputTestId?: string; } & FormLayoutType; export const SliderInputFormField = forwardRef< @@ -46,6 +48,8 @@ export const SliderInputFormField = forwardRef< numberInputClassName, layout = FormLayout.Horizontal, percentage = false, + sliderTestId, + numberInputTestId, }, ref, ) => { @@ -95,6 +99,7 @@ export const SliderInputFormField = forwardRef< max={displayMax} min={displayMin} step={displayStep} + data-testid={sliderTestId} > @@ -118,6 +123,7 @@ export const SliderInputFormField = forwardRef< ); } }} + data-testid={numberInputTestId} > diff --git a/web/src/components/ui/radio.tsx b/web/src/components/ui/radio.tsx index 64fa7d14f4..edcfb502d0 100644 --- a/web/src/components/ui/radio.tsx +++ b/web/src/components/ui/radio.tsx @@ -13,9 +13,17 @@ type RadioProps = { disabled?: boolean; onChange?: (checked: boolean) => void; children?: React.ReactNode; + testId?: string; }; -function Radio({ value, checked, disabled, onChange, children }: RadioProps) { +function Radio({ + value, + checked, + disabled, + onChange, + children, + testId, +}: RadioProps) { const groupContext = useContext(RadioGroupContext); const isControlled = checked !== undefined; // const [internalChecked, setInternalChecked] = useState(false); @@ -54,6 +62,7 @@ function Radio({ value, checked, disabled, onChange, children }: RadioProps) { mergedDisabled && 'border-muted', )} onClick={handleClick} + data-testid={testId} > {isChecked && (
diff --git a/web/src/components/ui/select.tsx b/web/src/components/ui/select.tsx index b4bd825ab7..71e28fe7cc 100644 --- a/web/src/components/ui/select.tsx +++ b/web/src/components/ui/select.tsx @@ -203,6 +203,8 @@ export type RAGFlowSelectProps = Partial & { contentProps?: React.ComponentPropsWithoutRef; triggerClassName?: string; onlyShowSelectedIcon?: boolean; + triggerTestId?: string; + optionTestIdPrefix?: string; } & SelectPrimitive.SelectProps; /** @@ -237,6 +239,8 @@ export const RAGFlowSelect = forwardRef< // defaultValue, triggerClassName, onlyShowSelectedIcon = false, + triggerTestId, + optionTestIdPrefix, }, ref, ) { @@ -301,6 +305,7 @@ export const RAGFlowSelect = forwardRef< allowClear={allowClear} ref={ref} className={triggerClassName} + data-testid={triggerTestId} > {label} @@ -313,6 +318,11 @@ export const RAGFlowSelect = forwardRef< value={o.value as RAGFlowSelectOptionType['value']} key={o.value} disabled={o.disabled} + data-testid={ + optionTestIdPrefix + ? `${optionTestIdPrefix}-${o.value}` + : undefined + } >
{o.icon} @@ -326,7 +336,16 @@ export const RAGFlowSelect = forwardRef< {o.label} {o.options.map((x) => ( - + {x.label} ))} diff --git a/web/src/pages/dataset/components/metedata/interface.ts b/web/src/pages/dataset/components/metedata/interface.ts index f5b65b194c..6b759a64c5 100644 --- a/web/src/pages/dataset/components/metedata/interface.ts +++ b/web/src/pages/dataset/components/metedata/interface.ts @@ -73,6 +73,11 @@ export type IManageModalProps = { builtInMetadata?: IBuiltInMetadataItem[]; success?: (data: any) => void; secondTitle?: ReactNode; + testId?: string; + okButtonTestId?: string; + addButtonTestId?: string; + nestedModalTestId?: string; + nestedModalOkButtonTestId?: string; }; export interface IManageValuesProps { @@ -97,6 +102,9 @@ export interface IManageValuesProps { type?: MetadataValueType, ) => void; addDeleteValue: (key: string, value: string) => void; + testId?: string; + okButtonTestId?: string; + addValueButtonTestId?: string; } export interface DeleteOperation { diff --git a/web/src/pages/dataset/components/metedata/manage-modal.tsx b/web/src/pages/dataset/components/metedata/manage-modal.tsx index 3fb8fca812..7fa3fc6bce 100644 --- a/web/src/pages/dataset/components/metedata/manage-modal.tsx +++ b/web/src/pages/dataset/components/metedata/manage-modal.tsx @@ -68,6 +68,11 @@ export const ManageMetadataModal = (props: IManageModalProps) => { success, documentIds, secondTitle, + testId, + okButtonTestId, + addButtonTestId, + nestedModalTestId, + nestedModalOkButtonTestId, } = props; const { t } = useTranslation(); const [valueData, setValueData] = useState({ @@ -304,6 +309,8 @@ export const ManageMetadataModal = (props: IManageModalProps) => { onCancel={hideModal} maskClosable={false} okText={t('common.save')} + testId={testId} + okButtonTestId={okButtonTestId} onOk={async () => { const res = await handleSave({ callback: hideModal, @@ -337,6 +344,7 @@ export const ManageMetadataModal = (props: IManageModalProps) => { className="border border-border-button" type="button" onClick={handAddValueRow} + data-testid={addButtonTestId} > {t('common.add')} @@ -571,6 +579,9 @@ export const ManageMetadataModal = (props: IManageModalProps) => { isShowValueSwitch={isShowValueSwitch} isShowType={true} isVerticalShowValue={isVerticalShowValue} + testId={nestedModalTestId} + okButtonTestId={nestedModalOkButtonTestId} + addValueButtonTestId="ds-settings-metadata-add-modal-add-value-btn" // handleDeleteSingleValue={handleDeleteSingleValue} // handleDeleteSingleRow={handleDeleteSingleRow} /> diff --git a/web/src/pages/dataset/components/metedata/manage-values-modal.tsx b/web/src/pages/dataset/components/metedata/manage-values-modal.tsx index 97383e60a6..f2a74a1c9e 100644 --- a/web/src/pages/dataset/components/metedata/manage-values-modal.tsx +++ b/web/src/pages/dataset/components/metedata/manage-values-modal.tsx @@ -123,6 +123,9 @@ export const ManageValuesModal = (props: IManageValuesProps) => { isVerticalShowValue, isShowType, type: metadataType, + testId, + okButtonTestId, + addValueButtonTestId, } = props; const { metaData, @@ -251,6 +254,8 @@ export const ManageValuesModal = (props: IManageValuesProps) => { onOk={() => formRef.current?.submit(handleSubmit)} maskClosable={false} footer={null} + testId={testId} + okButtonTestId={okButtonTestId} >
{!isEditField && ( @@ -281,6 +286,7 @@ export const ManageValuesModal = (props: IManageValuesProps) => { variant={'ghost'} className="border border-border-button" onClick={handleAddValue} + data-testid={addValueButtonTestId} > diff --git a/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx b/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx index 45db84f498..66ad986f93 100644 --- a/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx +++ b/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx @@ -107,11 +107,13 @@ export const EmbeddingSelect = ({ field, name, disabled = false, + testId, }: { isEdit: boolean; field: FieldValues; name?: string; disabled?: boolean; + testId?: string; }) => { const { t } = useTranslate('knowledgeConfiguration'); const form = useFormContext(); @@ -149,6 +151,7 @@ export const EmbeddingSelect = ({ value={field.value} options={embeddingModelOptions} placeholder={t('embeddingModelPlaceholder')} + testId={testId} /> ); @@ -188,6 +191,7 @@ export function EmbeddingModelItem({ line = 1, isEdit }: IProps) { isEdit={!!isEdit} field={field} disabled={disabled} + testId="ds-settings-basic-embedding-model-select" >
@@ -313,6 +317,7 @@ export function EnableTocToggle() {
@@ -345,6 +350,8 @@ export function ImageContextWindow() { defaultValue={0} min={0} max={256} + sliderTestId="ds-settings-parser-image-table-context-window-slider" + numberInputTestId="ds-settings-parser-image-table-context-window-input" />
@@ -365,6 +372,8 @@ export function OverlappedPercent() { label={t('knowledgeConfiguration.overlappedPercent')} max={0.3} step={0.01} + sliderTestId="ds-settings-parser-overlapped-percent-slider" + numberInputTestId="ds-settings-parser-overlapped-percent-input" > ); } @@ -439,7 +448,12 @@ export function AutoMetadata({ tooltip: t('knowledgeConfiguration.autoMetadataTip'), render: (fieldProps: ControllerRenderProps) => (
-
@@ -61,6 +64,7 @@ export function GeneralForm() {
@@ -74,7 +78,12 @@ export function GeneralForm() { {t('setting.avatar')} - +
@@ -99,7 +108,10 @@ export function GeneralForm() { {t('flow.description')} - +
diff --git a/web/src/pages/dataset/dataset-setting/index.tsx b/web/src/pages/dataset/dataset-setting/index.tsx index b4a8590538..b3ce08ea09 100644 --- a/web/src/pages/dataset/dataset-setting/index.tsx +++ b/web/src/pages/dataset/dataset-setting/index.tsx @@ -334,6 +334,7 @@ export default function DatasetSettings() {