mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
172 lines
4.6 KiB
TypeScript
172 lines
4.6 KiB
TypeScript
import { expect } from '@playwright/test'
|
|
|
|
import {
|
|
cameraStatesClose,
|
|
preview3dPipelineTest as test,
|
|
Preview3DPipelineContext,
|
|
waitForAppBootstrapped
|
|
} from '@e2e/fixtures/helpers/Preview3DPipelineFixture'
|
|
import { assetPath } from '@e2e/fixtures/utils/paths'
|
|
|
|
async function seedLoad3dWithCubeObj(
|
|
pipeline: Preview3DPipelineContext
|
|
): Promise<void> {
|
|
const { comfyPage, load3d } = pipeline
|
|
const fileChooserPromise = comfyPage.page.waitForEvent('filechooser')
|
|
await load3d.getUploadButton('upload 3d model').click()
|
|
const fileChooser = await fileChooserPromise
|
|
await fileChooser.setFiles(assetPath('cube.obj'))
|
|
|
|
await expect
|
|
.poll(
|
|
() =>
|
|
pipeline.getModelFileWidgetValue(Preview3DPipelineContext.loadNodeId),
|
|
{ timeout: 15_000 }
|
|
)
|
|
.toContain('cube.obj')
|
|
|
|
await load3d.waitForModelLoaded()
|
|
await comfyPage.nextFrame()
|
|
}
|
|
|
|
async function alignPreview3dWorkflowUiSettings(
|
|
pipeline: Preview3DPipelineContext
|
|
): Promise<void> {
|
|
await pipeline.comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
|
|
await pipeline.comfyPage.settings.setSetting(
|
|
'Comfy.Workflow.WorkflowTabsPosition',
|
|
'Sidebar'
|
|
)
|
|
}
|
|
|
|
test.describe('Preview3D execution flow', { tag: ['@node', '@slow'] }, () => {
|
|
test('Preview3D loads model from execution output', async ({
|
|
preview3dPipeline: pipeline
|
|
}) => {
|
|
test.setTimeout(120_000)
|
|
|
|
await seedLoad3dWithCubeObj(pipeline)
|
|
|
|
await pipeline.comfyPage.command.executeCommand('Comfy.QueuePrompt')
|
|
|
|
await expect
|
|
.poll(
|
|
() =>
|
|
pipeline.getModelFileWidgetValue(
|
|
Preview3DPipelineContext.previewNodeId
|
|
),
|
|
{ timeout: 90_000 }
|
|
)
|
|
.not.toBe('')
|
|
|
|
const modelPath = await pipeline.getModelFileWidgetValue(
|
|
Preview3DPipelineContext.previewNodeId
|
|
)
|
|
await expect(
|
|
modelPath.length,
|
|
'Preview3D model path populated'
|
|
).toBeGreaterThan(4)
|
|
|
|
await expect
|
|
.poll(
|
|
() =>
|
|
pipeline.getLastTimeModelFile(Preview3DPipelineContext.previewNodeId),
|
|
{ timeout: 5000 }
|
|
)
|
|
.toBe(modelPath)
|
|
|
|
await pipeline.preview3d.waitForModelLoaded()
|
|
|
|
await expect
|
|
.poll(async () => {
|
|
const b = await pipeline.preview3d.canvas.boundingBox()
|
|
return (b?.width ?? 0) > 0 && (b?.height ?? 0) > 0
|
|
})
|
|
.toBe(true)
|
|
})
|
|
|
|
test('Preview3D restores last model and camera after save and full reload', async ({
|
|
preview3dPipeline: pipeline
|
|
}) => {
|
|
test.setTimeout(180_000)
|
|
|
|
await seedLoad3dWithCubeObj(pipeline)
|
|
|
|
await pipeline.comfyPage.command.executeCommand('Comfy.QueuePrompt')
|
|
|
|
await expect
|
|
.poll(
|
|
() =>
|
|
pipeline.getModelFileWidgetValue(
|
|
Preview3DPipelineContext.previewNodeId
|
|
),
|
|
{ timeout: 90_000 }
|
|
)
|
|
.not.toBe('')
|
|
|
|
await pipeline.preview3d.waitForModelLoaded()
|
|
|
|
const savedPath = await pipeline.getModelFileWidgetValue(
|
|
Preview3DPipelineContext.previewNodeId
|
|
)
|
|
const savedCamera = await pipeline.getCameraStateFromProperties(
|
|
Preview3DPipelineContext.previewNodeId
|
|
)
|
|
expect(savedCamera, 'Camera state present after execution').not.toBeNull()
|
|
|
|
const workflowName = `p3d-restore-${Date.now().toString(36)}`
|
|
await pipeline.comfyPage.menu.workflowsTab.open()
|
|
await pipeline.comfyPage.menu.topbar.saveWorkflow(workflowName)
|
|
|
|
await pipeline.comfyPage.page.reload({ waitUntil: 'networkidle' })
|
|
await waitForAppBootstrapped(pipeline.comfyPage)
|
|
|
|
await alignPreview3dWorkflowUiSettings(pipeline)
|
|
|
|
const tab = pipeline.comfyPage.menu.workflowsTab
|
|
await tab.open()
|
|
await tab.getPersistedItem(workflowName).click()
|
|
await pipeline.comfyPage.workflow.waitForWorkflowIdle(15_000)
|
|
await pipeline.comfyPage.vueNodes.waitForNodes()
|
|
|
|
await expect
|
|
.poll(
|
|
() =>
|
|
pipeline.getModelFileWidgetValue(
|
|
Preview3DPipelineContext.previewNodeId
|
|
),
|
|
{ timeout: 30_000 }
|
|
)
|
|
.toBe(savedPath)
|
|
|
|
await expect
|
|
.poll(
|
|
() =>
|
|
pipeline.getLastTimeModelFile(Preview3DPipelineContext.previewNodeId),
|
|
{ timeout: 5000 }
|
|
)
|
|
.toBe(savedPath)
|
|
|
|
await pipeline.preview3d.waitForModelLoaded()
|
|
|
|
await expect
|
|
.poll(async () => {
|
|
const b = await pipeline.preview3d.canvas.boundingBox()
|
|
return (b?.width ?? 0) > 0 && (b?.height ?? 0) > 0
|
|
})
|
|
.toBe(true)
|
|
|
|
await expect
|
|
.poll(async () =>
|
|
cameraStatesClose(
|
|
await pipeline.getCameraStateFromProperties(
|
|
Preview3DPipelineContext.previewNodeId
|
|
),
|
|
savedCamera,
|
|
2e-2
|
|
)
|
|
)
|
|
.toBe(true)
|
|
})
|
|
})
|