diff --git a/packages/dify-ui/src/alert-dialog/__tests__/index.spec.tsx b/packages/dify-ui/src/alert-dialog/__tests__/index.spec.tsx index 18e7c3b13f0..e3a2a7cca76 100644 --- a/packages/dify-ui/src/alert-dialog/__tests__/index.spec.tsx +++ b/packages/dify-ui/src/alert-dialog/__tests__/index.spec.tsx @@ -26,7 +26,6 @@ describe('AlertDialog wrapper', () => { await expect.element(screen.getByRole('alertdialog')).toHaveTextContent('Confirm Delete') await expect.element(screen.getByRole('alertdialog')).toHaveTextContent('This action cannot be undone.') - await expect.element(document.body.querySelector('.bg-background-overlay') as HTMLElement).toHaveClass('absolute', 'inset-0', 'z-50') }) it('should not render content when dialog is closed', async () => { @@ -96,7 +95,7 @@ describe('AlertDialog wrapper', () => { }) describe('Composition Helpers', () => { - it('should render actions wrapper and default confirm button styles', async () => { + it('should render actions wrapper and confirm button', async () => { const screen = await render( @@ -108,8 +107,8 @@ describe('AlertDialog wrapper', () => { , ) - await expect.element(screen.getByTestId('actions')).toHaveClass('flex', 'items-start', 'justify-end', 'gap-2', 'self-stretch', 'p-6', 'custom-actions') - await expect.element(screen.getByRole('button', { name: 'Confirm' })).toHaveClass('bg-components-button-destructive-primary-bg') + await expect.element(screen.getByTestId('actions')).toHaveClass('custom-actions') + await expect.element(screen.getByRole('button', { name: 'Confirm' })).toBeInTheDocument() }) it('should keep dialog open after confirm click and close via cancel helper', async () => { diff --git a/packages/dify-ui/src/autocomplete/__tests__/index.spec.tsx b/packages/dify-ui/src/autocomplete/__tests__/index.spec.tsx index 17cdaaaceed..ad99a97e9e9 100644 --- a/packages/dify-ui/src/autocomplete/__tests__/index.spec.tsx +++ b/packages/dify-ui/src/autocomplete/__tests__/index.spec.tsx @@ -72,28 +72,6 @@ const renderAutocomplete = ({ describe('Autocomplete wrappers', () => { describe('Input group and input', () => { - it('should apply medium input group and input classes by default', async () => { - const screen = await renderAutocomplete() - - await expect.element(screen.getByTestId('input-group')).toHaveClass('rounded-lg') - await expect.element(screen.getByRole('combobox', { name: 'Search suggestions' })).toHaveClass('px-3') - await expect.element(screen.getByRole('combobox', { name: 'Search suggestions' })).toHaveClass('system-sm-regular') - }) - - it('should apply large input group and input classes when large size is provided', async () => { - const screen = await renderAutocomplete({ - children: ( - - - - ), - }) - - await expect.element(screen.getByTestId('input-group')).toHaveClass('rounded-[10px]') - await expect.element(screen.getByRole('combobox', { name: 'Search suggestions' })).toHaveClass('px-4') - await expect.element(screen.getByRole('combobox', { name: 'Search suggestions' })).toHaveClass('system-md-regular') - }) - it('should set input defaults and forward passthrough props', async () => { const screen = await renderAutocomplete({ children: ( @@ -122,8 +100,6 @@ describe('Autocomplete wrappers', () => { await expect.element(screen.getByRole('button', { name: 'Clear autocomplete' })).toHaveAttribute('type', 'button') await expect.element(screen.getByRole('button', { name: 'Open autocomplete suggestions' })).toHaveAttribute('type', 'button') - expect(screen.getByRole('button', { name: 'Clear autocomplete' }).element().querySelector('.i-ri-close-line')).toHaveAttribute('aria-hidden', 'true') - expect(screen.getByRole('button', { name: 'Open autocomplete suggestions' }).element().querySelector('.i-ri-arrow-down-s-line')).toHaveAttribute('aria-hidden', 'true') }) it('should preserve explicit labels and custom children', async () => { @@ -143,8 +119,6 @@ describe('Autocomplete wrappers', () => { expect(screen.getByRole('button', { name: 'Reset search' }).element()).toContainElement(screen.getByTestId('custom-clear').element()) expect(screen.getByRole('button', { name: 'Show suggestions' }).element()).toContainElement(screen.getByTestId('custom-trigger').element()) - expect(screen.getByRole('button', { name: 'Reset search' }).element().querySelector('.i-ri-close-line')).not.toBeInTheDocument() - expect(screen.getByRole('button', { name: 'Show suggestions' }).element().querySelector('.i-ri-arrow-down-s-line')).not.toBeInTheDocument() }) it('should rely on aria-labelledby when provided instead of injecting fallback labels', async () => { @@ -168,15 +142,11 @@ describe('Autocomplete wrappers', () => { }) describe('Content and options', () => { - it('should use default overlay placement and Dify popup classes', async () => { + it('should use default overlay placement', async () => { const screen = await renderAutocomplete({ open: true }) await expect.element(screen.getByRole('group', { name: 'autocomplete positioner' })).toHaveAttribute('data-side', 'bottom') await expect.element(screen.getByRole('group', { name: 'autocomplete positioner' })).toHaveAttribute('data-align', 'start') - await expect.element(screen.getByRole('group', { name: 'autocomplete positioner' })).toHaveClass('z-50') - await expect.element(screen.getByRole('dialog', { name: 'autocomplete popup' })).toHaveClass('rounded-xl') - await expect.element(screen.getByRole('dialog', { name: 'autocomplete popup' })).toHaveClass('w-(--anchor-width)') - await expect.element(screen.getByRole('listbox', { name: 'autocomplete list' })).toHaveClass('scroll-py-1') }) it('should apply custom placement side and passthrough popup props', async () => { @@ -212,17 +182,6 @@ describe('Autocomplete wrappers', () => { expect(onPopupClick).toHaveBeenCalledTimes(1) }) - it('should render item text indicator status and empty wrappers with design classes', async () => { - const screen = await renderAutocomplete({ open: true }) - - await expect.element(screen.getByText('Workflow')).toHaveClass('system-sm-medium') - await expect.element(screen.getByTestId('status')).toHaveClass('text-text-tertiary') - await expect.element(screen.getByTestId('empty')).toHaveClass('system-sm-regular') - await expect.element(screen.getByTestId('empty')).toHaveClass('empty:p-0') - expect(screen.getByTestId('empty').element().getBoundingClientRect().height).toBe(0) - expect(screen.getByText('Workflow').element().parentElement?.querySelector('.i-ri-arrow-right-line')).toHaveAttribute('aria-hidden', 'true') - }) - it('should forward custom classes to label separator item text and indicator', async () => { const screen = await renderWithSafeViewport( diff --git a/packages/dify-ui/src/avatar/__tests__/index.spec.tsx b/packages/dify-ui/src/avatar/__tests__/index.spec.tsx index b0ea4962822..e427b09ed0d 100644 --- a/packages/dify-ui/src/avatar/__tests__/index.spec.tsx +++ b/packages/dify-ui/src/avatar/__tests__/index.spec.tsx @@ -23,31 +23,6 @@ describe('Avatar', () => { }) }) - describe('Size variants', () => { - it.each([ - { size: 'xxs' as const, expectedClass: 'size-4' }, - { size: 'xs' as const, expectedClass: 'size-5' }, - { size: 'sm' as const, expectedClass: 'size-6' }, - { size: 'md' as const, expectedClass: 'size-8' }, - { size: 'lg' as const, expectedClass: 'size-9' }, - { size: 'xl' as const, expectedClass: 'size-10' }, - { size: '2xl' as const, expectedClass: 'size-12' }, - { size: '3xl' as const, expectedClass: 'size-16' }, - ])('should apply $expectedClass for size="$size"', async ({ size, expectedClass }) => { - const screen = await render() - - const root = screen.container.firstElementChild as HTMLElement - expect(root).toHaveClass(expectedClass) - }) - - it('should default to md size when size is not specified', async () => { - const screen = await render() - - const root = screen.container.firstElementChild as HTMLElement - expect(root).toHaveClass('size-8') - }) - }) - describe('className prop', () => { it('should merge className with avatar variant classes on root', async () => { const screen = await render( @@ -56,7 +31,6 @@ describe('Avatar', () => { const root = screen.container.firstElementChild as HTMLElement expect(root).toHaveClass('custom-class') - expect(root).toHaveClass('rounded-full', 'bg-primary-600') }) }) @@ -71,7 +45,7 @@ describe('Avatar', () => { , ) - await expect.element(screen.getByTestId('avatar-root')).toHaveClass('size-6') + await expect.element(screen.getByTestId('avatar-root')).toBeInTheDocument() await expect.element(screen.getByText('J')).toBeInTheDocument() await expect.element(screen.getByText('J')).toHaveStyle({ backgroundColor: 'rgb(1, 2, 3)' }) }) @@ -81,9 +55,8 @@ describe('Avatar', () => { it('should handle empty string name gracefully', async () => { const screen = await render() - const fallback = screen.container.querySelector('.text-white') as HTMLElement - expect(fallback).toBeInTheDocument() - expect(fallback.textContent).toBe('') + expect(screen.container.firstElementChild).toBeInTheDocument() + expect(screen.container.textContent).toBe('') }) it.each([ diff --git a/packages/dify-ui/src/button/__tests__/index.spec.tsx b/packages/dify-ui/src/button/__tests__/index.spec.tsx index 32258e2136c..bb2eeb50538 100644 --- a/packages/dify-ui/src/button/__tests__/index.spec.tsx +++ b/packages/dify-ui/src/button/__tests__/index.spec.tsx @@ -33,68 +33,6 @@ describe('Button', () => { expect(button.tagName).toBe('A') expect(button).toHaveAttribute('href', '/test') }) - - it('applies base layout classes', async () => { - const screen = await render() - const btn = screen.getByRole('button').element() - expect(btn).toHaveClass('inline-flex', 'justify-center', 'items-center', 'cursor-pointer') - }) - }) - - describe('variants', () => { - it('applies default secondary variant', async () => { - const screen = await render() - const btn = screen.getByRole('button').element() - expect(btn).toHaveClass('bg-components-button-secondary-bg', 'text-components-button-secondary-text') - }) - - it.each([ - { variant: 'primary' as const, expectedClass: 'bg-components-button-primary-bg' }, - { variant: 'secondary' as const, expectedClass: 'bg-components-button-secondary-bg' }, - { variant: 'secondary-accent' as const, expectedClass: 'text-components-button-secondary-accent-text' }, - { variant: 'ghost' as const, expectedClass: 'text-components-button-ghost-text' }, - { variant: 'ghost-accent' as const, expectedClass: 'hover:bg-state-accent-hover' }, - { variant: 'tertiary' as const, expectedClass: 'bg-components-button-tertiary-bg' }, - ])('applies $variant variant', async ({ variant, expectedClass }) => { - const screen = await render() - await expect.element(screen.getByRole('button')).toHaveClass(expectedClass) - }) - - it('applies destructive tone with default variant', async () => { - const screen = await render() - await expect.element(screen.getByRole('button')).toHaveClass('bg-components-button-destructive-secondary-bg') - }) - - it('applies destructive tone with primary variant', async () => { - const screen = await render() - await expect.element(screen.getByRole('button')).toHaveClass('bg-components-button-destructive-primary-bg') - }) - - it('applies destructive tone with tertiary variant', async () => { - const screen = await render() - await expect.element(screen.getByRole('button')).toHaveClass('bg-components-button-destructive-tertiary-bg') - }) - - it('applies destructive tone with ghost variant', async () => { - const screen = await render() - await expect.element(screen.getByRole('button')).toHaveClass('text-components-button-destructive-ghost-text') - }) - }) - - describe('sizes', () => { - it('applies default medium size', async () => { - const screen = await render() - await expect.element(screen.getByRole('button')).toHaveClass('h-8', 'rounded-lg') - }) - - it.each([ - { size: 'small' as const, expectedClass: 'h-6' }, - { size: 'medium' as const, expectedClass: 'h-8' }, - { size: 'large' as const, expectedClass: 'h-9' }, - ])('applies $size size', async ({ size, expectedClass }) => { - const screen = await render() - await expect.element(screen.getByRole('button')).toHaveClass(expectedClass) - }) }) describe('loading', () => { @@ -208,7 +146,6 @@ describe('Button', () => { const screen = await render() const btn = screen.getByRole('button').element() expect(btn).toHaveClass('custom-class') - expect(btn).toHaveClass('inline-flex') }) }) diff --git a/packages/dify-ui/src/checkbox/__tests__/index.spec.tsx b/packages/dify-ui/src/checkbox/__tests__/index.spec.tsx index b1cba9efcde..20c8bb93a4e 100644 --- a/packages/dify-ui/src/checkbox/__tests__/index.spec.tsx +++ b/packages/dify-ui/src/checkbox/__tests__/index.spec.tsx @@ -17,17 +17,14 @@ describe('Checkbox', () => { await expect.element(checkbox).toHaveAttribute('data-unchecked', '') await expect.element(checkbox).not.toHaveAttribute('data-checked') await expect.element(checkbox).not.toHaveAttribute('data-indeterminate') - await expect.element(checkbox).toHaveClass('focus-visible:ring-2', 'focus-visible:ring-state-accent-solid') }) - it('should expose checked data attributes and icon styling hooks', async () => { + it('should expose checked data attributes', async () => { const screen = await render() const checkbox = screen.getByRole('checkbox', { name: 'Accept terms' }) await expect.element(checkbox).toHaveAttribute('aria-checked', 'true') await expect.element(checkbox).toHaveAttribute('data-checked', '') - await expect.element(checkbox).toHaveClass('data-checked:bg-components-checkbox-bg') - expect(screen.container.querySelector('.i-ri-check-line')).toBeInTheDocument() }) it('should expose mixed state when indeterminate', async () => { @@ -36,8 +33,6 @@ describe('Checkbox', () => { await expect.element(checkbox).toHaveAttribute('aria-checked', 'mixed') await expect.element(checkbox).toHaveAttribute('data-indeterminate', '') - expect(screen.container.querySelector('.i-ri-check-line')).not.toBeInTheDocument() - expect(screen.container.querySelector('span span.rounded-full.bg-current')).toBeInTheDocument() }) it('should call onCheckedChange with the next checked value', async () => { @@ -75,7 +70,6 @@ describe('Checkbox', () => { const checkbox = screen.getByRole('checkbox', { name: 'Accept terms' }) await expect.element(checkbox).toHaveAttribute('data-disabled', '') - await expect.element(checkbox).toHaveClass('data-disabled:cursor-not-allowed') asHTMLElement(checkbox.element()).click() @@ -125,6 +119,6 @@ describe('CheckboxSkeleton', () => { const screen = await render() expect(screen.container.querySelector('[role="checkbox"]')).not.toBeInTheDocument() - await expect.element(screen.getByTestId('checkbox-skeleton')).toHaveClass('bg-text-quaternary', 'opacity-20') + await expect.element(screen.getByTestId('checkbox-skeleton')).toBeInTheDocument() }) }) diff --git a/packages/dify-ui/src/collapsible/__tests__/index.spec.tsx b/packages/dify-ui/src/collapsible/__tests__/index.spec.tsx index 0692ffbcc61..bd1525d0d6b 100644 --- a/packages/dify-ui/src/collapsible/__tests__/index.spec.tsx +++ b/packages/dify-ui/src/collapsible/__tests__/index.spec.tsx @@ -62,28 +62,4 @@ describe('Collapsible wrappers', () => { await expect.element(screen.getByRole('button', { name: 'Styled trigger' })).toHaveAttribute('data-panel-open', '') await expect.element(screen.getByText('Styled panel')).toBeInTheDocument() }) - - it('applies Dify disclosure defaults without a pressed active style', async () => { - const screen = await render( - - Styled trigger - Styled panel - , - ) - const trigger = screen.getByRole('button', { name: 'Styled trigger' }).element() - const panel = screen.getByText('Styled panel').element() - - expect(trigger).toHaveClass( - 'hover:not-data-disabled:bg-components-panel-on-panel-item-bg-hover', - 'focus-visible:ring-2', - 'focus-visible:ring-state-accent-solid', - 'data-panel-open:text-text-primary', - ) - expect(trigger.className).not.toContain('active:') - expect(panel).toHaveClass( - 'h-(--collapsible-panel-height)', - 'data-ending-style:h-0', - 'data-starting-style:h-0', - ) - }) }) diff --git a/packages/dify-ui/src/combobox/__tests__/index.spec.tsx b/packages/dify-ui/src/combobox/__tests__/index.spec.tsx index 08045eb20e3..13b9fa2b165 100644 --- a/packages/dify-ui/src/combobox/__tests__/index.spec.tsx +++ b/packages/dify-ui/src/combobox/__tests__/index.spec.tsx @@ -103,78 +103,15 @@ const renderInputCombobox = ({ describe('Combobox wrappers', () => { describe('Select-like trigger', () => { - it('should render label and apply medium trigger classes by default', async () => { + it('should render label and trigger with combobox semantics', async () => { const screen = await renderSelectLikeCombobox() - await expect.element(screen.getByText('Resource type')).toHaveClass('system-sm-medium') - await expect.element(screen.getByRole('combobox', { name: 'Resource type' })).toHaveClass('rounded-lg') - await expect.element(screen.getByRole('combobox', { name: 'Resource type' })).toHaveClass('system-sm-regular') - }) - - it('should apply small and large trigger size variants', async () => { - const smallScreen = await renderSelectLikeCombobox({ - children: ( - - - - ), - }) - - await expect.element(smallScreen.getByRole('combobox', { name: 'Small resource type' })).toHaveClass('rounded-md') - await expect.element(smallScreen.getByRole('combobox', { name: 'Small resource type' })).toHaveClass('system-xs-regular') - - const largeScreen = await renderSelectLikeCombobox({ - children: ( - - - - ), - }) - - await expect.element(largeScreen.getByRole('combobox', { name: 'Large resource type' })).toHaveClass('rounded-[10px]') - await expect.element(largeScreen.getByRole('combobox', { name: 'Large resource type' })).toHaveClass('system-md-regular') - }) - - it('should render default trigger icon and support hiding it', async () => { - const withIcon = await renderSelectLikeCombobox() - - expect(withIcon.getByTestId('trigger').element().querySelector('.i-ri-arrow-down-s-line')).toHaveAttribute('aria-hidden', 'true') - - const withoutIcon = await renderSelectLikeCombobox({ - children: ( - - - - ), - }) - - expect(withoutIcon.getByRole('combobox', { name: 'Resource type without icon' }).element().querySelector('.i-ri-arrow-down-s-line')).not.toBeInTheDocument() + await expect.element(screen.getByText('Resource type')).toBeInTheDocument() + await expect.element(screen.getByRole('combobox', { name: 'Resource type' })).toBeInTheDocument() }) }) describe('Input group and controls', () => { - it('should apply medium input group and input classes by default', async () => { - const screen = await renderInputCombobox() - - await expect.element(screen.getByTestId('input-group')).toHaveClass('rounded-lg') - await expect.element(screen.getByRole('combobox', { name: 'Search resources' })).toHaveClass('px-3') - await expect.element(screen.getByRole('combobox', { name: 'Search resources' })).toHaveClass('system-sm-regular') - }) - - it('should apply large input group and input classes when large size is provided', async () => { - const screen = await renderInputCombobox({ - children: ( - - - - ), - }) - - await expect.element(screen.getByTestId('input-group')).toHaveClass('rounded-[10px]') - await expect.element(screen.getByRole('combobox', { name: 'Search resources' })).toHaveClass('px-4') - await expect.element(screen.getByRole('combobox', { name: 'Search resources' })).toHaveClass('system-md-regular') - }) - it('should set input defaults and forward passthrough props', async () => { const screen = await renderInputCombobox({ children: ( @@ -201,8 +138,6 @@ describe('Combobox wrappers', () => { await expect.element(screen.getByRole('button', { name: 'Clear combobox' })).toHaveAttribute('type', 'button') await expect.element(screen.getByRole('button', { name: 'Open combobox options' })).toHaveAttribute('type', 'button') - expect(screen.getByRole('button', { name: 'Clear combobox' }).element().querySelector('.i-ri-close-line')).toHaveAttribute('aria-hidden', 'true') - expect(screen.getByRole('button', { name: 'Open combobox options' }).element().querySelector('.i-ri-arrow-down-s-line')).toHaveAttribute('aria-hidden', 'true') }) it('should rely on aria-labelledby when provided instead of injecting fallback labels', async () => { @@ -226,15 +161,11 @@ describe('Combobox wrappers', () => { }) describe('Content and options', () => { - it('should use default overlay placement and Dify popup classes', async () => { + it('should use default overlay placement', async () => { const screen = await renderSelectLikeCombobox({ open: true }) await expect.element(screen.getByRole('group', { name: 'combobox positioner' })).toHaveAttribute('data-side', 'bottom') await expect.element(screen.getByRole('group', { name: 'combobox positioner' })).toHaveAttribute('data-align', 'start') - await expect.element(screen.getByRole('group', { name: 'combobox positioner' })).toHaveClass('z-50') - await expect.element(screen.getByRole('dialog', { name: 'combobox popup' })).toHaveClass('rounded-xl') - await expect.element(screen.getByRole('dialog', { name: 'combobox popup' })).toHaveClass('w-(--anchor-width)') - await expect.element(screen.getByRole('listbox', { name: 'combobox list' })).toHaveClass('scroll-py-1') }) it('should apply custom placement side and passthrough popup props', async () => { @@ -270,18 +201,6 @@ describe('Combobox wrappers', () => { expect(onPopupClick).toHaveBeenCalledTimes(1) }) - it('should render item text indicator status and empty wrappers with design classes', async () => { - const screen = await renderSelectLikeCombobox({ open: true }) - - expect(screen.getByRole('option', { name: 'Workflow' }).element().className).not.toContain('mx-1') - await expect.element(screen.getByTestId('list').getByText('Workflow')).toHaveClass('system-sm-medium') - await expect.element(screen.getByTestId('status')).toHaveClass('text-text-tertiary') - await expect.element(screen.getByTestId('empty')).toHaveClass('system-sm-regular') - await expect.element(screen.getByTestId('empty')).toHaveClass('empty:p-0') - expect(screen.getByTestId('empty').element().getBoundingClientRect().height).toBe(0) - expect(screen.getByTestId('list').getByText('Workflow').element().parentElement?.querySelector('.i-ri-check-line')).toHaveAttribute('aria-hidden', 'true') - }) - it('should forward custom classes to group label separator item text and indicator', async () => { const screen = await renderWithSafeViewport( @@ -368,7 +287,6 @@ describe('Combobox wrappers', () => { await expect.element(screen.getByTestId('chips')).toHaveClass('custom-chips') await expect.element(screen.getByText('maya').element().parentElement!).toHaveClass('custom-chip') await expect.element(screen.getByRole('button', { name: 'Remove selected item' })).toHaveAttribute('type', 'button') - expect(screen.getByTestId('remove-chip').element().querySelector('.i-ri-close-line')).toHaveAttribute('aria-hidden', 'true') }) it('should preserve chip remove aria-labelledby over fallback label', async () => { diff --git a/packages/dify-ui/src/dialog/__tests__/index.spec.tsx b/packages/dify-ui/src/dialog/__tests__/index.spec.tsx index 04c2b9b6503..e2126d1441e 100644 --- a/packages/dify-ui/src/dialog/__tests__/index.spec.tsx +++ b/packages/dify-ui/src/dialog/__tests__/index.spec.tsx @@ -23,7 +23,6 @@ describe('Dialog wrapper', () => { await expect.element(screen.getByRole('dialog')).toHaveTextContent('Dialog Title') await expect.element(screen.getByRole('dialog')).toHaveTextContent('Dialog Description') - await expect.element(document.body.querySelector('.bg-background-overlay') as HTMLElement).toHaveClass('absolute', 'inset-0', 'z-50') }) }) diff --git a/packages/dify-ui/src/drawer/__tests__/index.spec.tsx b/packages/dify-ui/src/drawer/__tests__/index.spec.tsx index 8384199e158..d402e288812 100644 --- a/packages/dify-ui/src/drawer/__tests__/index.spec.tsx +++ b/packages/dify-ui/src/drawer/__tests__/index.spec.tsx @@ -49,7 +49,7 @@ describe('Drawer wrapper', () => { expect(screen.container).not.toContainElement(dialog) await expect.element(dialog).toHaveTextContent('Workspace controls') await expect.element(screen.getByText('Configure the current workspace.')).toBeInTheDocument() - await expect.element(screen.getByTestId('drawer-backdrop')).toHaveClass('absolute', 'inset-0', 'z-50') + await expect.element(screen.getByTestId('drawer-backdrop')).toBeInTheDocument() asHTMLElement(screen.getByRole('button', { name: 'Close drawer' }).element()).click() diff --git a/packages/dify-ui/src/field/__tests__/index.spec.tsx b/packages/dify-ui/src/field/__tests__/index.spec.tsx index e84d150aeaf..0581a322503 100644 --- a/packages/dify-ui/src/field/__tests__/index.spec.tsx +++ b/packages/dify-ui/src/field/__tests__/index.spec.tsx @@ -1,4 +1,3 @@ -import * as React from 'react' import { render } from 'vitest-browser-react' import { Checkbox } from '../../checkbox' import { CheckboxGroup } from '../../checkbox-group' @@ -38,9 +37,6 @@ describe('Field primitives', () => { expect(label.tagName).toBe('LABEL') expect(label).toHaveAttribute('for', asHTMLElement(input.element()).id) expect(asHTMLElement(input.element()).getAttribute('aria-describedby')?.split(' ')).toContain(description.id) - await expect.element(input).toHaveClass('rounded-lg', 'system-sm-regular') - await expect.element(screen.getByText('Email')).toHaveClass('py-1', 'system-sm-medium') - await expect.element(screen.getByText('Used for account notifications.')).toHaveClass('py-0.5', 'body-xs-regular') asHTMLElement(screen.getByRole('button', { name: 'Save' }).element()).click() @@ -48,7 +44,6 @@ describe('Field primitives', () => { const error = asHTMLElement(screen.getByText('Email is required.').element()) await expect.element(screen.getByText('Email is required.')).toBeInTheDocument() await expect.element(input).toHaveAttribute('aria-invalid', 'true') - await expect.element(input).toHaveClass('data-invalid:border-components-input-border-destructive') expect(asHTMLElement(input.element()).getAttribute('aria-describedby')?.split(' ')).toEqual( expect.arrayContaining([description.id, error.id]), ) @@ -92,28 +87,9 @@ describe('Field primitives', () => { await expect.element(screen.getByRole('group', { name: 'Features' })).toBeInTheDocument() await expect.element(screen.getByRole('checkbox', { name: 'Search' })).toHaveAttribute('aria-checked', 'true') - await expect.element(screen.getByText('Choose at least one feature.')).toHaveClass('text-text-destructive', 'body-xs-regular') }) - it('should apply design-system control sizes when requested', async () => { - const screen = await render( - - - Name - - - - Alias - - - , - ) - - await expect.element(screen.getByRole('textbox', { name: 'Name' })).toHaveClass('rounded-[10px]', 'py-[7px]', 'system-md-regular') - await expect.element(screen.getByRole('textbox', { name: 'Alias' })).toHaveClass('rounded-md', 'py-[3px]', 'system-xs-regular') - }) - - it('should expose the design-system read-only state', async () => { + it('should expose the read-only state', async () => { const screen = await render( Token @@ -122,6 +98,5 @@ describe('Field primitives', () => { ) await expect.element(screen.getByRole('textbox', { name: 'Token' })).toHaveAttribute('readonly') - await expect.element(screen.getByRole('textbox', { name: 'Token' })).toHaveClass('read-only:cursor-default', 'read-only:focus:border-transparent') }) }) diff --git a/packages/dify-ui/src/fieldset/__tests__/index.spec.tsx b/packages/dify-ui/src/fieldset/__tests__/index.spec.tsx index 9ee90af3066..3b6198d4b42 100644 --- a/packages/dify-ui/src/fieldset/__tests__/index.spec.tsx +++ b/packages/dify-ui/src/fieldset/__tests__/index.spec.tsx @@ -5,7 +5,7 @@ import { } from '../index' describe('Fieldset primitives', () => { - it('should apply reset design-system classes', async () => { + it('should forward className to the fieldset and legend', async () => { const screen = await render( Permissions @@ -15,7 +15,7 @@ describe('Fieldset primitives', () => { const legend = screen.getByText('Permissions').element() as HTMLElement const fieldset = legend.closest('fieldset') as HTMLElement - await expect.element(fieldset).toHaveClass('m-0', 'min-w-0', 'border-0', 'p-0', 'custom-root') - await expect.element(legend).toHaveClass('mb-1', 'py-1', 'system-sm-medium', 'text-text-secondary', 'custom-legend') + await expect.element(fieldset).toHaveClass('custom-root') + await expect.element(legend).toHaveClass('custom-legend') }) }) diff --git a/packages/dify-ui/src/file-tree/__tests__/index.spec.tsx b/packages/dify-ui/src/file-tree/__tests__/index.spec.tsx index 3475b2f5b1e..4f23c8bdc86 100644 --- a/packages/dify-ui/src/file-tree/__tests__/index.spec.tsx +++ b/packages/dify-ui/src/file-tree/__tests__/index.spec.tsx @@ -73,48 +73,6 @@ describe('FileTree', () => { await expect.element(selectedFile).toHaveAttribute('data-selected') }) - it('uses Figma-aligned row, indentation, icon, and selected label styles', async () => { - const screen = await render() - - await expect.element(screen.getByLabelText('Project files')).toHaveClass('gap-px', 'p-1') - await expect.element(screen.getByRole('button', { name: 'button.tsx' })).toHaveClass('h-6', 'rounded-md', 'ps-2', 'pe-1.5', 'data-[selected]:bg-state-base-active') - await expect.element(screen.getByText('button.tsx')).toHaveClass('group-data-[selected]/file-tree-row:system-sm-medium', 'group-data-[selected]/file-tree-row:text-text-primary') - await expect.element(screen.getByText('README.md')).toHaveAttribute('data-label', 'README.md') - await expect.element(screen.getByText('README.md')).toHaveClass('after:content-[attr(data-label)]') - expect(screen.container.querySelector('.before\\:bottom-\\[-1px\\]')).toBeInTheDocument() - expect(screen.container.querySelector('.i-ri-folder-open-line')).toBeInTheDocument() - }) - - it('uses Remix fill icons for each non-folder file type', async () => { - const iconTypes = [ - ['file', 'i-ri-file-3-fill'], - ['markdown', 'i-ri-markdown-fill'], - ['json', 'i-ri-braces-fill'], - ['image', 'i-ri-file-image-fill'], - ['code', 'i-ri-file-code-fill'], - ['database', 'i-ri-database-2-fill'], - ['text', 'i-ri-file-text-fill'], - ['pdf', 'i-ri-file-pdf-2-fill'], - ['table', 'i-ri-file-excel-fill'], - ['archive', 'i-ri-file-zip-fill'], - ] as const - const screen = await render( - - - {iconTypes.map(([type]) => ( - - - {type} - - ))} - - , - ) - - for (const [, iconClassName] of iconTypes) - expect(screen.container.querySelector(`.${iconClassName}`)).toBeInTheDocument() - }) - it('collapses and expands folders with click and native button keyboard behavior', async () => { const screen = await render() const src = screen.getByRole('button', { name: 'src' }).element() as HTMLElement @@ -158,10 +116,9 @@ describe('FileTree', () => { expect(onPreview).not.toHaveBeenCalled() await expect.element(screen.getByRole('button', { name: 'disabled.txt' })).toBeDisabled() await expect.element(screen.getByRole('button', { name: 'disabled.txt' })).toHaveAttribute('data-disabled') - await expect.element(screen.getByRole('button', { name: 'disabled.txt' })).toHaveClass('data-disabled:cursor-not-allowed') }) - it('styles disabled folder triggers from the resolved collapsible state', async () => { + it('resolves disabled folder triggers through the collapsible state', async () => { const onOpenChange = vi.fn() const screen = await render( @@ -188,6 +145,5 @@ describe('FileTree', () => { expect(onOpenChange).not.toHaveBeenCalled() await expect.element(trigger).toHaveAttribute('aria-disabled', 'true') await expect.element(trigger).toHaveAttribute('aria-expanded', 'true') - await expect.element(trigger).toHaveClass('aria-disabled:cursor-not-allowed') }) }) diff --git a/packages/dify-ui/src/input/__tests__/index.spec.tsx b/packages/dify-ui/src/input/__tests__/index.spec.tsx index 8ceb8dc07c9..ecb7a5aadff 100644 --- a/packages/dify-ui/src/input/__tests__/index.spec.tsx +++ b/packages/dify-ui/src/input/__tests__/index.spec.tsx @@ -1,13 +1,12 @@ -import * as React from 'react' import { render } from 'vitest-browser-react' -import { FieldControl, FieldError, FieldLabel, FieldRoot } from '../../field' +import { FieldError, FieldLabel, FieldRoot } from '../../field' import { Form } from '../../form' import { Input } from '../index' const asHTMLElement = (element: HTMLElement | SVGElement) => element as HTMLElement describe('Input', () => { - it('should render a labelled Base UI input with design-system classes', async () => { + it('should render a labelled Base UI input with its value', async () => { const screen = await render(