diff --git a/browser_tests/fixtures/VueNodeHelpers.ts b/browser_tests/fixtures/VueNodeHelpers.ts index e3b3de542..b51750299 100644 --- a/browser_tests/fixtures/VueNodeHelpers.ts +++ b/browser_tests/fixtures/VueNodeHelpers.ts @@ -22,6 +22,13 @@ export class VueNodeHelpers { ) } + /** + * Get locator for a Vue node by the node's title (displayed name in the header) + */ + getNodeByTitle(title: string): Locator { + return this.page.locator(`[data-node-id]`).filter({ hasText: title }) + } + /** * Get total count of Vue nodes in the DOM */ diff --git a/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts b/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts index c80a86503..74ec17cc9 100644 --- a/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts +++ b/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts @@ -15,11 +15,10 @@ test.describe('Vue Node Bypass', () => { test('should allow toggling bypass on a selected node with hotkey', async ({ comfyPage }) => { - const checkpointNode = comfyPage.page.locator('[data-node-id]').filter({ - hasText: 'Load Checkpoint' - }) - await checkpointNode.getByText('Load Checkpoint').click() + await comfyPage.page.getByText('Load Checkpoint').click() await comfyPage.page.keyboard.press(BYPASS_HOTKEY) + + const checkpointNode = comfyPage.vueNodes.getNodeByTitle('Load Checkpoint') await expect(checkpointNode).toHaveClass(BYPASS_CLASS) await comfyPage.page.keyboard.press(BYPASS_HOTKEY) @@ -29,15 +28,12 @@ test.describe('Vue Node Bypass', () => { test('should allow toggling bypass on multiple selected nodes with hotkey', async ({ comfyPage }) => { - const checkpointNode = comfyPage.page.locator('[data-node-id]').filter({ - hasText: 'Load Checkpoint' - }) - const ksamplerNode = comfyPage.page.locator('[data-node-id]').filter({ - hasText: 'KSampler' - }) + await comfyPage.page.getByText('Load Checkpoint').click() + await comfyPage.page.getByText('KSampler').click({ modifiers: ['Control'] }) + + const checkpointNode = comfyPage.vueNodes.getNodeByTitle('Load Checkpoint') + const ksamplerNode = comfyPage.vueNodes.getNodeByTitle('KSampler') - await checkpointNode.getByText('Load Checkpoint').click() - await ksamplerNode.getByText('KSampler').click({ modifiers: ['Control'] }) await comfyPage.page.keyboard.press(BYPASS_HOTKEY) await expect(checkpointNode).toHaveClass(BYPASS_CLASS) await expect(ksamplerNode).toHaveClass(BYPASS_CLASS) diff --git a/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts b/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts new file mode 100644 index 000000000..37dcfd37b --- /dev/null +++ b/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts @@ -0,0 +1,45 @@ +import { + comfyExpect as expect, + comfyPageFixture as test +} from '../../../fixtures/ComfyPage' + +const MUTE_HOTKEY = 'Control+m' +const MUTE_CLASS = /opacity-50/ + +test.describe('Vue Node Mute', () => { + test.beforeEach(async ({ comfyPage }) => { + await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.vueNodes.waitForNodes() + }) + + test('should allow toggling mute on a selected node with hotkey', async ({ + comfyPage + }) => { + await comfyPage.page.getByText('Load Checkpoint').click() + await comfyPage.page.keyboard.press(MUTE_HOTKEY) + + const checkpointNode = comfyPage.vueNodes.getNodeByTitle('Load Checkpoint') + await expect(checkpointNode).toHaveClass(MUTE_CLASS) + + await comfyPage.page.keyboard.press(MUTE_HOTKEY) + await expect(checkpointNode).not.toHaveClass(MUTE_CLASS) + }) + + test('should allow toggling mute on multiple selected nodes with hotkey', async ({ + comfyPage + }) => { + await comfyPage.page.getByText('Load Checkpoint').click() + await comfyPage.page.getByText('KSampler').click({ modifiers: ['Control'] }) + + const checkpointNode = comfyPage.vueNodes.getNodeByTitle('Load Checkpoint') + const ksamplerNode = comfyPage.vueNodes.getNodeByTitle('KSampler') + + await comfyPage.page.keyboard.press(MUTE_HOTKEY) + await expect(checkpointNode).toHaveClass(MUTE_CLASS) + await expect(ksamplerNode).toHaveClass(MUTE_CLASS) + + await comfyPage.page.keyboard.press(MUTE_HOTKEY) + await expect(checkpointNode).not.toHaveClass(MUTE_CLASS) + await expect(ksamplerNode).not.toHaveClass(MUTE_CLASS) + }) +}) diff --git a/src/renderer/extensions/vueNodes/components/LGraphNode.vue b/src/renderer/extensions/vueNodes/components/LGraphNode.vue index 7171ec770..828ee3c8c 100644 --- a/src/renderer/extensions/vueNodes/components/LGraphNode.vue +++ b/src/renderer/extensions/vueNodes/components/LGraphNode.vue @@ -21,6 +21,8 @@ 'animate-pulse': executing, 'opacity-50 before:rounded-2xl before:pointer-events-none before:absolute before:bg-bypass/60 before:inset-0': bypassed, + 'opacity-50 before:rounded-2xl before:pointer-events-none before:absolute before:inset-0': + muted, 'will-change-transform': isDragging }, @@ -213,6 +215,7 @@ const hasAnyError = computed((): boolean => { }) const bypassed = computed((): boolean => nodeData.mode === 4) +const muted = computed((): boolean => nodeData.mode === 2) // NEVER mode // Use canvas interactions for proper wheel event handling and pointer event capture control const { handleWheel, shouldHandleNodePointerEvents } = useCanvasInteractions()