diff --git a/browser_tests/ComfyPage.ts b/browser_tests/ComfyPage.ts index c30143ceb..8bc2cca07 100644 --- a/browser_tests/ComfyPage.ts +++ b/browser_tests/ComfyPage.ts @@ -1198,6 +1198,11 @@ export class NodeReference { ) return originSlot } + async getContextMenuOptionNames() { + await this.click('title', { button: 'right' }) + const ctx = this.comfyPage.page.locator('.litecontextmenu') + return await ctx.locator('.litemenu-entry').allInnerTexts() + } async clickContextMenuOption(optionText: string) { await this.click('title', { button: 'right' }) const ctx = this.comfyPage.page.locator('.litecontextmenu') diff --git a/browser_tests/rightClickMenu.spec.ts b/browser_tests/rightClickMenu.spec.ts index 05335e1e1..ab3ad57dd 100644 --- a/browser_tests/rightClickMenu.spec.ts +++ b/browser_tests/rightClickMenu.spec.ts @@ -93,16 +93,54 @@ test.describe('Node Right Click Menu', () => { ) }) - test('Can convert widget to input', async ({ comfyPage }) => { - await comfyPage.rightClickEmptyLatentNode() - await expect(comfyPage.canvas).toHaveScreenshot('right-click-node.png') - await comfyPage.page.getByText('Convert Widget to Input').click() - await comfyPage.nextFrame() - await comfyPage.page.getByText('Convert width to input').click() - await comfyPage.nextFrame() - await expect(comfyPage.canvas).toHaveScreenshot( - 'right-click-node-widget-converted.png' - ) + test.describe('Widget conversion', () => { + const convertibleWidgetTypes = ['text', 'string', 'number', 'toggle'] + + test.afterEach(async ({ comfyPage }) => { + // Restore default setting value + await comfyPage.setSetting('Comfy.NodeInputConversionSubmenus', true) + }) + + test('Can convert widget to input', async ({ comfyPage }) => { + await comfyPage.rightClickEmptyLatentNode() + await expect(comfyPage.canvas).toHaveScreenshot('right-click-node.png') + await comfyPage.page.getByText('Convert Widget to Input').click() + await comfyPage.nextFrame() + await comfyPage.page.getByText('Convert width to input').click() + await comfyPage.nextFrame() + await expect(comfyPage.canvas).toHaveScreenshot( + 'right-click-node-widget-converted.png' + ) + }) + + convertibleWidgetTypes.forEach((widgetType) => { + test(`Can convert ${widgetType} widget to input`, async ({ + comfyPage + }) => { + const nodeType = 'KSampler' + + // To avoid needing multiple clicks, disable nesting of conversion options + await comfyPage.setSetting('Comfy.NodeInputConversionSubmenus', false) + + // Add the widget using the node's `addWidget` method + await comfyPage.page.evaluate( + ([nodeType, widgetType]) => { + const node = window['app'].graph.nodes.find( + (n) => n.type === nodeType + ) + node.addWidget(widgetType, widgetType, 'defaultValue', () => {}, {}) + }, + [nodeType, widgetType] + ) + + // Verify the context menu includes the conversion option + const node = (await comfyPage.getNodeRefsByType(nodeType))[0] + const menuOptions = await node.getContextMenuOptionNames() + expect(menuOptions.includes(`Convert ${widgetType} to input`)).toBe( + true + ) + }) + }) }) test('Can pin and unpin', async ({ comfyPage }) => { diff --git a/src/extensions/core/widgetInputs.ts b/src/extensions/core/widgetInputs.ts index 3402ebb8b..c18cb5014 100644 --- a/src/extensions/core/widgetInputs.ts +++ b/src/extensions/core/widgetInputs.ts @@ -6,7 +6,15 @@ import type { INodeInputSlot, IWidget } from '@comfyorg/litegraph' import type { InputSpec } from '@/types/apiTypes' const CONVERTED_TYPE = 'converted-widget' -const VALID_TYPES = ['STRING', 'combo', 'number', 'toggle', 'BOOLEAN'] +const VALID_TYPES = [ + 'STRING', + 'combo', + 'number', + 'toggle', + 'BOOLEAN', + 'text', + 'string' +] const CONFIG = Symbol() const GET_CONFIG = Symbol() const TARGET = Symbol() // Used for reroutes to specify the real target widget