mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
## Summary Alright, alright, alright. These e2e tests have been runnin' around like they're late for somethin', settin' tight little timeouts like the world's gonna end in 250 milliseconds. Man, you gotta *breathe*. Let the framework do its thing. Go slow to go fast, that's what I always say. ## Changes - **What**: Removed ~120 redundant timeout overrides from auto-retrying Playwright assertions (`toBeVisible`, `toBeHidden`, `toHaveCount`, `toBeEnabled`, `toHaveAttribute`, `toContainText`, `expect.poll`) where 5000ms is already the default. Also removed sub-5s timeouts (1s, 2s, 3s) that were just *begging* for flaky failures — like wearin' a belt and suspenders and also holdin' your pants up with both hands. Raised the absurdly short timeouts in `customMatchers.ts` (250ms `toPass` → 5000ms, 256ms poll → default). Kept `timeout: 5000` on `.toPass()` calls (defaults to 0), `.waitFor()`, `waitForRequest`, `waitForFunction`, intentionally-short timeouts inside retry loops, and conditional `.isVisible()/.catch()` checks — those fellas actually need the help. ## Review Focus Every remaining timeout in the diff is there for a *reason*. The ones on `.toPass()` stay because that API defaults to zero — it won't retry at all without one. The ones on `.waitFor()` and `waitForRequest` stay because those are locator actions, not auto-retrying assertions. The intentionally-short ones inside `toPass` retry loops (`interaction.spec.ts`) and the negative assertions (`actionbar.spec.ts` confirming no response arrives) — those are *supposed* to be tight. The short timeouts on regular assertions were actively *encouragin'* flaky failures. That's like settin' your alarm for 4 AM and then gettin' mad you're tired. Just... don't do that, man. Let things take the time they need. 38 files, net -115 lines. Less code, more chill. That's livin'. --------- Co-authored-by: Amp <amp@ampcode.com>
154 lines
4.6 KiB
TypeScript
154 lines
4.6 KiB
TypeScript
import { expect } from '@playwright/test'
|
|
|
|
import { assetPath } from '@e2e/fixtures/utils/paths'
|
|
import { load3dTest as test } from '@e2e/fixtures/helpers/Load3DFixtures'
|
|
|
|
test.describe('Load3D', () => {
|
|
test(
|
|
'Renders canvas with upload buttons and controls menu',
|
|
{ tag: ['@smoke', '@screenshot'] },
|
|
async ({ load3d }) => {
|
|
await expect(load3d.node).toBeVisible()
|
|
|
|
await expect(load3d.canvas).toBeVisible()
|
|
|
|
await expect
|
|
.poll(async () => {
|
|
const b = await load3d.canvas.boundingBox()
|
|
return b?.width ?? 0
|
|
})
|
|
.toBeGreaterThan(0)
|
|
await expect
|
|
.poll(async () => {
|
|
const b = await load3d.canvas.boundingBox()
|
|
return b?.height ?? 0
|
|
})
|
|
.toBeGreaterThan(0)
|
|
|
|
await expect(load3d.getUploadButton('upload 3d model')).toBeVisible()
|
|
await expect(
|
|
load3d.getUploadButton('upload extra resources')
|
|
).toBeVisible()
|
|
await expect(load3d.getUploadButton('clear')).toBeVisible()
|
|
|
|
await expect(load3d.menuButton).toBeVisible()
|
|
|
|
await expect(load3d.node).toHaveScreenshot('load3d-empty-node.png', {
|
|
maxDiffPixelRatio: 0.05
|
|
})
|
|
}
|
|
)
|
|
|
|
test(
|
|
'Controls menu opens and shows all categories',
|
|
{ tag: ['@smoke', '@screenshot'] },
|
|
async ({ load3d }) => {
|
|
await load3d.openMenu()
|
|
|
|
await expect(load3d.getMenuCategory('Scene')).toBeVisible()
|
|
await expect(load3d.getMenuCategory('Model')).toBeVisible()
|
|
await expect(load3d.getMenuCategory('Camera')).toBeVisible()
|
|
await expect(load3d.getMenuCategory('Light')).toBeVisible()
|
|
await expect(load3d.getMenuCategory('Export')).toBeVisible()
|
|
|
|
await expect(load3d.node).toHaveScreenshot(
|
|
'load3d-controls-menu-open.png',
|
|
{ maxDiffPixelRatio: 0.05 }
|
|
)
|
|
}
|
|
)
|
|
|
|
test(
|
|
'Changing background color updates the scene',
|
|
{ tag: ['@smoke', '@screenshot'] },
|
|
async ({ comfyPage, load3d }) => {
|
|
await load3d.setBackgroundColor('#cc3333')
|
|
await comfyPage.nextFrame()
|
|
|
|
await expect
|
|
.poll(() =>
|
|
comfyPage.page.evaluate(() => {
|
|
const n = window.app!.graph.getNodeById(1)
|
|
const config = n?.properties?.['Scene Config'] as
|
|
| Record<string, string>
|
|
| undefined
|
|
return config?.backgroundColor
|
|
})
|
|
)
|
|
.toBe('#cc3333')
|
|
|
|
await expect(load3d.node).toHaveScreenshot('load3d-red-background.png', {
|
|
maxDiffPixelRatio: 0.05
|
|
})
|
|
}
|
|
)
|
|
|
|
test(
|
|
'Recording controls are visible for Load3D',
|
|
{ tag: '@smoke' },
|
|
async ({ load3d }) => {
|
|
await expect(load3d.recordingButton).toBeVisible()
|
|
}
|
|
)
|
|
|
|
test(
|
|
'Uploads a 3D model via button and renders it',
|
|
{ tag: ['@screenshot'] },
|
|
async ({ comfyPage, load3d }) => {
|
|
const uploadResponsePromise = comfyPage.page.waitForResponse(
|
|
(resp) => resp.url().includes('/upload/') && resp.status() === 200,
|
|
{ timeout: 15000 }
|
|
)
|
|
|
|
const fileChooserPromise = comfyPage.page.waitForEvent('filechooser')
|
|
await load3d.getUploadButton('upload 3d model').click()
|
|
const fileChooser = await fileChooserPromise
|
|
await fileChooser.setFiles(assetPath('cube.obj'))
|
|
|
|
await uploadResponsePromise
|
|
|
|
const node = await comfyPage.nodeOps.getNodeRefById(1)
|
|
const modelFileWidget = await node.getWidget(0)
|
|
await expect.poll(() => modelFileWidget.getValue()).toContain('cube.obj')
|
|
|
|
await load3d.waitForModelLoaded()
|
|
await comfyPage.nextFrame()
|
|
|
|
await expect(load3d.node).toHaveScreenshot(
|
|
'load3d-uploaded-cube-obj.png',
|
|
{ maxDiffPixelRatio: 0.1 }
|
|
)
|
|
}
|
|
)
|
|
|
|
test(
|
|
'Drag-and-drops a 3D model onto the canvas',
|
|
{ tag: ['@screenshot'] },
|
|
async ({ comfyPage, load3d }) => {
|
|
const canvasBox = await load3d.canvas.boundingBox()
|
|
expect(canvasBox, 'Canvas bounding box should exist').not.toBeNull()
|
|
const dropPosition = {
|
|
x: canvasBox!.x + canvasBox!.width / 2,
|
|
y: canvasBox!.y + canvasBox!.height / 2
|
|
}
|
|
|
|
await comfyPage.dragDrop.dragAndDropFile('cube.obj', {
|
|
dropPosition,
|
|
waitForUpload: true
|
|
})
|
|
|
|
const node = await comfyPage.nodeOps.getNodeRefById(1)
|
|
const modelFileWidget = await node.getWidget(0)
|
|
await expect.poll(() => modelFileWidget.getValue()).toContain('cube.obj')
|
|
|
|
await load3d.waitForModelLoaded()
|
|
await comfyPage.nextFrame()
|
|
|
|
await expect(load3d.node).toHaveScreenshot(
|
|
'load3d-dropped-cube-obj.png',
|
|
{ maxDiffPixelRatio: 0.1 }
|
|
)
|
|
}
|
|
)
|
|
})
|