add CanvasNavigationMode (#4533)

Co-authored-by: bymyself <cbyrne@comfy.org>
Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Terry Jia
2025-07-25 22:01:43 -04:00
committed by GitHub
parent 271643aa93
commit e3628ed156
24 changed files with 297 additions and 46 deletions

View File

@@ -803,3 +803,222 @@ test.describe('Viewport settings', () => {
)
})
})
test.describe('Canvas Navigation', () => {
test.describe('Legacy Mode', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.setSetting('Comfy.Canvas.NavigationMode', 'legacy')
})
test('Left-click drag in empty area should pan canvas', async ({
comfyPage
}) => {
await comfyPage.dragAndDrop({ x: 50, y: 50 }, { x: 150, y: 150 })
await expect(comfyPage.canvas).toHaveScreenshot(
'legacy-left-drag-pan.png'
)
})
test('Middle-click drag should pan canvas', async ({ comfyPage }) => {
await comfyPage.page.mouse.move(50, 50)
await comfyPage.page.mouse.down({ button: 'middle' })
await comfyPage.page.mouse.move(150, 150)
await comfyPage.page.mouse.up({ button: 'middle' })
await comfyPage.nextFrame()
await expect(comfyPage.canvas).toHaveScreenshot(
'legacy-middle-drag-pan.png'
)
})
test('Mouse wheel should zoom in/out', async ({ comfyPage }) => {
await comfyPage.page.mouse.move(400, 300)
await comfyPage.page.mouse.wheel(0, -120)
await comfyPage.nextFrame()
await expect(comfyPage.canvas).toHaveScreenshot(
'legacy-wheel-zoom-in.png'
)
await comfyPage.page.mouse.wheel(0, 240)
await comfyPage.nextFrame()
await expect(comfyPage.canvas).toHaveScreenshot(
'legacy-wheel-zoom-out.png'
)
})
test('Left-click on node should not pan canvas', async ({ comfyPage }) => {
await comfyPage.clickTextEncodeNode1()
const selectedCount = await comfyPage.getSelectedGraphNodesCount()
expect(selectedCount).toBe(1)
await expect(comfyPage.canvas).toHaveScreenshot(
'legacy-click-node-select.png'
)
})
})
test.describe('Standard Mode', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.setSetting('Comfy.Canvas.NavigationMode', 'standard')
})
test('Left-click drag in empty area should select nodes', async ({
comfyPage
}) => {
const clipNodes = await comfyPage.getNodeRefsByType('CLIPTextEncode')
const clipNode1Pos = await clipNodes[0].getPosition()
const clipNode2Pos = await clipNodes[1].getPosition()
const offset = 64
await comfyPage.dragAndDrop(
{
x: Math.min(clipNode1Pos.x, clipNode2Pos.x) - offset,
y: Math.min(clipNode1Pos.y, clipNode2Pos.y) - offset
},
{
x: Math.max(clipNode1Pos.x, clipNode2Pos.x) + offset,
y: Math.max(clipNode1Pos.y, clipNode2Pos.y) + offset
}
)
const selectedCount = await comfyPage.getSelectedGraphNodesCount()
expect(selectedCount).toBe(clipNodes.length)
await expect(comfyPage.canvas).toHaveScreenshot(
'standard-left-drag-select.png'
)
})
test('Middle-click drag should pan canvas', async ({ comfyPage }) => {
await comfyPage.page.mouse.move(50, 50)
await comfyPage.page.mouse.down({ button: 'middle' })
await comfyPage.page.mouse.move(150, 150)
await comfyPage.page.mouse.up({ button: 'middle' })
await comfyPage.nextFrame()
await expect(comfyPage.canvas).toHaveScreenshot(
'standard-middle-drag-pan.png'
)
})
test('Ctrl + mouse wheel should zoom in/out', async ({ comfyPage }) => {
await comfyPage.page.mouse.move(400, 300)
await comfyPage.page.keyboard.down('Control')
await comfyPage.page.mouse.wheel(0, -120)
await comfyPage.page.keyboard.up('Control')
await comfyPage.nextFrame()
await expect(comfyPage.canvas).toHaveScreenshot(
'standard-ctrl-wheel-zoom-in.png'
)
await comfyPage.page.keyboard.down('Control')
await comfyPage.page.mouse.wheel(0, 240)
await comfyPage.page.keyboard.up('Control')
await comfyPage.nextFrame()
await expect(comfyPage.canvas).toHaveScreenshot(
'standard-ctrl-wheel-zoom-out.png'
)
})
test('Left-click on node should select node (not start selection box)', async ({
comfyPage
}) => {
await comfyPage.clickTextEncodeNode1()
const selectedCount = await comfyPage.getSelectedGraphNodesCount()
expect(selectedCount).toBe(1)
await expect(comfyPage.canvas).toHaveScreenshot(
'standard-click-node-select.png'
)
})
test('Space + left-click drag should pan canvas', async ({ comfyPage }) => {
// Click canvas to focus it
await comfyPage.page.click('canvas')
await comfyPage.nextFrame()
await comfyPage.page.keyboard.down('Space')
await comfyPage.dragAndDrop({ x: 50, y: 50 }, { x: 150, y: 150 })
await comfyPage.page.keyboard.up('Space')
await expect(comfyPage.canvas).toHaveScreenshot(
'standard-space-drag-pan.png'
)
})
test('Space key overrides default left-click behavior', async ({
comfyPage
}) => {
const clipNodes = await comfyPage.getNodeRefsByType('CLIPTextEncode')
const clipNode1Pos = await clipNodes[0].getPosition()
const offset = 64
await comfyPage.dragAndDrop(
{
x: clipNode1Pos.x - offset,
y: clipNode1Pos.y - offset
},
{
x: clipNode1Pos.x + offset,
y: clipNode1Pos.y + offset
}
)
const selectedCountAfterDrag =
await comfyPage.getSelectedGraphNodesCount()
expect(selectedCountAfterDrag).toBeGreaterThan(0)
await comfyPage.clickEmptySpace()
const selectedCountAfterClear =
await comfyPage.getSelectedGraphNodesCount()
expect(selectedCountAfterClear).toBe(0)
await comfyPage.page.keyboard.down('Space')
await comfyPage.dragAndDrop(
{
x: clipNode1Pos.x - offset,
y: clipNode1Pos.y - offset
},
{
x: clipNode1Pos.x + offset,
y: clipNode1Pos.y + offset
}
)
await comfyPage.page.keyboard.up('Space')
const selectedCountAfterSpaceDrag =
await comfyPage.getSelectedGraphNodesCount()
expect(selectedCountAfterSpaceDrag).toBe(0)
})
})
test.describe('Edge Cases', () => {
test('Multiple modifier keys work correctly in legacy mode', async ({
comfyPage
}) => {
await comfyPage.setSetting('Comfy.Canvas.NavigationMode', 'legacy')
await comfyPage.page.keyboard.down('Alt')
await comfyPage.page.keyboard.down('Shift')
await comfyPage.dragAndDrop({ x: 50, y: 50 }, { x: 150, y: 150 })
await comfyPage.page.keyboard.up('Shift')
await comfyPage.page.keyboard.up('Alt')
await expect(comfyPage.canvas).toHaveScreenshot(
'legacy-alt-shift-drag.png'
)
})
test('Cursor changes appropriately in different modes', async ({
comfyPage
}) => {
const getCursorStyle = async () => {
return await comfyPage.page.evaluate(() => {
return (
document.getElementById('graph-canvas')!.style.cursor || 'default'
)
})
}
await comfyPage.setSetting('Comfy.Canvas.NavigationMode', 'legacy')
await comfyPage.page.mouse.move(50, 50)
await comfyPage.page.mouse.down()
expect(await getCursorStyle()).toBe('grabbing')
await comfyPage.page.mouse.up()
})
})
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB