diff --git a/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.png b/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.png index 8daf9f66b..2bf70f0d2 100644 Binary files a/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.png and b/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.png differ diff --git a/src/locales/en/main.json b/src/locales/en/main.json index 371ff3e09..11d915f2f 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -31,6 +31,7 @@ "logs": "Logs", "videoFailedToLoad": "Video failed to load", "audioFailedToLoad": "Audio failed to load", + "liveSamplingPreview": "Live sampling preview", "extensionName": "Extension Name", "reloadToApplyChanges": "Reload to apply changes", "insert": "Insert", diff --git a/src/renderer/extensions/vueNodes/VideoPreview.vue b/src/renderer/extensions/vueNodes/VideoPreview.vue index e32f569b6..f438d4f97 100644 --- a/src/renderer/extensions/vueNodes/VideoPreview.vue +++ b/src/renderer/extensions/vueNodes/VideoPreview.vue @@ -1,7 +1,7 @@ @@ -155,6 +149,7 @@ import { cn } from '@/utils/tailwindUtil' import { useNodeResize } from '../composables/useNodeResize' import { calculateIntrinsicSize } from '../utils/calculateIntrinsicSize' +import LivePreview from './LivePreview.vue' import NodeContent from './NodeContent.vue' import NodeHeader from './NodeHeader.vue' import NodeSlots from './NodeSlots.vue' diff --git a/src/renderer/extensions/vueNodes/components/LivePreview.vue b/src/renderer/extensions/vueNodes/components/LivePreview.vue new file mode 100644 index 000000000..84042cb41 --- /dev/null +++ b/src/renderer/extensions/vueNodes/components/LivePreview.vue @@ -0,0 +1,73 @@ + + + diff --git a/src/renderer/extensions/vueNodes/components/NodeContent.vue b/src/renderer/extensions/vueNodes/components/NodeContent.vue index 81165724a..1701f3584 100644 --- a/src/renderer/extensions/vueNodes/components/NodeContent.vue +++ b/src/renderer/extensions/vueNodes/components/NodeContent.vue @@ -2,7 +2,7 @@
{{ $t('Node Content Error') }}
-
+
{ + const defaultProps = { + imageUrl: '/api/view?filename=test_sample.png&type=temp' + } + + const mountLivePreview = (props = {}) => { + return mount(LivePreview, { + props: { ...defaultProps, ...props }, + global: { + plugins: [ + createTestingPinia({ + createSpy: vi.fn + }), + i18n + ], + stubs: { + 'i-lucide:image-off': true + } + } + }) + } + + it('renders preview when imageUrl provided', () => { + const wrapper = mountLivePreview() + + expect(wrapper.find('img').exists()).toBe(true) + expect(wrapper.find('img').attributes('src')).toBe(defaultProps.imageUrl) + }) + + it('does not render when no imageUrl provided', () => { + const wrapper = mountLivePreview({ imageUrl: null }) + + expect(wrapper.find('img').exists()).toBe(false) + expect(wrapper.text()).toBe('') + }) + + it('displays calculating dimensions text initially', () => { + const wrapper = mountLivePreview() + + expect(wrapper.text()).toContain('Calculating dimensions') + }) + + it('has proper accessibility attributes', () => { + const wrapper = mountLivePreview() + + const img = wrapper.find('img') + expect(img.attributes('alt')).toBe('Live sampling preview') + }) + + it('handles image load event', async () => { + const wrapper = mountLivePreview() + const img = wrapper.find('img') + + // Mock the naturalWidth and naturalHeight properties on the img element + Object.defineProperty(img.element, 'naturalWidth', { + writable: false, + value: 512 + }) + Object.defineProperty(img.element, 'naturalHeight', { + writable: false, + value: 512 + }) + + // Trigger the load event + await img.trigger('load') + + expect(wrapper.text()).toContain('512 x 512') + }) + + it('handles image error state', async () => { + const wrapper = mountLivePreview() + const img = wrapper.find('img') + + // Trigger the error event + await img.trigger('error') + + // Check that the image is hidden and error content is shown + expect(wrapper.find('img').exists()).toBe(false) + expect(wrapper.text()).toContain('Image failed to load') + }) + + it('resets state when imageUrl changes', async () => { + const wrapper = mountLivePreview() + const img = wrapper.find('img') + + // Set error state via event + await img.trigger('error') + expect(wrapper.text()).toContain('Error loading image') + + // Change imageUrl prop + await wrapper.setProps({ imageUrl: '/new-image.png' }) + await nextTick() + + // State should be reset - dimensions text should show calculating + expect(wrapper.text()).toContain('Calculating dimensions') + expect(wrapper.text()).not.toContain('Error loading image') + }) + + it('shows error state when image fails to load', async () => { + const wrapper = mountLivePreview() + const img = wrapper.find('img') + + // Trigger error event + await img.trigger('error') + + // Should show error state instead of image + expect(wrapper.find('img').exists()).toBe(false) + expect(wrapper.text()).toContain('Image failed to load') + expect(wrapper.text()).toContain('Error loading image') + }) +})