Files
ComfyUI_frontend/src/renderer/extensions/vueNodes/widgets/components/WidgetButton.test.ts
Alexander Brown b994608506 Tests: Vitest configuration cleanup (#5888)
## Summary

Simplify default scripts. Filtering is still available to users, we can
revisit tagging or grouping later.
This fixes the issue where we had tests that were in the codebase but
never run because they weren't under `/src/components`

Also deletes the duplicate litegraph tests and their associated vitest
config file.

## Changes

- **What**: Test cleanup

## Review Focus

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5888-Tests-Vitest-configuration-cleanup-2806d73d36508197b800f68f0b028279)
by [Unito](https://www.unito.io)
2025-10-02 21:01:42 -07:00

218 lines
6.5 KiB
TypeScript

import { mount } from '@vue/test-utils'
import Button from 'primevue/button'
import type { ButtonProps } from 'primevue/button'
import PrimeVue from 'primevue/config'
import { describe, expect, it, vi } from 'vitest'
import WidgetButton from '@/renderer/extensions/vueNodes/widgets/components/WidgetButton.vue'
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
describe('WidgetButton Interactions', () => {
const createMockWidget = (
options: Partial<ButtonProps> = {},
callback?: () => void,
name: string = 'test_button'
): SimplifiedWidget<void> => ({
name,
type: 'button',
value: undefined,
options,
callback
})
const mountComponent = (widget: SimplifiedWidget<void>, readonly = false) => {
return mount(WidgetButton, {
global: {
plugins: [PrimeVue],
components: { Button }
},
props: {
widget,
readonly
}
})
}
const clickButton = async (wrapper: ReturnType<typeof mount>) => {
const button = wrapper.findComponent({ name: 'Button' })
await button.trigger('click')
return button
}
describe('Click Handling', () => {
it('calls callback when button is clicked', async () => {
const mockCallback = vi.fn()
const widget = createMockWidget({}, mockCallback)
const wrapper = mountComponent(widget)
await clickButton(wrapper)
expect(mockCallback).toHaveBeenCalledTimes(1)
})
it('handles missing callback gracefully', async () => {
const widget = createMockWidget({}, undefined)
const wrapper = mountComponent(widget)
// Should not throw error when clicking without callback
await expect(clickButton(wrapper)).resolves.toBeDefined()
})
it('calls callback multiple times when clicked multiple times', async () => {
const mockCallback = vi.fn()
const widget = createMockWidget({}, mockCallback)
const wrapper = mountComponent(widget)
const numClicks = 8
for (let i = 0; i < numClicks; i++) {
await clickButton(wrapper)
}
expect(mockCallback).toHaveBeenCalledTimes(numClicks)
})
})
describe('Component Rendering', () => {
it('renders button component', () => {
const widget = createMockWidget()
const wrapper = mountComponent(widget)
const button = wrapper.findComponent({ name: 'Button' })
expect(button.exists()).toBe(true)
})
it('renders widget label when name is provided', () => {
const widget = createMockWidget()
const wrapper = mountComponent(widget)
const label = wrapper.find('label')
expect(label.exists()).toBe(true)
expect(label.text()).toBe('test_button')
})
it('does not render label when widget name is empty', () => {
const widget = createMockWidget({}, undefined, '')
const wrapper = mountComponent(widget)
const label = wrapper.find('label')
expect(label.exists()).toBe(false)
})
it('sets button size to small', () => {
const widget = createMockWidget()
const wrapper = mountComponent(widget)
const button = wrapper.findComponent({ name: 'Button' })
expect(button.props('size')).toBe('small')
})
it('passes widget options to button component', () => {
const buttonOptions = {
label: 'Custom Label',
icon: 'pi pi-check',
severity: 'success' as const
}
const widget = createMockWidget(buttonOptions)
const wrapper = mountComponent(widget)
const button = wrapper.findComponent({ name: 'Button' })
expect(button.props('label')).toBe('Custom Label')
expect(button.props('icon')).toBe('pi pi-check')
expect(button.props('severity')).toBe('success')
})
})
describe('Widget Options', () => {
it('handles button with text only', () => {
const widget = createMockWidget({ label: 'Click Me' })
const wrapper = mountComponent(widget)
const button = wrapper.findComponent({ name: 'Button' })
expect(button.props('label')).toBe('Click Me')
expect(button.props('icon')).toBeNull()
})
it('handles button with icon only', () => {
const widget = createMockWidget({ icon: 'pi pi-star' })
const wrapper = mountComponent(widget)
const button = wrapper.findComponent({ name: 'Button' })
expect(button.props('icon')).toBe('pi pi-star')
})
it('handles button with both text and icon', () => {
const widget = createMockWidget({
label: 'Save',
icon: 'pi pi-save'
})
const wrapper = mountComponent(widget)
const button = wrapper.findComponent({ name: 'Button' })
expect(button.props('label')).toBe('Save')
expect(button.props('icon')).toBe('pi pi-save')
})
it.for([
'secondary',
'success',
'info',
'warning',
'danger',
'help',
'contrast'
] as const)('handles button severity: %s', (severity) => {
const widget = createMockWidget({ severity })
const wrapper = mountComponent(widget)
const button = wrapper.findComponent({ name: 'Button' })
expect(button.props('severity')).toBe(severity)
})
it.for(['outlined', 'text'] as const)(
'handles button variant: %s',
(variant) => {
const widget = createMockWidget({ variant })
const wrapper = mountComponent(widget)
const button = wrapper.findComponent({ name: 'Button' })
expect(button.props('variant')).toBe(variant)
}
)
})
describe('Edge Cases', () => {
it('handles widget with no options', () => {
const widget = createMockWidget()
const wrapper = mountComponent(widget)
const button = wrapper.findComponent({ name: 'Button' })
expect(button.exists()).toBe(true)
})
it('handles callback that throws error', async () => {
const mockCallback = vi.fn(() => {
throw new Error('Callback error')
})
const widget = createMockWidget({}, mockCallback)
const wrapper = mountComponent(widget)
// Should not break the component when callback throws
await expect(clickButton(wrapper)).rejects.toThrow('Callback error')
expect(mockCallback).toHaveBeenCalledTimes(1)
})
it('handles rapid consecutive clicks', async () => {
const mockCallback = vi.fn()
const widget = createMockWidget({}, mockCallback)
const wrapper = mountComponent(widget)
// Simulate rapid clicks
const clickPromises = Array.from({ length: 16 }, () =>
clickButton(wrapper)
)
await Promise.all(clickPromises)
expect(mockCallback).toHaveBeenCalledTimes(16)
})
})
})