Files
ComfyUI_frontend/browser_tests/tests/load3d/preview3dExecution.spec.ts
2026-04-11 05:29:15 +00:00

159 lines
4.8 KiB
TypeScript

import { expect } from '@playwright/test'
import {
alignPreview3dWorkflowUiSettings,
nudgePreview3dCameraIntoProperties,
preview3dPipelineTest as test,
Preview3DPipelineContext,
seedLoad3dWithCubeObj,
setNonDefaultLoad3dCameraState
} from '@e2e/fixtures/helpers/Preview3DPipelineFixture'
import {
PREVIEW3D_CAMERA_AXIS_RESTORE_EPS,
PREVIEW3D_CAMERA_ZOOM_RESTORE_EPS,
preview3dRestoreCameraStatesMatch
} from '@e2e/fixtures/utils/preview3dCameraState'
test.describe('Preview3D execution flow', { tag: ['@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 pipeline.comfyPage.workflow.waitForWorkflowIdle(90_000, {
message:
'QueuePrompt did not finish: backend needs Load3D and Preview3D nodes and a working execution environment'
})
await expect
.poll(() =>
pipeline.getModelFileWidgetValue(Preview3DPipelineContext.previewNodeId)
)
.not.toBe('')
const modelPath = await pipeline.getModelFileWidgetValue(
Preview3DPipelineContext.previewNodeId
)
expect(modelPath.length, 'Preview3D model path populated').toBeGreaterThan(
4
)
await expect
.poll(() =>
pipeline.getLastTimeModelFile(Preview3DPipelineContext.previewNodeId)
)
.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 setNonDefaultLoad3dCameraState(pipeline)
await pipeline.comfyPage.command.executeCommand('Comfy.QueuePrompt')
await pipeline.comfyPage.workflow.waitForWorkflowIdle(90_000, {
message:
'QueuePrompt did not finish: backend needs Load3D and Preview3D nodes and a working execution environment'
})
await expect
.poll(() =>
pipeline.getModelFileWidgetValue(Preview3DPipelineContext.previewNodeId)
)
.not.toBe('')
await pipeline.preview3d.waitForModelLoaded()
await nudgePreview3dCameraIntoProperties(pipeline)
const savedPath = await pipeline.getModelFileWidgetValue(
Preview3DPipelineContext.previewNodeId
)
await expect
.poll(
() =>
pipeline.getCameraStateFromProperties(
Preview3DPipelineContext.previewNodeId
),
{
message:
'Preview3D Camera Config.state should exist after orbit (cameraChanged)'
}
)
.not.toBeNull()
const savedCamera = await pipeline.getCameraStateFromProperties(
Preview3DPipelineContext.previewNodeId
)
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: 'domcontentloaded' })
await pipeline.comfyPage.waitForReady({ timeout: 30_000 })
await alignPreview3dWorkflowUiSettings(pipeline)
const tab = pipeline.comfyPage.menu.workflowsTab
await tab.open()
await tab.getPersistedItem(workflowName).click()
await pipeline.comfyPage.workflow.waitForWorkflowIdle(30_000, {
message:
'Workflow did not settle after opening saved workflow from sidebar (Preview3D restore test)'
})
await pipeline.comfyPage.vueNodes.waitForNodes()
await expect
.poll(() =>
pipeline.getModelFileWidgetValue(Preview3DPipelineContext.previewNodeId)
)
.toBe(savedPath)
await expect
.poll(() =>
pipeline.getLastTimeModelFile(Preview3DPipelineContext.previewNodeId)
)
.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 () =>
preview3dRestoreCameraStatesMatch(
await pipeline.getCameraStateFromProperties(
Preview3DPipelineContext.previewNodeId
),
savedCamera
),
{
timeout: 15_000,
message: `Preview3D camera after reload should match saved state (axis max delta ≤ ${PREVIEW3D_CAMERA_AXIS_RESTORE_EPS}, zoom delta ≤ ${PREVIEW3D_CAMERA_ZOOM_RESTORE_EPS}; see preview3dCameraState.test.ts)`
}
)
.toBe(true)
})
})