mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-28 02:02:08 +00:00
Backport of #7902 to cloud/1.36
Original PR: https://github.com/Comfy-Org/ComfyUI_frontend/pull/7902
Cherry-picked merge commit e26e1f0c9e.
## Conflicts resolved
- **pnpm-lock.yaml**: Regenerated with `pnpm install`
-
**tests-ui/tests/components/dialog/footer/ManagerProgressFooter.test.ts**:
Removed (PR deletes this file along with the component it tested)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7918-backport-cloud-1-36-feat-add-HoneyToast-component-for-persistent-progress-notification-2e36d73d3650811a9f57f26c56b84c97)
by [Unito](https://www.unito.io)
Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: sno <snomiao@gmail.com>
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: GitHub Action <action@github.com>
138 lines
4.0 KiB
TypeScript
138 lines
4.0 KiB
TypeScript
import type { VueWrapper } from '@vue/test-utils'
|
|
import { mount } from '@vue/test-utils'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { defineComponent, h, nextTick, ref } from 'vue'
|
|
|
|
import HoneyToast from './HoneyToast.vue'
|
|
|
|
describe('HoneyToast', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
document.body.innerHTML = ''
|
|
})
|
|
|
|
function mountComponent(
|
|
props: { visible: boolean; expanded?: boolean } = { visible: true }
|
|
): VueWrapper {
|
|
return mount(HoneyToast, {
|
|
props,
|
|
slots: {
|
|
default: (slotProps: { isExpanded: boolean }) =>
|
|
h(
|
|
'div',
|
|
{ 'data-testid': 'content' },
|
|
slotProps.isExpanded ? 'expanded' : 'collapsed'
|
|
),
|
|
footer: (slotProps: { isExpanded: boolean; toggle: () => void }) =>
|
|
h(
|
|
'button',
|
|
{
|
|
'data-testid': 'toggle-btn',
|
|
onClick: slotProps.toggle
|
|
},
|
|
slotProps.isExpanded ? 'Collapse' : 'Expand'
|
|
)
|
|
},
|
|
attachTo: document.body
|
|
})
|
|
}
|
|
|
|
it('renders when visible is true', async () => {
|
|
const wrapper = mountComponent({ visible: true })
|
|
await nextTick()
|
|
|
|
const toast = document.body.querySelector('[role="status"]')
|
|
expect(toast).toBeTruthy()
|
|
|
|
wrapper.unmount()
|
|
})
|
|
|
|
it('does not render when visible is false', async () => {
|
|
const wrapper = mountComponent({ visible: false })
|
|
await nextTick()
|
|
|
|
const toast = document.body.querySelector('[role="status"]')
|
|
expect(toast).toBeFalsy()
|
|
|
|
wrapper.unmount()
|
|
})
|
|
|
|
it('passes is-expanded=false to slots by default', async () => {
|
|
const wrapper = mountComponent({ visible: true })
|
|
await nextTick()
|
|
|
|
const content = document.body.querySelector('[data-testid="content"]')
|
|
expect(content?.textContent).toBe('collapsed')
|
|
|
|
wrapper.unmount()
|
|
})
|
|
|
|
it('applies collapsed max-height class when collapsed', async () => {
|
|
const wrapper = mountComponent({ visible: true, expanded: false })
|
|
await nextTick()
|
|
|
|
const expandableArea = document.body.querySelector(
|
|
'[role="status"] > div:first-child'
|
|
)
|
|
expect(expandableArea?.classList.contains('max-h-0')).toBe(true)
|
|
|
|
wrapper.unmount()
|
|
})
|
|
|
|
it('has aria-live="polite" for accessibility', async () => {
|
|
const wrapper = mountComponent({ visible: true })
|
|
await nextTick()
|
|
|
|
const toast = document.body.querySelector('[role="status"]')
|
|
expect(toast?.getAttribute('aria-live')).toBe('polite')
|
|
|
|
wrapper.unmount()
|
|
})
|
|
|
|
it('supports v-model:expanded with reactive parent state', async () => {
|
|
const TestWrapper = defineComponent({
|
|
components: { HoneyToast },
|
|
setup() {
|
|
const expanded = ref(false)
|
|
return { expanded }
|
|
},
|
|
template: `
|
|
<HoneyToast :visible="true" v-model:expanded="expanded">
|
|
<template #default="slotProps">
|
|
<div data-testid="content">{{ slotProps.isExpanded ? 'expanded' : 'collapsed' }}</div>
|
|
</template>
|
|
<template #footer="slotProps">
|
|
<button data-testid="toggle-btn" @click="slotProps.toggle">
|
|
{{ slotProps.isExpanded ? 'Collapse' : 'Expand' }}
|
|
</button>
|
|
</template>
|
|
</HoneyToast>
|
|
`
|
|
})
|
|
|
|
const wrapper = mount(TestWrapper, { attachTo: document.body })
|
|
await nextTick()
|
|
|
|
const content = document.body.querySelector('[data-testid="content"]')
|
|
expect(content?.textContent).toBe('collapsed')
|
|
|
|
const toggleBtn = document.body.querySelector(
|
|
'[data-testid="toggle-btn"]'
|
|
) as HTMLButtonElement
|
|
expect(toggleBtn?.textContent?.trim()).toBe('Expand')
|
|
|
|
toggleBtn?.click()
|
|
await nextTick()
|
|
|
|
expect(content?.textContent).toBe('expanded')
|
|
expect(toggleBtn?.textContent?.trim()).toBe('Collapse')
|
|
|
|
const expandableArea = document.body.querySelector(
|
|
'[role="status"] > div:first-child'
|
|
)
|
|
expect(expandableArea?.classList.contains('max-h-[400px]')).toBe(true)
|
|
|
|
wrapper.unmount()
|
|
})
|
|
})
|