fix: sync node.imgs in Vue nodes for Copy Image compatibility

- Add syncNodeImgs() to ImagePreview.vue to sync node.imgs on image load
- Simplify setupNodeForMaskEditor() to reuse sync logic
- Add aria-label to MaskEditorButton for accessibility
- Add browser test for mask editor button functionality
- Add unit test for node.imgs sync behavior

Fixes copy image and other legacy features that rely on node.imgs
This commit is contained in:
bymyself
2025-12-12 18:45:05 -08:00
parent db7beb6e9f
commit 9d4974e4ec
3 changed files with 14 additions and 12 deletions

View File

@@ -25,7 +25,9 @@ test.describe('Vue Nodes Mask Editor', () => {
waitForUpload: true
})
await comfyPage.page.waitForTimeout(500)
// Wait for image preview to appear
const imagePreview = comfyPage.page.locator('.image-preview img')
await expect(imagePreview).toBeVisible()
const maskEditorDialog = comfyPage.page.locator('.maskEditor-dialog-root')
@@ -33,9 +35,9 @@ test.describe('Vue Nodes Mask Editor', () => {
await comfyPage.selectNodes(['Load Image'])
await expect(comfyPage.selectionToolbox).toBeVisible()
const toolboxMaskButton = comfyPage.page.locator(
'.selection-toolbox button:has(.i-comfy\\:mask)'
)
const toolboxMaskButton = comfyPage.selectionToolbox.getByRole('button', {
name: /mask editor/i
})
await expect(toolboxMaskButton).toBeVisible()
await toolboxMaskButton.click()

View File

@@ -5,6 +5,7 @@
value: $t('commands.Comfy_MaskEditor_OpenMaskEditor.label'),
showDelay: 1000
}"
:aria-label="$t('commands.Comfy_MaskEditor_OpenMaskEditor.label')"
severity="secondary"
text
@click="openMaskEditor"

View File

@@ -1,6 +1,6 @@
import { createTestingPinia } from '@pinia/testing'
import { mount } from '@vue/test-utils'
import { describe, expect, it, vi } from 'vitest'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { nextTick } from 'vue'
import { createI18n } from 'vue-i18n'
@@ -58,6 +58,11 @@ describe('ImagePreview', () => {
]
}
beforeEach(() => {
delete mockNode.imgs
delete mockNode.imageIndex
})
const mountImagePreview = (props = {}) => {
return mount(ImagePreview, {
props: { ...defaultProps, ...props },
@@ -315,10 +320,6 @@ describe('ImagePreview', () => {
})
it('syncs node.imgs on image load for legacy compatibility', async () => {
// Reset mock node state
delete mockNode.imgs
delete mockNode.imageIndex
const wrapper = mountImagePreview({
imageUrls: [defaultProps.imageUrls[0]],
nodeId: 'test-node-123'
@@ -327,13 +328,11 @@ describe('ImagePreview', () => {
const img = wrapper.find('img')
expect(img.exists()).toBe(true)
// Simulate image load event
await img.trigger('load')
await nextTick()
// Verify node.imgs was synced
expect(mockNode.imgs).toBeDefined()
expect(mockNode.imgs).toHaveLength(1)
expect(mockNode.imgs?.[0]).toBe(img.element)
expect(mockNode.imageIndex).toBe(0)
})
})