test: enhance BatchAction component tests by improving dialog interaction

This commit is contained in:
CodingOnStar
2026-04-14 11:00:46 +08:00
parent af922ff77e
commit 03cc885447
4 changed files with 63 additions and 20 deletions

12
pnpm-lock.yaml generated
View File

@ -24,9 +24,6 @@ catalogs:
'@cucumber/cucumber':
specifier: 12.8.0
version: 12.8.0
'@date-fns/tz':
specifier: 1.4.1
version: 1.4.1
'@egoist/tailwindcss-icons':
specifier: 1.9.2
version: 1.9.2
@ -270,9 +267,6 @@ catalogs:
cron-parser:
specifier: 5.5.0
version: 5.5.0
date-fns:
specifier: 4.1.0
version: 4.1.0
dayjs:
specifier: 1.11.20
version: 1.11.20
@ -655,9 +649,6 @@ importers:
'@base-ui/react':
specifier: 'catalog:'
version: 1.4.0(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@date-fns/tz':
specifier: 'catalog:'
version: 1.4.1
'@emoji-mart/data':
specifier: 'catalog:'
version: 1.2.1
@ -760,9 +751,6 @@ importers:
cron-parser:
specifier: 'catalog:'
version: 5.5.0
date-fns:
specifier: 'catalog:'
version: 4.1.0
dayjs:
specifier: 'catalog:'
version: 1.11.20

View File

@ -1,4 +1,4 @@
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react'
import { fireEvent, render, screen, waitFor, within } from '@testing-library/react'
import * as React from 'react'
import BatchAction from '../batch-action'
@ -29,11 +29,10 @@ describe('BatchAction', () => {
render(<BatchAction {...baseProps} onBatchDelete={onBatchDelete} />)
fireEvent.click(screen.getByRole('button', { name: 'common.operation.delete' }))
await screen.findByText('appAnnotation.list.delete.title')
const dialog = await screen.findByRole('alertdialog')
expect(within(dialog).getByText('appAnnotation.list.delete.title')).toBeInTheDocument()
await act(async () => {
fireEvent.click(screen.getAllByRole('button', { name: 'common.operation.delete' })[1])
})
fireEvent.click(within(dialog).getByRole('button', { name: 'common.operation.delete' }))
await waitFor(() => {
expect(onBatchDelete).toHaveBeenCalledTimes(1)

View File

@ -8,7 +8,65 @@ import * as React from 'react'
import { parsePlacement } from '@/app/components/base/ui/placement'
import { cn } from '@/utils/classnames'
export const Select = BaseSelect.Root
type SelectRootProps<Value, Multiple extends boolean | undefined = false> = BaseSelect.Root.Props<Value, Multiple> & {
form?: string
}
export function Select<Value, Multiple extends boolean | undefined = false>({
form,
inputRef,
name,
...props
}: SelectRootProps<Value, Multiple>) {
const hiddenInputRef = React.useRef<HTMLInputElement | null>(null)
const handleInputRef = React.useCallback((node: HTMLInputElement | null) => {
hiddenInputRef.current = node
if (!inputRef)
return
if (typeof inputRef === 'function') {
inputRef(node)
return
}
inputRef.current = node
}, [inputRef])
React.useLayoutEffect(() => {
const hiddenInput = hiddenInputRef.current
if (!hiddenInput)
return
const syncFormAttribute = (node: HTMLInputElement) => {
if (form === undefined)
node.removeAttribute('form')
else
node.setAttribute('form', form)
}
syncFormAttribute(hiddenInput)
if (!name)
return
let sibling = hiddenInput.nextElementSibling
while (sibling instanceof HTMLInputElement && sibling.type === 'hidden' && sibling.name === name) {
syncFormAttribute(sibling)
sibling = sibling.nextElementSibling
}
}, [form, name])
return (
<BaseSelect.Root
{...props}
name={name}
inputRef={handleInputRef}
/>
)
}
export const SelectValue = BaseSelect.Value
/** @public */
export const SelectGroup = BaseSelect.Group

View File

@ -56,7 +56,6 @@
"@amplitude/analytics-browser": "catalog:",
"@amplitude/plugin-session-replay-browser": "catalog:",
"@base-ui/react": "catalog:",
"@date-fns/tz": "catalog:",
"@emoji-mart/data": "catalog:",
"@floating-ui/react": "catalog:",
"@formatjs/intl-localematcher": "catalog:",
@ -91,7 +90,6 @@
"cmdk": "catalog:",
"copy-to-clipboard": "catalog:",
"cron-parser": "catalog:",
"date-fns": "catalog:",
"dayjs": "catalog:",
"decimal.js": "catalog:",
"dompurify": "catalog:",