test: add e2e tests for slot context menu in Vue nodes mode

This commit is contained in:
bymyself
2026-03-13 10:15:34 -07:00
parent 372bd06ba9
commit 4d1272cedd

View File

@@ -0,0 +1,151 @@
import { expect } from '@playwright/test'
import { comfyPageFixture as test } from '../../../../fixtures/ComfyPage'
test.describe('Vue Nodes - Slot Context Menu', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', false)
await comfyPage.setup()
await comfyPage.vueNodes.waitForNodes()
})
test('Right-clicking an input slot dot shows the slot context menu', async ({
comfyPage
}) => {
// KSampler has input slots with connections — find any input slot
const ksamplerNode = comfyPage.vueNodes.getNodeByTitle('KSampler')
const inputSlot = ksamplerNode.locator('.lg-slot--input').first()
await expect(inputSlot).toBeVisible()
// Click on the left edge where the SlotConnectionDot is
await inputSlot.click({ button: 'right', position: { x: 6, y: 12 } })
// The custom slot context menu should appear (role="menu" is on the
// teleported menu, not on the PrimeVue node context menu)
const slotMenu = comfyPage.page.locator(
'div[role="menu"]:not(.p-contextmenu)'
)
await expect(slotMenu).toBeVisible()
// Should show "Rename" since standard slots are not nameLocked
await expect(
slotMenu.getByRole('menuitem', { name: 'Rename' })
).toBeVisible()
})
test('Right-clicking the node body shows the node context menu, not the slot menu', async ({
comfyPage
}) => {
const ksamplerNode = comfyPage.vueNodes.getNodeByTitle('KSampler')
const nodeBody = ksamplerNode.locator('[data-testid^="node-body-"]')
await expect(nodeBody).toBeVisible()
await nodeBody.click({ button: 'right' })
await comfyPage.nextFrame()
// The PrimeVue node context menu should appear
const nodeMenu = comfyPage.page.locator('.p-contextmenu')
await expect(nodeMenu).toBeVisible()
// Slot-specific items should NOT be present
await expect(
comfyPage.page.getByRole('menuitem', { name: 'Disconnect Links' })
).not.toBeVisible()
})
test('Right-clicking an output slot dot shows the slot context menu', async ({
comfyPage
}) => {
const checkpointNode =
comfyPage.vueNodes.getNodeByTitle('Load Checkpoint')
const outputSlot = checkpointNode.locator('.lg-slot--output').first()
await expect(outputSlot).toBeVisible()
// Click on the right edge where the output SlotConnectionDot is
const box = await outputSlot.boundingBox()
await outputSlot.click({
button: 'right',
position: { x: (box?.width ?? 24) - 6, y: 12 }
})
const slotMenu = comfyPage.page.locator(
'div[role="menu"]:not(.p-contextmenu)'
)
await expect(slotMenu).toBeVisible()
await expect(
slotMenu.getByRole('menuitem', { name: 'Rename' })
).toBeVisible()
})
test('Slot context menu closes when clicking outside', async ({
comfyPage
}) => {
const ksamplerNode = comfyPage.vueNodes.getNodeByTitle('KSampler')
const inputSlot = ksamplerNode.locator('.lg-slot--input').first()
await expect(inputSlot).toBeVisible()
await inputSlot.click({ button: 'right', position: { x: 6, y: 12 } })
const slotMenu = comfyPage.page.locator(
'div[role="menu"]:not(.p-contextmenu)'
)
await expect(slotMenu).toBeVisible()
// Press Escape to close the menu
await comfyPage.page.keyboard.press('Escape')
await expect(slotMenu).not.toBeVisible()
})
test('Slot context menu Disconnect Links removes connections', async ({
comfyPage
}) => {
// Use page.evaluate to find a KSampler input with an active link
const slotIndex = await comfyPage.page.evaluate(() => {
const graph = window.app!.graph!
const nodes = graph.findNodesByType('KSampler', [])
const ksamplerNode = nodes.find((n) =>
n.inputs?.some((i) => i.link != null)
)
if (!ksamplerNode) return -1
return ksamplerNode.inputs!.findIndex((i) => i.link != null)
})
expect(slotIndex).toBeGreaterThanOrEqual(0)
// Find the corresponding Vue input slot
const ksamplerNode = comfyPage.vueNodes.getNodeByTitle('KSampler')
const inputSlot = ksamplerNode.locator('.lg-slot--input').nth(slotIndex)
await expect(inputSlot).toBeVisible()
await inputSlot.click({ button: 'right', position: { x: 6, y: 12 } })
const slotMenu = comfyPage.page.locator(
'div[role="menu"]:not(.p-contextmenu)'
)
await expect(slotMenu).toBeVisible()
await expect(
slotMenu.getByRole('menuitem', { name: 'Disconnect Links' })
).toBeVisible()
await slotMenu
.getByRole('menuitem', { name: 'Disconnect Links' })
.click()
// Menu should close
await expect(slotMenu).not.toBeVisible()
// Verify the link was removed in the graph
const linkRemoved = await comfyPage.page.evaluate(
(idx) => {
const graph = window.app!.graph!
const node = graph.findNodesByType('KSampler', [])[0]
return node?.inputs?.[idx]?.link == null
},
slotIndex
)
expect(linkRemoved).toBe(true)
})
})