mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-23 06:10:32 +00:00
Group Nodes are a legacy feature superseded by Subgraphs. This removes all UI entry points for creating new Group Nodes, while keeping the loading, ungrouping, and management code intact so existing workflows that contain Group Nodes continue to load and can still be unpacked or managed. Removed entry points: - 'Convert selected nodes to group node' command - Alt+G keybinding - 'Convert to Group Node (Deprecated)' canvas and node context menu items - 'Convert to Group Node' option in the Vue selection menu - Associated en locale strings - Browser tests that exercised the creation flow
227 lines
8.1 KiB
TypeScript
227 lines
8.1 KiB
TypeScript
import { expect } from '@playwright/test'
|
|
|
|
import { NodeBadgeMode } from '@/types/nodeSource'
|
|
import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
|
|
import { DefaultGraphPositions } from '@e2e/fixtures/constants/defaultGraphPositions'
|
|
|
|
test.beforeEach(async ({ comfyPage }) => {
|
|
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled')
|
|
})
|
|
|
|
test.describe(
|
|
'Canvas Right Click Menu',
|
|
{ tag: ['@screenshot', '@ui'] },
|
|
() => {
|
|
test('Can add node', async ({ comfyPage }) => {
|
|
await comfyPage.canvasOps.rightClick()
|
|
await expect(comfyPage.canvas).toHaveScreenshot('right-click-menu.png')
|
|
await comfyPage.page.getByText('Add Node').click()
|
|
await comfyPage.page.getByText('loaders').click()
|
|
await comfyPage.page.getByText('Load VAE').click()
|
|
await comfyPage.contextMenu.waitForHidden()
|
|
await comfyPage.expectScreenshot(
|
|
comfyPage.canvas,
|
|
'add-node-node-added.png'
|
|
)
|
|
})
|
|
|
|
test('Can add group', async ({ comfyPage }) => {
|
|
await comfyPage.canvasOps.rightClick()
|
|
await expect(comfyPage.canvas).toHaveScreenshot('right-click-menu.png')
|
|
await comfyPage.page.getByText('Add Group', { exact: true }).click()
|
|
await comfyPage.contextMenu.waitForHidden()
|
|
await comfyPage.expectScreenshot(
|
|
comfyPage.canvas,
|
|
'add-group-group-added.png'
|
|
)
|
|
})
|
|
}
|
|
)
|
|
|
|
test.describe('Node Right Click Menu', { tag: ['@screenshot', '@ui'] }, () => {
|
|
test('Can open properties panel', async ({ comfyPage }) => {
|
|
await comfyPage.canvas.click({
|
|
position: DefaultGraphPositions.emptyLatentWidgetClick,
|
|
button: 'right'
|
|
})
|
|
await comfyPage.page.mouse.move(10, 10)
|
|
await comfyPage.expectScreenshot(comfyPage.canvas, 'right-click-node.png')
|
|
await comfyPage.page.getByText('Properties Panel').click()
|
|
await comfyPage.contextMenu.waitForHidden()
|
|
await comfyPage.expectScreenshot(
|
|
comfyPage.canvas,
|
|
'right-click-node-properties-panel.png'
|
|
)
|
|
})
|
|
|
|
test('Can collapse', async ({ comfyPage }) => {
|
|
await comfyPage.canvas.click({
|
|
position: DefaultGraphPositions.emptyLatentWidgetClick,
|
|
button: 'right'
|
|
})
|
|
await comfyPage.page.mouse.move(10, 10)
|
|
await comfyPage.expectScreenshot(comfyPage.canvas, 'right-click-node.png')
|
|
await comfyPage.page.getByText('Collapse').click()
|
|
await comfyPage.contextMenu.waitForHidden()
|
|
await comfyPage.expectScreenshot(
|
|
comfyPage.canvas,
|
|
'right-click-node-collapsed.png'
|
|
)
|
|
})
|
|
|
|
test('Can collapse (Node Badge)', async ({ comfyPage }) => {
|
|
await comfyPage.settings.setSetting(
|
|
'Comfy.NodeBadge.NodeIdBadgeMode',
|
|
NodeBadgeMode.ShowAll
|
|
)
|
|
await comfyPage.settings.setSetting(
|
|
'Comfy.NodeBadge.NodeSourceBadgeMode',
|
|
NodeBadgeMode.ShowAll
|
|
)
|
|
|
|
await comfyPage.canvas.click({
|
|
position: DefaultGraphPositions.emptyLatentWidgetClick,
|
|
button: 'right'
|
|
})
|
|
await comfyPage.page.mouse.move(10, 10)
|
|
await comfyPage.nextFrame()
|
|
await comfyPage.page.getByText('Collapse').click()
|
|
await comfyPage.contextMenu.waitForHidden()
|
|
await comfyPage.expectScreenshot(
|
|
comfyPage.canvas,
|
|
'right-click-node-collapsed-badge.png'
|
|
)
|
|
})
|
|
|
|
test('Can bypass', async ({ comfyPage }) => {
|
|
await comfyPage.canvas.click({
|
|
position: DefaultGraphPositions.emptyLatentWidgetClick,
|
|
button: 'right'
|
|
})
|
|
await comfyPage.page.mouse.move(10, 10)
|
|
await comfyPage.expectScreenshot(comfyPage.canvas, 'right-click-node.png')
|
|
await comfyPage.page.getByText('Bypass').click()
|
|
await comfyPage.contextMenu.waitForHidden()
|
|
await comfyPage.expectScreenshot(
|
|
comfyPage.canvas,
|
|
'right-click-node-bypassed.png'
|
|
)
|
|
})
|
|
|
|
test('Can pin and unpin', async ({ comfyPage }) => {
|
|
await comfyPage.settings.setSetting('Comfy.Graph.AutoPanSpeed', 0)
|
|
await comfyPage.canvas.click({
|
|
position: DefaultGraphPositions.emptyLatentWidgetClick,
|
|
button: 'right'
|
|
})
|
|
await comfyPage.page.mouse.move(10, 10)
|
|
await comfyPage.expectScreenshot(comfyPage.canvas, 'right-click-node.png')
|
|
await comfyPage.page.locator('.litemenu-entry:has-text("Pin")').click()
|
|
await comfyPage.contextMenu.waitForHidden()
|
|
await comfyPage.nextFrame()
|
|
|
|
// Get EmptyLatentImage node title position dynamically (for dragging)
|
|
const emptyLatentNode = await comfyPage.nodeOps.getNodeRefById(5)
|
|
const titlePos = await emptyLatentNode.getTitlePosition()
|
|
await comfyPage.canvasOps.dragAndDrop(titlePos, { x: 16, y: 16 })
|
|
await expect(comfyPage.canvas).toHaveScreenshot('node-pinned.png')
|
|
await comfyPage.canvas.click({
|
|
position: DefaultGraphPositions.emptyLatentWidgetClick,
|
|
button: 'right'
|
|
})
|
|
await comfyPage.page.mouse.move(10, 10)
|
|
await comfyPage.expectScreenshot(
|
|
comfyPage.canvas,
|
|
'right-click-pinned-node.png'
|
|
)
|
|
await comfyPage.page.locator('.litemenu-entry:has-text("Unpin")').click()
|
|
await comfyPage.contextMenu.waitForHidden()
|
|
await comfyPage.canvas.click({
|
|
position: DefaultGraphPositions.emptyLatentWidgetClick,
|
|
button: 'right'
|
|
})
|
|
await comfyPage.page.mouse.move(10, 10)
|
|
await comfyPage.expectScreenshot(
|
|
comfyPage.canvas,
|
|
'right-click-unpinned-node.png'
|
|
)
|
|
})
|
|
|
|
test('Can move after unpin', async ({ comfyPage }) => {
|
|
await comfyPage.canvas.click({
|
|
position: DefaultGraphPositions.emptyLatentWidgetClick,
|
|
button: 'right'
|
|
})
|
|
await comfyPage.page.mouse.move(10, 10)
|
|
await comfyPage.nextFrame()
|
|
await comfyPage.page.locator('.litemenu-entry:has-text("Pin")').click()
|
|
await comfyPage.contextMenu.waitForHidden()
|
|
await comfyPage.canvas.click({
|
|
position: DefaultGraphPositions.emptyLatentWidgetClick,
|
|
button: 'right'
|
|
})
|
|
await comfyPage.page.mouse.move(10, 10)
|
|
await comfyPage.nextFrame()
|
|
await comfyPage.page.locator('.litemenu-entry:has-text("Unpin")').click()
|
|
await comfyPage.contextMenu.waitForHidden()
|
|
await comfyPage.nextFrame()
|
|
|
|
// Get EmptyLatentImage node title position dynamically (for dragging)
|
|
const emptyLatentNode = await comfyPage.nodeOps.getNodeRefById(5)
|
|
const titlePos = await emptyLatentNode.getTitlePosition()
|
|
await comfyPage.canvasOps.dragAndDrop(titlePos, { x: 200, y: 590 })
|
|
await expect(comfyPage.canvas).toHaveScreenshot(
|
|
'right-click-unpinned-node-moved.png'
|
|
)
|
|
})
|
|
|
|
test('Can pin/unpin selected nodes', async ({ comfyPage }) => {
|
|
await comfyPage.nodeOps.selectNodes(['CLIP Text Encode (Prompt)'])
|
|
await comfyPage.page.keyboard.down('Control')
|
|
await comfyPage.canvas.click({
|
|
position: DefaultGraphPositions.emptyLatentWidgetClick,
|
|
button: 'right'
|
|
})
|
|
await comfyPage.page.mouse.move(10, 10)
|
|
await comfyPage.nextFrame()
|
|
await comfyPage.page.locator('.litemenu-entry:has-text("Pin")').click()
|
|
await comfyPage.page.keyboard.up('Control')
|
|
await comfyPage.contextMenu.waitForHidden()
|
|
await comfyPage.expectScreenshot(
|
|
comfyPage.canvas,
|
|
'selected-nodes-pinned.png'
|
|
)
|
|
await comfyPage.canvas.click({
|
|
position: DefaultGraphPositions.emptyLatentWidgetClick,
|
|
button: 'right'
|
|
})
|
|
await comfyPage.page.mouse.move(10, 10)
|
|
await comfyPage.nextFrame()
|
|
await comfyPage.page.locator('.litemenu-entry:has-text("Unpin")').click()
|
|
await comfyPage.contextMenu.waitForHidden()
|
|
await comfyPage.expectScreenshot(
|
|
comfyPage.canvas,
|
|
'selected-nodes-unpinned.png'
|
|
)
|
|
})
|
|
|
|
test('Can clone pinned nodes', async ({ comfyPage }) => {
|
|
const nodeCount = await comfyPage.nodeOps.getGraphNodesCount()
|
|
const node = (await comfyPage.nodeOps.getFirstNodeRef())!
|
|
await node.clickContextMenuOption('Pin')
|
|
await comfyPage.contextMenu.waitForHidden()
|
|
await node.click('title', { button: 'right' })
|
|
await expect(
|
|
comfyPage.page.locator('.litemenu-entry:has-text("Unpin")')
|
|
).toBeAttached()
|
|
const cloneItem = comfyPage.page.locator(
|
|
'.litemenu-entry:has-text("Clone")'
|
|
)
|
|
await cloneItem.click()
|
|
await comfyPage.contextMenu.waitForHidden()
|
|
await expect
|
|
.poll(() => comfyPage.nodeOps.getGraphNodesCount())
|
|
.toBe(nodeCount + 1)
|
|
})
|
|
})
|