Files
ComfyUI_frontend/src/components/common/EditableText.test.ts
Alexander Brown 3de387429a test: migrate 11 interactive component tests from VTU to VTL (Phase 2) (#10490)
## Summary

Phase 2 of the VTL migration: migrate 11 interactive component tests
from @vue/test-utils to @testing-library/vue (69 tests).

Stacked on #10471.

## Changes

- **What**: Migrate BatchCountEdit, BypassButton, BuilderFooterToolbar,
ComfyActionbar, SidebarIcon, EditableText, UrlInput, SearchInput,
TagsInput, TreeExplorerTreeNode, ColorCustomizationSelector from VTU to
VTL
- **Pattern transforms**: `trigger('click')` → `userEvent.click()`,
`setValue()` → `userEvent.type()`, `findComponent().props()` →
`getByRole/getByText/getByTestId`, `emitted()` → callback props
- **Removed**: 4 `@ts-expect-error` annotations, 1 change-detector test
(SearchInput `vm.focus`)
- **PrimeVue**: `data-pc-name` selectors + `aria-pressed` for
SelectButton, container queries for ColorPicker/InputIcon

## Review Focus

- PrimeVue escape hatches in ColorCustomizationSelector
(SelectButton/ColorPicker lack standard ARIA roles)
- Teleport test in ComfyActionbar uses `container.querySelector`
intentionally (scoped to teleport target)
- SearchInput debounce tests use `fireEvent.update` instead of
`userEvent.type` due to fake timer interaction
- EditableText escape-then-blur test simplified:
`userEvent.keyboard('{Escape}')` already triggers blur internally

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10490-test-migrate-11-interactive-component-tests-from-VTU-to-VTL-Phase-2-32e6d73d3650817ca40fd61395499e3f)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-26 19:46:31 -07:00

121 lines
3.6 KiB
TypeScript

import { fireEvent, render, screen } from '@testing-library/vue'
import userEvent from '@testing-library/user-event'
import PrimeVue from 'primevue/config'
import InputText from 'primevue/inputtext'
import { describe, expect, it, vi } from 'vitest'
import EditableText from './EditableText.vue'
describe('EditableText', () => {
function renderComponent(
props: { modelValue: string; isEditing?: boolean },
callbacks: {
onEdit?: (...args: unknown[]) => void
onCancel?: (...args: unknown[]) => void
} = {}
) {
const user = userEvent.setup()
render(EditableText, {
global: {
plugins: [PrimeVue],
components: { InputText }
},
props: {
...props,
...(callbacks.onEdit && { onEdit: callbacks.onEdit }),
...(callbacks.onCancel && { onCancel: callbacks.onCancel })
}
})
return { user }
}
it('renders span with modelValue when not editing', () => {
renderComponent({ modelValue: 'Test Text', isEditing: false })
expect(screen.getByText('Test Text')).toBeInTheDocument()
expect(screen.queryByRole('textbox')).not.toBeInTheDocument()
})
it('renders input with modelValue when editing', () => {
renderComponent({ modelValue: 'Test Text', isEditing: true })
expect(screen.queryByText('Test Text')).not.toBeInTheDocument()
expect(screen.getByRole('textbox')).toHaveValue('Test Text')
})
it('emits edit event when input is submitted', async () => {
const onEdit = vi.fn()
const { user } = renderComponent(
{ modelValue: 'Test Text', isEditing: true },
{ onEdit }
)
const input = screen.getByRole('textbox')
await user.clear(input)
await user.type(input, 'New Text')
await user.keyboard('{Enter}')
expect(onEdit).toHaveBeenCalledWith('New Text')
})
it('finishes editing on blur', async () => {
const onEdit = vi.fn()
renderComponent({ modelValue: 'Test Text', isEditing: true }, { onEdit })
await fireEvent.blur(screen.getByRole('textbox'))
expect(onEdit).toHaveBeenCalledWith('Test Text')
})
it('cancels editing on escape key', async () => {
const onEdit = vi.fn()
const onCancel = vi.fn()
const { user } = renderComponent(
{ modelValue: 'Original Text', isEditing: true },
{ onEdit, onCancel }
)
const input = screen.getByRole('textbox')
await user.clear(input)
await user.type(input, 'Modified Text')
await user.keyboard('{Escape}')
expect(onCancel).toHaveBeenCalled()
expect(onEdit).not.toHaveBeenCalled()
expect(input).toHaveValue('Original Text')
})
it('does not save changes when escape is pressed', async () => {
const onEdit = vi.fn()
const onCancel = vi.fn()
const { user } = renderComponent(
{ modelValue: 'Original Text', isEditing: true },
{ onEdit, onCancel }
)
const input = screen.getByRole('textbox')
await user.clear(input)
await user.type(input, 'Modified Text')
// Escape triggers cancelEditing → blur internally, so no separate blur needed
await user.keyboard('{Escape}')
expect(onCancel).toHaveBeenCalled()
expect(onEdit).not.toHaveBeenCalled()
})
it('saves changes on enter but not on escape', async () => {
const onEditEnter = vi.fn()
const { user: userEnter } = renderComponent(
{ modelValue: 'Original Text', isEditing: true },
{ onEdit: onEditEnter }
)
const enterInput = screen.getByRole('textbox')
await userEnter.clear(enterInput)
await userEnter.type(enterInput, 'Saved Text')
await userEnter.keyboard('{Enter}')
expect(onEditEnter).toHaveBeenCalledWith('Saved Text')
})
})