Files
ComfyUI_frontend/src/components/queue/QueueNotificationBanner.test.ts
Alexander Brown 08b1199265 test: migrate 13 component tests from VTU to VTL (Phase 1) (#10471)
## Summary

Migrate 13 component test files from @vue/test-utils to
@testing-library/vue as Phase 1 of incremental VTL adoption.

## Changes

- **What**: Rewrite 13 test files (88 tests) to use `render`/`screen`
queries, `userEvent` interactions, and `jest-dom` assertions. Add
`data-testid` attributes to 6 components for lint-clean icon/element
queries. Delete unused `src/utils/test-utils.ts`.
- **Dependencies**: `@testing-library/vue`,
`@testing-library/user-event`, `@testing-library/jest-dom` (installed in
Phase 0)

## Review Focus

- `data-testid` additions to component templates are minimal and
non-behavioral
- PrimeVue passthrough (`pt`) usage in UserAvatar.vue for icon testid
- 2 targeted `eslint-disable` in FormRadioGroup.test.ts where PrimeVue
places `aria-describedby` on wrapper div, not input

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10471-test-migrate-13-component-tests-from-VTU-to-VTL-Phase-1-32d6d73d36508159a33ffa285afb4c38)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-03-26 18:15:11 -07:00

147 lines
4.0 KiB
TypeScript

import { render, screen } from '@testing-library/vue'
import { describe, expect, it } from 'vitest'
import { createI18n } from 'vue-i18n'
import QueueNotificationBanner from '@/components/queue/QueueNotificationBanner.vue'
import type { QueueNotificationBanner as QueueNotificationBannerItem } from '@/composables/queue/useQueueNotificationBanners'
const i18n = createI18n({
legacy: false,
locale: 'en',
messages: {
en: {
queue: {
jobAddedToQueue: 'Job added to queue',
jobQueueing: 'Job queueing'
},
sideToolbar: {
queueProgressOverlay: {
preview: 'Preview',
jobCompleted: 'Job completed',
jobFailed: 'Job failed',
jobsAddedToQueue:
'{count} job added to queue | {count} jobs added to queue',
jobsCompleted: '{count} job completed | {count} jobs completed',
jobsFailed: '{count} job failed | {count} jobs failed'
}
}
}
}
})
function renderComponent(notification: QueueNotificationBannerItem) {
return render(QueueNotificationBanner, {
props: { notification },
global: {
plugins: [i18n]
}
})
}
describe(QueueNotificationBanner, () => {
it('renders singular queued message without count prefix', () => {
renderComponent({
type: 'queued',
count: 1
})
expect(screen.getByText('Job added to queue')).toBeInTheDocument()
expect(screen.queryByText(/1 job/)).not.toBeInTheDocument()
})
it('renders queued message with pluralization', () => {
renderComponent({
type: 'queued',
count: 2
})
expect(screen.getByText('2 jobs added to queue')).toBeInTheDocument()
expect(screen.getByTestId('notification-icon')).toHaveClass(
'icon-[lucide--check]'
)
})
it('renders queued pending message with spinner icon', () => {
renderComponent({
type: 'queuedPending',
count: 1
})
expect(screen.getByText('Job queueing')).toBeInTheDocument()
const icon = screen.getByTestId('notification-icon')
expect(icon).toHaveClass('icon-[lucide--loader-circle]')
expect(icon).toHaveClass('animate-spin')
})
it('renders failed message and alert icon', () => {
renderComponent({
type: 'failed',
count: 1
})
expect(screen.getByText('Job failed')).toBeInTheDocument()
expect(screen.getByTestId('notification-icon')).toHaveClass(
'icon-[lucide--circle-alert]'
)
})
it('renders completed message with thumbnail preview when provided', () => {
renderComponent({
type: 'completed',
count: 3,
thumbnailUrls: ['https://example.com/preview.png']
})
expect(screen.getByText('3 jobs completed')).toBeInTheDocument()
const image = screen.getByRole('img')
expect(image).toHaveAttribute('src', 'https://example.com/preview.png')
expect(image).toHaveAttribute('alt', 'Preview')
})
it('renders two completion thumbnail previews', () => {
renderComponent({
type: 'completed',
count: 4,
thumbnailUrls: [
'https://example.com/preview-1.png',
'https://example.com/preview-2.png'
]
})
const images = screen.getAllByRole('img')
expect(images).toHaveLength(2)
expect(images[0]).toHaveAttribute(
'src',
'https://example.com/preview-1.png'
)
expect(images[1]).toHaveAttribute(
'src',
'https://example.com/preview-2.png'
)
})
it('caps completion thumbnail previews at two', () => {
renderComponent({
type: 'completed',
count: 4,
thumbnailUrls: [
'https://example.com/preview-1.png',
'https://example.com/preview-2.png',
'https://example.com/preview-3.png',
'https://example.com/preview-4.png'
]
})
const images = screen.getAllByRole('img')
expect(images).toHaveLength(2)
expect(images[0]).toHaveAttribute(
'src',
'https://example.com/preview-1.png'
)
expect(images[1]).toHaveAttribute(
'src',
'https://example.com/preview-2.png'
)
})
})