@@ -201,7 +162,8 @@ const createBaseProps = () => {
}
describe('ConfigModalFormFields', () => {
- it('should update paragraph, number, checkbox, and select defaults', () => {
+ it('should update paragraph, number, checkbox, and select defaults', async () => {
+ const user = userEvent.setup()
const paragraphProps = createBaseProps()
paragraphProps.tempPayload = {
...paragraphProps.tempPayload,
@@ -229,9 +191,12 @@ describe('ConfigModalFormFields', () => {
default: false,
}
checkboxProps.checkboxDefaultSelectValue = 'true'
- render(
)
- fireEvent.click(screen.getByText('ui-select:true'))
+ const checkboxView = render(
)
+ await user.click(screen.getByRole('combobox'))
+ const checkboxOptions = await screen.findAllByRole('option')
+ await user.click(checkboxOptions[1]!)
expect(checkboxProps.payloadChangeHandlers.default).toHaveBeenCalledWith(false)
+ checkboxView.unmount()
const selectProps = createBaseProps()
selectProps.tempPayload = {
@@ -242,7 +207,9 @@ describe('ConfigModalFormFields', () => {
selectProps.options = ['alpha', 'beta']
render(
)
fireEvent.click(screen.getByText('config-select'))
- fireEvent.click(screen.getByText('ui-select:alpha'))
+ await user.click(screen.getByRole('combobox'))
+ const selectOptions = await screen.findAllByRole('option')
+ await user.click(selectOptions[2]!)
expect(selectProps.payloadChangeHandlers.options).toHaveBeenCalledWith(['alpha', 'beta'])
expect(selectProps.payloadChangeHandlers.default).toHaveBeenCalledWith('beta')
})
@@ -348,7 +315,8 @@ describe('ConfigModalFormFields', () => {
expect(textProps.payloadChangeHandlers.default).toHaveBeenCalledWith(undefined)
})
- it('should clear select defaults and apply uploader fallback values', () => {
+ it('should clear select defaults and apply uploader fallback values', async () => {
+ const user = userEvent.setup()
const selectProps = createBaseProps()
selectProps.tempPayload = {
...selectProps.tempPayload,
@@ -356,10 +324,13 @@ describe('ConfigModalFormFields', () => {
default: 'alpha',
}
selectProps.options = ['alpha', ' ', 'beta']
- render(
)
+ const selectView = render(
)
- fireEvent.click(screen.getByText('ui-select-empty'))
+ await user.click(screen.getByRole('combobox'))
+ const selectOptions = await screen.findAllByRole('option')
+ await user.click(selectOptions[0]!)
expect(selectProps.payloadChangeHandlers.default).toHaveBeenCalledWith(undefined)
+ selectView.unmount()
const singleFallbackProps = createBaseProps()
singleFallbackProps.tempPayload = {
@@ -416,21 +387,10 @@ describe('ConfigModalFormFields', () => {
render(
)
expect(screen.getAllByText('config-select')).toHaveLength(1)
- expect(screen.queryByText('ui-select:__empty__')).not.toBeInTheDocument()
+ expect(screen.queryByRole('combobox')).not.toBeInTheDocument()
})
- it('should preserve existing select and file defaults when present', () => {
- const selectProps = createBaseProps()
- selectProps.tempPayload = {
- ...selectProps.tempPayload,
- type: InputVarType.select,
- default: undefined,
- }
- selectProps.options = ['alpha', 'beta']
- render(
)
-
- expect(screen.getByText('ui-select:__empty__')).toBeInTheDocument()
-
+ it('should preserve existing file defaults when present', () => {
const existingFile = {
fileId: 'existing-file',
type: 'local_file',
diff --git a/web/app/components/app/configuration/config-var/config-modal/__tests__/type-select.spec.tsx b/web/app/components/app/configuration/config-var/config-modal/__tests__/type-select.spec.tsx
index 148f5872647..4aad4aadd31 100644
--- a/web/app/components/app/configuration/config-var/config-modal/__tests__/type-select.spec.tsx
+++ b/web/app/components/app/configuration/config-var/config-modal/__tests__/type-select.spec.tsx
@@ -3,8 +3,6 @@ import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import TypeSelector from '../type-select'
-vi.mock('@langgenius/dify-ui/select', () => import('@/__mocks__/base-ui-select'))
-
vi.mock('@/app/components/workflow/nodes/_base/components/input-var-type-icon', () => ({
default: ({ type }: { type: string }) =>
{type},
}))
diff --git a/web/app/components/app/configuration/config/agent/agent-setting/__tests__/index.spec.tsx b/web/app/components/app/configuration/config/agent/agent-setting/__tests__/index.spec.tsx
index e05d0af638f..287fbbc49bf 100644
--- a/web/app/components/app/configuration/config/agent/agent-setting/__tests__/index.spec.tsx
+++ b/web/app/components/app/configuration/config/agent/agent-setting/__tests__/index.spec.tsx
@@ -3,25 +3,6 @@ import { act, fireEvent, render, screen } from '@testing-library/react'
import { MAX_ITERATIONS_NUM } from '@/config'
import { AgentSetting } from '../index'
-vi.mock('@langgenius/dify-ui/slider', () => ({
- Slider: (props: {
- className?: string
- min?: number
- max?: number
- value: number
- onValueChange: (value: number) => void
- }) => (
-
props.onValueChange(Number(e.target.value))}
- />
- ),
-}))
-
const basePayload = {
enabled: true,
strategy: 'react',
diff --git a/web/app/components/app/configuration/dataset-config/context-var/__tests__/var-picker.spec.tsx b/web/app/components/app/configuration/dataset-config/context-var/__tests__/var-picker.spec.tsx
index 0b3c1a63886..5babe06c125 100644
--- a/web/app/components/app/configuration/dataset-config/context-var/__tests__/var-picker.spec.tsx
+++ b/web/app/components/app/configuration/dataset-config/context-var/__tests__/var-picker.spec.tsx
@@ -1,45 +1,8 @@
-import type { ReactNode } from 'react'
import type { Props } from '../var-picker'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
-import * as React from 'react'
import VarPicker from '../var-picker'
-vi.mock('@langgenius/dify-ui/popover', () => {
- const PopoverContext = React.createContext({
- open: false,
- onOpenChange: undefined as ((open: boolean) => void) | undefined,
- })
-
- return {
- Popover: ({
- children,
- open,
- onOpenChange,
- }: {
- children: ReactNode
- open?: boolean
- onOpenChange?: (open: boolean) => void
- }) =>
{children},
- PopoverTrigger: ({ render }: { render?: ReactNode }) => {
- const { open, onOpenChange } = React.use(PopoverContext)
- return (
-
- )
- },
- PopoverContent: ({ children }: { children: ReactNode }) => {
- const { open } = React.use(PopoverContext)
- return open ? (
-
- {children}
-
- ) : null
- },
- }
-})
-
const options: Props['options'] = [
{ name: 'Variable 1', value: 'var1', type: 'string' },
{ name: 'Variable 2', value: 'var2', type: 'number' },
@@ -48,7 +11,7 @@ const options: Props['options'] = [
describe('VarPicker', () => {
it('shows the selected variable', () => {
render(
)
- expect(screen.getByRole('button', { name: 'choose variable' })).toHaveTextContent('var1')
+ expect(screen.getByRole('button')).toHaveTextContent('var1')
})
it('shows the configured empty-selection message', () => {
@@ -64,19 +27,21 @@ describe('VarPicker', () => {
})
it('selects a variable and closes the options', async () => {
+ const user = userEvent.setup()
const onChange = vi.fn()
render(
)
- await userEvent.click(screen.getByRole('button', { name: 'choose variable' }))
- await userEvent.click(screen.getByText('var2'))
+ await user.click(screen.getByRole('button'))
+ await user.click(screen.getByText('var2'))
expect(onChange).toHaveBeenCalledWith('var2')
- expect(screen.queryByRole('dialog', { name: 'variable options' })).not.toBeInTheDocument()
+ expect(screen.queryByText('var2')).not.toBeInTheDocument()
})
it('shows the empty state when no variables are available', async () => {
+ const user = userEvent.setup()
render(
)
- await userEvent.click(screen.getByRole('button', { name: 'choose variable' }))
+ await user.click(screen.getByRole('button'))
expect(screen.getByText('appDebug.feature.dataSet.queryVariable.noVar')).toBeInTheDocument()
})
})
diff --git a/web/app/components/app/configuration/debug/__tests__/chat-user-input.spec.tsx b/web/app/components/app/configuration/debug/__tests__/chat-user-input.spec.tsx
index b4506f33dcb..636d64fcd4d 100644
--- a/web/app/components/app/configuration/debug/__tests__/chat-user-input.spec.tsx
+++ b/web/app/components/app/configuration/debug/__tests__/chat-user-input.spec.tsx
@@ -1,6 +1,7 @@
import type { Inputs, ModelConfig } from '@/models/debug'
import type { PromptVariable } from '@/types/app'
import { fireEvent, render, screen } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
import ChatUserInput from '../chat-user-input'
const mockSetInputs = vi.fn()
@@ -41,75 +42,6 @@ vi.mock('@/app/components/base/input', () => ({
),
}))
-vi.mock('@langgenius/dify-ui/select', async () => {
- const React = await import('react')
- const SelectContext = React.createContext<{
- disabled?: boolean
- onValueChange?: (value: string) => void
- value?: string | null
- }>({})
-
- return {
- Select: ({
- children,
- disabled,
- onValueChange,
- value,
- }: {
- children: React.ReactNode
- disabled?: boolean
- onValueChange?: (value: string) => void
- value?: string | null
- }) => (
-
- {children}
-
- ),
- SelectValue: ({ placeholder }: { placeholder?: React.ReactNode }) => {
- const context = React.use(SelectContext)
- return <>{context.value || placeholder}>
- },
- SelectTrigger: ({ children, className }: { children: React.ReactNode; className?: string }) => {
- const context = React.useContext(SelectContext)
- return (
-
-
-
-
- )
- },
- SelectContent: ({ children }: { children: React.ReactNode }) =>
{children}
,
- SelectItem: ({ children, value }: { children: React.ReactNode; value: string }) => {
- const context = React.useContext(SelectContext)
- return (
-
- )
- },
- SelectItemText: ({ children }: { children: React.ReactNode }) => <>{children}>,
- SelectItemIndicator: () => null,
- }
-})
-
vi.mock('@/app/components/workflow/nodes/_base/components/before-run-form/bool-input', () => ({
default: ({
name,
@@ -256,7 +188,8 @@ describe('ChatUserInput', () => {
expect(screen.getByRole('textbox', { name: 'Description' })).toBeInTheDocument()
})
- it('should render select input type', () => {
+ it('should render select input type', async () => {
+ const user = userEvent.setup()
mockUseContext.mockReturnValue(
createContextValue({
modelConfig: createModelConfig([
@@ -271,10 +204,11 @@ describe('ChatUserInput', () => {
)
render(
)
- expect(screen.getByTestId('select-input')).toBeInTheDocument()
- expect(screen.getByText('A')).toBeInTheDocument()
- expect(screen.getByText('B')).toBeInTheDocument()
- expect(screen.getByText('C')).toBeInTheDocument()
+ const select = screen.getByRole('combobox')
+ await user.click(select)
+ expect(await screen.findByRole('option', { name: 'A' })).toBeInTheDocument()
+ expect(screen.getByRole('option', { name: 'B' })).toBeInTheDocument()
+ expect(screen.getByRole('option', { name: 'C' })).toBeInTheDocument()
})
it('should render number input type', () => {
@@ -324,7 +258,7 @@ describe('ChatUserInput', () => {
render(
)
expect(screen.getByTestId('input-Name')).toBeInTheDocument()
expect(screen.getByRole('textbox', { name: 'Description' })).toBeInTheDocument()
- expect(screen.getByTestId('select-input')).toBeInTheDocument()
+ expect(screen.getByRole('combobox')).toBeInTheDocument()
})
it('should show optional label for non-required fields', () => {
@@ -497,7 +431,8 @@ describe('ChatUserInput', () => {
expect(mockSetInputs).toHaveBeenCalledWith({ desc: 'New Description' })
})
- it('should call setInputs when select input changes', () => {
+ it('should call setInputs when select input changes', async () => {
+ const user = userEvent.setup()
mockUseContext.mockReturnValue(
createContextValue({
modelConfig: createModelConfig([
@@ -512,31 +447,12 @@ describe('ChatUserInput', () => {
)
render(
)
- fireEvent.click(screen.getByTestId('select-B'))
+ await user.click(screen.getByRole('combobox'))
+ await user.click(await screen.findByRole('option', { name: 'B' }))
expect(mockSetInputs).toHaveBeenCalledWith({ choice: 'B' })
})
- it('should ignore empty select updates', () => {
- mockUseContext.mockReturnValue(
- createContextValue({
- modelConfig: createModelConfig([
- createPromptVariable({
- key: 'choice',
- name: 'Choice',
- type: 'select',
- options: ['A', 'B', 'C'],
- }),
- ]),
- }),
- )
-
- render(
)
- fireEvent.click(screen.getByTestId('select-empty'))
-
- expect(mockSetInputs).not.toHaveBeenCalled()
- })
-
it('should call setInputs when number input changes', () => {
mockUseContext.mockReturnValue(
createContextValue({
@@ -676,7 +592,7 @@ describe('ChatUserInput', () => {
)
render(
)
- expect(screen.getByTestId('select-input')).toBeDisabled()
+ expect(screen.getByRole('combobox')).toBeDisabled()
})
it('should disable checkbox when configuration is readonly and test/run is denied', () => {
@@ -862,7 +778,8 @@ describe('ChatUserInput', () => {
})
describe('Edge Cases', () => {
- it('should handle select with empty options', () => {
+ it('should show no options when a select has no configured choices', async () => {
+ const user = userEvent.setup()
mockUseContext.mockReturnValue(
createContextValue({
modelConfig: createModelConfig([
@@ -872,25 +789,11 @@ describe('ChatUserInput', () => {
)
render(
)
- const select = screen.getByTestId('select-input')
- expect(select).toBeInTheDocument()
+ const select = screen.getByRole('combobox')
+ await user.click(select)
expect(screen.queryAllByRole('option')).toHaveLength(0)
})
- it('should handle select with undefined options', () => {
- mockUseContext.mockReturnValue(
- createContextValue({
- modelConfig: createModelConfig([
- createPromptVariable({ key: 'choice', name: 'Choice', type: 'select' }),
- ]),
- }),
- )
-
- render(
)
- const select = screen.getByTestId('select-input')
- expect(select).toBeInTheDocument()
- })
-
it('should preserve other input values when updating one field', () => {
mockUseContext.mockReturnValue(
createContextValue({
diff --git a/web/app/components/app/configuration/debug/debug-with-multiple-model/__tests__/chat-item.spec.tsx b/web/app/components/app/configuration/debug/debug-with-multiple-model/__tests__/chat-item.spec.tsx
index 8d88c235a5d..1779b60ec58 100644
--- a/web/app/components/app/configuration/debug/debug-with-multiple-model/__tests__/chat-item.spec.tsx
+++ b/web/app/components/app/configuration/debug/debug-with-multiple-model/__tests__/chat-item.spec.tsx
@@ -102,10 +102,6 @@ vi.mock('@/app/components/base/chat/chat', () => ({
},
}))
-vi.mock('@langgenius/dify-ui/avatar', () => ({
- Avatar: ({ name }: { name: string }) =>
{name}
,
-}))
-
const createModelAndParameter = (
overrides: Partial
= {},
): ModelAndParameter => ({
diff --git a/web/app/components/app/configuration/prompt-value-panel/__tests__/index.spec.tsx b/web/app/components/app/configuration/prompt-value-panel/__tests__/index.spec.tsx
index 4fcb36ba44a..303781a233d 100644
--- a/web/app/components/app/configuration/prompt-value-panel/__tests__/index.spec.tsx
+++ b/web/app/components/app/configuration/prompt-value-panel/__tests__/index.spec.tsx
@@ -1,6 +1,7 @@
/* oxlint-disable typescript/no-explicit-any */
import type { IPromptValuePanelProps } from '../index'
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
import * as React from 'react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import ConfigContext from '@/context/debug-configuration'
@@ -9,29 +10,6 @@ import PromptValuePanel from '../index'
const mockSetShowAppConfigureFeaturesModal = vi.fn()
-vi.mock('@langgenius/dify-ui/button', () => ({
- Button: ({
- children,
- onClick,
- disabled,
- className,
- }: {
- children: React.ReactNode
- onClick?: () => void
- disabled?: boolean
- className?: string
- }) => (
-
- ),
-}))
-
vi.mock('@/app/components/app/store', () => ({
useStore: (
selector: (state: {
@@ -65,60 +43,6 @@ vi.mock('@/app/components/base/features/new-feature-panel/feature-bar', () => ({
),
}))
-vi.mock('@langgenius/dify-ui/select', async () => {
- const React = await import('react')
- const SelectContext = React.createContext<{
- onValueChange?: (value: string) => void
- value?: string | null
- }>({})
-
- return {
- Select: ({
- children,
- onValueChange,
- value,
- }: {
- children: React.ReactNode
- onValueChange?: (value: string) => void
- value?: string | null
- }) => (
-
- {children}
-
- ),
- SelectValue: ({ placeholder }: { placeholder?: React.ReactNode }) => {
- const context = React.use(SelectContext)
- return <>{context.value || placeholder}>
- },
- SelectTrigger: ({ children }: { children: React.ReactNode }) => {
- const context = React.useContext(SelectContext)
- return (
-
-
-
-
- )
- },
- SelectContent: ({ children }: { children: React.ReactNode }) => {children}
,
- SelectItem: ({ children, value }: { children: React.ReactNode; value: string }) => {
- const context = React.useContext(SelectContext)
- return (
-
- )
- },
- SelectItemText: ({ children }: { children: React.ReactNode }) => <>{children}>,
- SelectItemIndicator: () => null,
- }
-})
-
vi.mock('@/app/components/workflow/nodes/_base/components/before-run-form/bool-input', () => ({
default: ({ name, onChange }: { name: string; onChange: (value: boolean) => void }) => (