mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-30 19:21:54 +00:00
4.7 KiB
4.7 KiB
Node Patterns
⚠️ LiteGraph Mode: These patterns apply to the default LiteGraph canvas rendering. For Vue Nodes 2.0 (DOM-based rendering), see vue-nodes.md.
Mode Node Access Example LiteGraph comfyPage.getNodeRefsByTitle()[0]node.click(),node.getWidget('seed')Vue Nodes comfyPage.vueNodes.getNodeByTitle()Playwright locators, CSS classes
Getting Node References
By Title (Preferred)
// Use display names (e.g., 'KSampler', 'VAE Decode', 'CLIP Text Encode (Prompt)')
// These match the display_name from node definitions, not internal type names
const node = (await comfyPage.getNodeRefsByTitle('KSampler'))[0]
// For multi-selection
await comfyPage.selectNodes(['KSampler', 'VAE Decode'])
By ID
// When you know the specific node ID
const node = comfyPage.getNodeRefById(5)
First/Last Node
const firstNode = comfyPage.getFirstNode()
const lastNode = comfyPage.getLastNode()
Node Operations
Click Node
const node = (await comfyPage.getNodeRefsByTitle('KSampler'))[0]
await node.click()
await comfyPage.nextFrame()
Drag Node
const node = (await comfyPage.getNodeRefsByTitle('KSampler'))[0]
await node.drag({ x: 100, y: 50 })
await comfyPage.nextFrame()
Collapse/Expand
await node.collapse()
await comfyPage.nextFrame()
await node.expand()
await comfyPage.nextFrame()
// Assert state
await expect(node).toBeCollapsed()
Bypass
await node.bypass()
await comfyPage.nextFrame()
// Assert state
await expect(node).toBeBypassed()
Pin
await node.pin()
await comfyPage.nextFrame()
// Assert state
await expect(node).toBePinned()
Delete
await node.click()
await comfyPage.canvas.focus()
await comfyPage.page.keyboard.press('Delete')
await comfyPage.nextFrame()
Slots (Inputs/Outputs)
Get Slot Reference
// Output slot
const outputSlot = node.getOutputSlot('MODEL')
// Input slot
const inputSlot = node.getInputSlot('model')
Get Slot Position
const position = await outputSlot.getPosition()
// { x: number, y: number }
Connect Slots
const sourceNode = (await comfyPage.getNodeRefsByTitle('Load Checkpoint'))[0]
const targetNode = (await comfyPage.getNodeRefsByTitle('KSampler'))[0]
const outputSlot = sourceNode.getOutputSlot('MODEL')
const inputSlot = targetNode.getInputSlot('model')
await comfyMouse.dragFromTo(
await outputSlot.getPosition(),
await inputSlot.getPosition(),
{ steps: 10 }
)
await comfyPage.nextFrame()
Widgets
Get Widget
const widget = node.getWidget('seed')
const stepsWidget = node.getWidget('steps')
Set Widget Value
await widget.setValue(12345)
await comfyPage.nextFrame()
Get Widget Value
const value = await widget.getValue()
expect(value).toBe(12345)
Widget Types
See patterns/widgets.md for type-specific patterns.
Node Assertions
// Visibility
await expect(node.locator).toBeVisible()
// States (custom matchers)
await expect(node).toBeCollapsed()
await expect(node).toBeBypassed()
await expect(node).toBePinned()
Example: Complete Node Test
import {
comfyPageFixture as test,
comfyExpect as expect
} from './fixtures/ComfyPage'
test.describe('Node Operations', { tag: ['@node'] }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.loadWorkflow('nodes/basic')
await comfyPage.nextFrame()
})
test.afterEach(async ({ comfyPage }) => {
await comfyPage.resetView()
})
test('collapses and expands node', async ({ comfyPage }) => {
const node = (await comfyPage.getNodeRefsByTitle('KSampler'))[0]
await node.collapse()
await comfyPage.nextFrame()
await expect(node).toBeCollapsed()
await node.expand()
await comfyPage.nextFrame()
await expect(node).not.toBeCollapsed()
})
test('connects two nodes', async ({ comfyPage, comfyMouse }) => {
const source = (await comfyPage.getNodeRefsByTitle('Load Checkpoint'))[0]
const target = (await comfyPage.getNodeRefsByTitle('KSampler'))[0]
await comfyMouse.dragFromTo(
await source.getOutputSlot('MODEL').getPosition(),
await target.getInputSlot('model').getPosition(),
{ steps: 10 }
)
await comfyPage.nextFrame()
// Verify connection via screenshot or workflow state
await expect(comfyPage.canvas).toHaveScreenshot('connected.png')
})
})