mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 06:20:11 +00:00
Backport of #10337 to `core/1.42` Automatically created by backport workflow. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-10743-backport-core-1-42-feat-App-mode-Switch-to-Nodes-2-0-when-entering-builder-3336d73d365081c58cbade12aa6ecf05) by [Unito](https://www.unito.io) Co-authored-by: pythongosssss <125205205+pythongosssss@users.noreply.github.com>
168 lines
5.5 KiB
TypeScript
168 lines
5.5 KiB
TypeScript
import type { ComfyPage } from '../fixtures/ComfyPage'
|
|
import {
|
|
comfyPageFixture as test,
|
|
comfyExpect as expect
|
|
} from '../fixtures/ComfyPage'
|
|
import { fitToViewInstant } from '../helpers/fitToView'
|
|
import { getPromotedWidgetNames } from '../helpers/promotedWidgets'
|
|
|
|
/**
|
|
* Convert the KSampler (id 3) in the default workflow to a subgraph,
|
|
* enter builder, select the promoted seed widget as input and
|
|
* SaveImage/PreviewImage as output.
|
|
*
|
|
* Returns the subgraph node reference for further interaction.
|
|
*/
|
|
async function setupSubgraphBuilder(comfyPage: ComfyPage) {
|
|
const { page, appMode } = comfyPage
|
|
await comfyPage.workflow.loadWorkflow('default')
|
|
|
|
const ksampler = await comfyPage.nodeOps.getNodeRefById('3')
|
|
await ksampler.click('title')
|
|
const subgraphNode = await ksampler.convertToSubgraph()
|
|
await comfyPage.nextFrame()
|
|
|
|
const subgraphNodeId = String(subgraphNode.id)
|
|
const promotedNames = await getPromotedWidgetNames(comfyPage, subgraphNodeId)
|
|
expect(promotedNames).toContain('seed')
|
|
|
|
await fitToViewInstant(comfyPage)
|
|
await appMode.enterBuilder()
|
|
await appMode.goToInputs()
|
|
|
|
// Reset zoom to 1 and center on the subgraph node so click coords are accurate
|
|
await comfyPage.canvasOps.setScale(1)
|
|
await subgraphNode.centerOnNode()
|
|
|
|
// Click the promoted seed widget on the canvas to select it
|
|
const seedWidgetRef = await subgraphNode.getWidget(0)
|
|
const seedPos = await seedWidgetRef.getPosition()
|
|
const titleHeight = await page.evaluate(
|
|
() => window.LiteGraph!['NODE_TITLE_HEIGHT'] as number
|
|
)
|
|
|
|
await page.mouse.click(seedPos.x, seedPos.y + titleHeight)
|
|
await comfyPage.nextFrame()
|
|
|
|
// Select an output node
|
|
await appMode.goToOutputs()
|
|
|
|
const saveImageNodeId = await page.evaluate(() =>
|
|
String(
|
|
window.app!.rootGraph.nodes.find(
|
|
(n: { type?: string }) =>
|
|
n.type === 'SaveImage' || n.type === 'PreviewImage'
|
|
)?.id
|
|
)
|
|
)
|
|
const saveImageRef = await comfyPage.nodeOps.getNodeRefById(saveImageNodeId)
|
|
await saveImageRef.centerOnNode()
|
|
|
|
// Node is centered on screen, so click the canvas center
|
|
const canvasBox = await page.locator('#graph-canvas').boundingBox()
|
|
if (!canvasBox) throw new Error('Canvas not found')
|
|
await page.mouse.click(
|
|
canvasBox.x + canvasBox.width / 2,
|
|
canvasBox.y + canvasBox.height / 2
|
|
)
|
|
await comfyPage.nextFrame()
|
|
|
|
return subgraphNode
|
|
}
|
|
|
|
/** Save the workflow, reopen it, and enter app mode. */
|
|
async function saveAndReopenInAppMode(
|
|
comfyPage: ComfyPage,
|
|
workflowName: string
|
|
) {
|
|
await comfyPage.menu.topbar.saveWorkflow(workflowName)
|
|
|
|
const { workflowsTab } = comfyPage.menu
|
|
await workflowsTab.open()
|
|
await workflowsTab.getPersistedItem(workflowName).dblclick()
|
|
await comfyPage.nextFrame()
|
|
|
|
await comfyPage.appMode.toggleAppMode()
|
|
}
|
|
|
|
test.describe('App mode widget rename', { tag: ['@ui', '@subgraph'] }, () => {
|
|
test.beforeEach(async ({ comfyPage }) => {
|
|
await comfyPage.page.evaluate(() => {
|
|
window.app!.api.serverFeatureFlags.value = {
|
|
...window.app!.api.serverFeatureFlags.value,
|
|
linear_toggle_enabled: true
|
|
}
|
|
})
|
|
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
|
|
await comfyPage.settings.setSetting(
|
|
'Comfy.AppBuilder.VueNodeSwitchDismissed',
|
|
true
|
|
)
|
|
})
|
|
|
|
test('Rename from builder input-select sidebar', async ({ comfyPage }) => {
|
|
const { appMode } = comfyPage
|
|
await setupSubgraphBuilder(comfyPage)
|
|
|
|
// Go back to inputs step where IoItems are shown
|
|
await appMode.goToInputs()
|
|
|
|
const menu = appMode.getBuilderInputItemMenu('seed')
|
|
await expect(menu).toBeVisible({ timeout: 5000 })
|
|
await appMode.renameWidget(menu, 'Builder Input Seed')
|
|
|
|
// Verify in app mode after save/reload
|
|
await appMode.exitBuilder()
|
|
const workflowName = `${new Date().getTime()} builder-input`
|
|
await saveAndReopenInAppMode(comfyPage, workflowName)
|
|
|
|
await expect(appMode.linearWidgets).toBeVisible({ timeout: 5000 })
|
|
await expect(
|
|
appMode.linearWidgets.getByText('Builder Input Seed')
|
|
).toBeVisible()
|
|
})
|
|
|
|
test('Rename from builder preview sidebar', async ({ comfyPage }) => {
|
|
const { appMode } = comfyPage
|
|
await setupSubgraphBuilder(comfyPage)
|
|
|
|
await appMode.goToPreview()
|
|
|
|
const menu = appMode.getBuilderPreviewWidgetMenu('seed — New Subgraph')
|
|
await expect(menu).toBeVisible({ timeout: 5000 })
|
|
await appMode.renameWidget(menu, 'Preview Seed')
|
|
|
|
// Verify in app mode after save/reload
|
|
await appMode.exitBuilder()
|
|
const workflowName = `${new Date().getTime()} builder-preview`
|
|
await saveAndReopenInAppMode(comfyPage, workflowName)
|
|
|
|
await expect(appMode.linearWidgets).toBeVisible({ timeout: 5000 })
|
|
await expect(appMode.linearWidgets.getByText('Preview Seed')).toBeVisible()
|
|
})
|
|
|
|
test('Rename from app mode', async ({ comfyPage }) => {
|
|
const { appMode } = comfyPage
|
|
await setupSubgraphBuilder(comfyPage)
|
|
|
|
// Enter app mode from builder
|
|
await appMode.exitBuilder()
|
|
await appMode.toggleAppMode()
|
|
|
|
await expect(appMode.linearWidgets).toBeVisible({ timeout: 5000 })
|
|
|
|
const menu = appMode.getAppModeWidgetMenu('seed')
|
|
await appMode.renameWidget(menu, 'App Mode Seed')
|
|
|
|
await expect(appMode.linearWidgets.getByText('App Mode Seed')).toBeVisible()
|
|
|
|
// Verify persistence after save/reload
|
|
await appMode.toggleAppMode()
|
|
const workflowName = `${new Date().getTime()} app-mode`
|
|
await saveAndReopenInAppMode(comfyPage, workflowName)
|
|
|
|
await expect(appMode.linearWidgets).toBeVisible({ timeout: 5000 })
|
|
await expect(appMode.linearWidgets.getByText('App Mode Seed')).toBeVisible()
|
|
})
|
|
})
|