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>
))}