playwright : add data-testids for new test (#13364)

### What problem does this PR solve?

add data-testids for new test

### Type of change

- [x] Other (please describe): add data-testids for new test
This commit is contained in:
Idriss Sbaaoui
2026-03-04 19:28:36 +08:00
committed by GitHub
parent c99b53064d
commit b3a7332c08
24 changed files with 215 additions and 18 deletions

View File

@ -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"
></SliderInputFormField>
);
}
@ -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"
></SliderInputFormField>
);
}

View File

@ -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<HTMLInputElement, AvatarUploadProps>(
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<HTMLInputElement, AvatarUploadProps>(
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}
>
<LucideX className="size-3" />
</Button>
@ -299,6 +315,7 @@ export const AvatarUpload = forwardRef<HTMLInputElement, AvatarUploadProps>(
className="absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer"
onChange={handleChange}
ref={ref}
data-testid={uploadInputTestId}
/>
</div>
<div className="margin-1 text-sm text-text-secondary">
@ -318,6 +335,8 @@ export const AvatarUpload = forwardRef<HTMLInputElement, AvatarUploadProps>(
size="small"
onCancel={handleCancelCrop}
onOk={handleCrop}
testId={cropModalTestId}
okButtonTestId={cropModalOkButtonTestId}
// footer={
// <div className="flex justify-end space-x-2">
// <Button variant="secondary" onClick={handleCancelCrop}>

View File

@ -75,6 +75,7 @@ export function ChildrenDelimiterForm() {
onChange(checked);
}}
{...restProps}
data-testid="ds-settings-parser-child-chunk-switch"
/>
</FormControl>
</div>
@ -99,7 +100,10 @@ export function ChildrenDelimiterForm() {
</FormLabel>
<div className="w-3/4">
<FormControl>
<DelimiterInput {...field} />
<DelimiterInput
{...field}
data-testid="ds-settings-parser-child-chunk-delimiter-input"
/>
</FormControl>
</div>
</div>

View File

@ -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'}
>
<AlertDialogHeader className="space-y-5">
<AlertDialogTitle>
@ -86,12 +93,20 @@ export function ConfirmDeleteDialog({
)}
</AlertDialogHeader>
<AlertDialogFooter className="px-5 flex items-center gap-2">
<AlertDialogCancel onClick={onCancel}>
<AlertDialogCancel
onClick={onCancel}
data-testid={
cancelButtonTestId ?? 'confirm-delete-dialog-cancel-btn'
}
>
{cancelButtonText || t('common.cancel')}
</AlertDialogCancel>
<AlertDialogAction
className="bg-state-error text-text-primary hover:text-text-primary hover:bg-state-error"
onClick={onOk}
data-testid={
confirmButtonTestId ?? 'confirm-delete-dialog-confirm-btn'
}
>
{okButtonText || t('common.delete')}
</AlertDialogAction>

View File

@ -13,10 +13,15 @@ interface EditTagsProps {
value?: string[];
onChange?: (tags: string[]) => void;
disabled?: boolean;
addButtonTestId?: string;
inputTestId?: string;
}
const EditTag = React.forwardRef<HTMLDivElement, EditTagsProps>(
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<HTMLInputElement>(null);
@ -92,6 +97,7 @@ const EditTag = React.forwardRef<HTMLDivElement, EditTagsProps>(
onChange={handleInputChange}
onBlur={handleInputConfirm}
disabled={disabled}
data-testid={inputTestId}
onKeyDown={(e) => {
if (e?.key === 'Enter') {
handleInputConfirm();
@ -107,6 +113,7 @@ const EditTag = React.forwardRef<HTMLDivElement, EditTagsProps>(
className="w-fit flex items-center justify-center gap-2 bg-bg-card border-border-button border"
onClick={showInput}
disabled={disabled}
data-testid={addButtonTestId}
>
<PlusOutlined />
</Button>

View File

@ -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({
</FormLabel>
<div className="w-3/4">
<FormControl>
<EditTag {...field}></EditTag>
<EditTag
{...field}
addButtonTestId={addButtonTestId}
inputTestId={inputTestId}
></EditTag>
</FormControl>
</div>
</div>

View File

@ -37,6 +37,7 @@ export function ExcelToHtmlFormField() {
<Switch
checked={field.value}
onCheckedChange={field.onChange}
data-testid="ds-settings-parser-excel-to-html-switch"
></Switch>
</FormControl>
</div>

View File

@ -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({
<SelectWithSearch
{...field}
options={options}
testId={testId}
></SelectWithSearch>
</FormControl>
</div>

View File

@ -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}
></SliderInputFormField>
);
}

View File

@ -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"
></SliderInputFormField>
);
}

View File

@ -147,7 +147,11 @@ const GraphRagItems = ({
></UseGraphRagFormField>
{useRaptor && (
<>
<EntityTypesFormField name="parser_config.graphrag.entity_types"></EntityTypesFormField>
<EntityTypesFormField
name="parser_config.graphrag.entity_types"
addButtonTestId="ds-settings-graph-entity-types-add-btn"
inputTestId="ds-settings-graph-entity-types-input"
></EntityTypesFormField>
<FormField
control={form.control}
name="parser_config.graphrag.method"
@ -171,6 +175,7 @@ const GraphRagItems = ({
<RAGFlowSelect
{...field}
options={methodOptions}
triggerTestId="ds-settings-graph-method-select"
></RAGFlowSelect>
</FormControl>
</div>
@ -200,6 +205,7 @@ const GraphRagItems = ({
<Switch
checked={field.value}
onCheckedChange={field.onChange}
data-testid="ds-settings-graph-entity-resolution-switch"
></Switch>
</FormControl>
</div>
@ -229,6 +235,7 @@ const GraphRagItems = ({
<Switch
checked={field.value}
onCheckedChange={field.onChange}
data-testid="ds-settings-graph-community-reports-switch"
></Switch>
</FormControl>
</div>

View File

@ -129,8 +129,18 @@ const RaptorFormFields = ({
<FormControl>
<Radio.Group {...field} disabled={!!data?.finish_at}>
<div className={'flex gap-4 w-full text-text-secondary '}>
<Radio value="dataset">{t('scopeDataset')}</Radio>
<Radio value="file">{t('scopeSingleFile')}</Radio>
<Radio
value="dataset"
testId="ds-settings-raptor-generation-scope-option-dataset"
>
{t('scopeDataset')}
</Radio>
<Radio
value="file"
testId="ds-settings-raptor-generation-scope-option-document"
>
{t('scopeSingleFile')}
</Radio>
</div>
</Radio.Group>
</FormControl>
@ -167,6 +177,7 @@ const RaptorFormFields = ({
onChange={(e) => {
field.onChange(e?.target?.value);
}}
data-testid="ds-settings-raptor-prompt-textarea"
/>
</FormControl>
</div>
@ -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"
></SliderInputFormField>
<SliderInputFormField
name={'parser_config.raptor.threshold'}
@ -195,6 +208,8 @@ const RaptorFormFields = ({
max={1}
min={0}
layout={FormLayout.Horizontal}
sliderTestId="ds-settings-raptor-threshold-slider"
numberInputTestId="ds-settings-raptor-threshold-input"
></SliderInputFormField>
<SliderInputFormField
name={'parser_config.raptor.max_cluster'}
@ -203,6 +218,8 @@ const RaptorFormFields = ({
max={1024}
min={1}
layout={FormLayout.Horizontal}
sliderTestId="ds-settings-raptor-max-cluster-slider"
numberInputTestId="ds-settings-raptor-max-cluster-input"
></SliderInputFormField>
<FormField
control={form.control}
@ -220,11 +237,13 @@ const RaptorFormFields = ({
className="w-full"
defaultValue={0}
type="number"
data-testid="ds-settings-raptor-seed-input"
suffix={
<div className="w-7 flex justify-center items-center">
<Shuffle
className="size-3.5 cursor-pointer"
onClick={handleGenerate}
data-testid="ds-settings-raptor-seed-randomize-btn"
/>
</div>
}

View File

@ -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}
></SingleFormSlider>
</FormControl>
<FormControl>
@ -118,6 +123,7 @@ export const SliderInputFormField = forwardRef<
);
}
}}
data-testid={numberInputTestId}
></NumberInput>
</FormControl>
</div>

View File

@ -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 && (
<div className="h-3 w-3 fill-primary text-primary bg-text-primary rounded-full" />

View File

@ -203,6 +203,8 @@ export type RAGFlowSelectProps = Partial<ControllerRenderProps> & {
contentProps?: React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>;
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}
>
<SelectValue placeholder={placeholder}>{label}</SelectValue>
</SelectTrigger>
@ -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
}
>
<div className="flex items-center gap-1">
{o.icon}
@ -326,7 +336,16 @@ export const RAGFlowSelect = forwardRef<
<SelectGroup key={idx}>
<SelectLabel className="pl-2">{o.label}</SelectLabel>
{o.options.map((x) => (
<SelectItem value={x.value} key={x.value} disabled={x.disabled}>
<SelectItem
value={x.value}
key={x.value}
disabled={x.disabled}
data-testid={
optionTestIdPrefix
? `${optionTestIdPrefix}-${x.value}`
: undefined
}
>
{x.label}
</SelectItem>
))}

View File

@ -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 {

View File

@ -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<IMetaDataTableData>({
@ -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}
>
<Plus />
{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}
/>

View File

@ -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}
>
<div className="flex flex-col gap-4">
{!isEditField && (
@ -281,6 +286,7 @@ export const ManageValuesModal = (props: IManageValuesProps) => {
variant={'ghost'}
className="border border-border-button"
onClick={handleAddValue}
data-testid={addValueButtonTestId}
>
<Plus />
</Button>

View File

@ -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}
/>
</Spin>
);
@ -188,6 +191,7 @@ export function EmbeddingModelItem({ line = 1, isEdit }: IProps) {
isEdit={!!isEdit}
field={field}
disabled={disabled}
testId="ds-settings-basic-embedding-model-select"
></EmbeddingSelect>
</FormControl>
</div>
@ -313,6 +317,7 @@ export function EnableTocToggle() {
<Switch
checked={field.value}
onCheckedChange={field.onChange}
data-testid="ds-settings-parser-page-index-switch"
/>
</FormControl>
</div>
@ -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"
/>
</FormControl>
<div className="flex pt-1">
@ -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"
></SliderInputFormField>
);
}
@ -439,7 +448,12 @@ export function AutoMetadata({
tooltip: t('knowledgeConfiguration.autoMetadataTip'),
render: (fieldProps: ControllerRenderProps) => (
<div className="flex items-center justify-between">
<Button type="button" variant="ghost" onClick={handleClickOpenMetadata}>
<Button
type="button"
variant="ghost"
onClick={handleClickOpenMetadata}
data-testid="ds-settings-metadata-open-modal-btn"
>
<div className="flex items-center gap-2">
<Settings />
{t('knowledgeConfiguration.settings')}
@ -448,6 +462,7 @@ export function AutoMetadata({
<Switch
checked={fieldProps.value}
onCheckedChange={fieldProps.onChange}
data-testid="ds-settings-metadata-switch"
/>
</div>
),
@ -500,6 +515,11 @@ export function AutoMetadata({
}) => {
handleSaveMetadata(data);
}}
testId="ds-settings-metadata-modal"
okButtonTestId="ds-settings-metadata-modal-save-btn"
addButtonTestId="ds-settings-metadata-add-btn"
nestedModalTestId="ds-settings-metadata-add-modal"
nestedModalOkButtonTestId="ds-settings-metadata-add-modal-confirm-btn"
/>
)}
</>

View File

@ -22,8 +22,12 @@ export function NaiveConfiguration() {
return (
<MainContainer>
<ConfigurationFormContainer>
<LayoutRecognizeFormField></LayoutRecognizeFormField>
<MaxTokenNumberFormField initialValue={512}></MaxTokenNumberFormField>
<LayoutRecognizeFormField testId="ds-settings-parser-pdf-parser-select"></LayoutRecognizeFormField>
<MaxTokenNumberFormField
initialValue={512}
sliderTestId="ds-settings-parser-recommended-chunk-size-slider"
numberInputTestId="ds-settings-parser-recommended-chunk-size-input"
></MaxTokenNumberFormField>
<DelimiterFormField></DelimiterFormField>
<ChildrenDelimiterForm />
<EnableTocToggle />

View File

@ -42,7 +42,10 @@ export function GeneralForm() {
{t('common.name')}
</FormLabel>
<FormControl className="w-3/4">
<Input {...field}></Input>
<Input
{...field}
data-testid="ds-settings-basic-name-input"
></Input>
</FormControl>
</div>
<div className="flex pt-1">
@ -61,6 +64,7 @@ export function GeneralForm() {
<SelectWithSearch
options={languageOptions}
triggerClassName="w-full"
testId="ds-settings-basic-language-select"
></SelectWithSearch>
</RAGFlowFormItem>
</div>
@ -74,7 +78,12 @@ export function GeneralForm() {
{t('setting.avatar')}
</FormLabel>
<FormControl className="w-3/4">
<AvatarUpload {...field}></AvatarUpload>
<AvatarUpload
{...field}
uploadInputTestId="ds-settings-basic-avatar-upload"
cropModalTestId="ds-settings-basic-avatar-crop-modal"
cropModalOkButtonTestId="ds-settings-basic-avatar-crop-confirm-btn"
></AvatarUpload>
</FormControl>
</div>
<div className="flex pt-1">
@ -99,7 +108,10 @@ export function GeneralForm() {
{t('flow.description')}
</FormLabel>
<FormControl className="w-3/4">
<Input {...field}></Input>
<Input
{...field}
data-testid="ds-settings-basic-description-input"
></Input>
</FormControl>
</div>
<div className="flex pt-1">

View File

@ -334,6 +334,7 @@ export default function DatasetSettings() {
<Button
type="reset"
className="bg-transparent text-color-white hover:bg-transparent border-gray-500 border-[1px]"
data-testid="ds-settings-page-cancel-btn"
onClick={() => {
form.reset();
}}

View File

@ -23,6 +23,7 @@ export function PermissionFormField() {
<SelectWithSearch
options={teamOptions}
triggerClassName="w-full"
testId="ds-settings-basic-permissions-select"
></SelectWithSearch>
</RAGFlowFormItem>
);

View File

@ -22,6 +22,7 @@ export function GeneralSavingButton() {
<ButtonLoading
type="button"
loading={submitLoading}
data-testid="ds-settings-basic-save-btn"
onClick={() => {
(async () => {
let isValidate = await form.trigger('name');
@ -55,6 +56,7 @@ export function SavingButton() {
return (
<ButtonLoading
loading={submitLoading}
data-testid="ds-settings-page-save-btn"
onClick={() => {
(async () => {
try {