mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-19 22:09:37 +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>
101 lines
3.5 KiB
TypeScript
101 lines
3.5 KiB
TypeScript
import { expect } from '@playwright/test'
|
|
|
|
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
|
|
import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
|
|
|
|
test.describe(
|
|
'Node context menu viewport overflow (#10824)',
|
|
{ tag: '@ui' },
|
|
() => {
|
|
test.beforeEach(async ({ comfyPage }) => {
|
|
// Keep the viewport well below the menu content height so overflow is guaranteed.
|
|
await comfyPage.page.setViewportSize({ width: 1280, height: 520 })
|
|
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled')
|
|
await comfyPage.settings.setSetting('Comfy.Canvas.SelectionToolbox', true)
|
|
await comfyPage.workflow.loadWorkflow('nodes/single_ksampler')
|
|
await comfyPage.nextFrame()
|
|
})
|
|
|
|
async function openMoreOptions(comfyPage: ComfyPage) {
|
|
const ksamplerNodes =
|
|
await comfyPage.nodeOps.getNodeRefsByTitle('KSampler')
|
|
if (ksamplerNodes.length === 0) {
|
|
throw new Error('No KSampler nodes found')
|
|
}
|
|
|
|
// Drag the KSampler toward the lower-left so the menu has limited space below it.
|
|
const nodePos = await ksamplerNodes[0].getPosition()
|
|
const viewportSize = comfyPage.page.viewportSize()!
|
|
const centerX = viewportSize.width / 3
|
|
const centerY = viewportSize.height * 0.75
|
|
await comfyPage.canvasOps.dragAndDrop(
|
|
{ x: nodePos.x, y: nodePos.y },
|
|
{ x: centerX, y: centerY }
|
|
)
|
|
await comfyPage.nextFrame()
|
|
|
|
await ksamplerNodes[0].click('title')
|
|
await comfyPage.nextFrame()
|
|
|
|
await expect(comfyPage.page.locator('.selection-toolbox')).toBeVisible()
|
|
|
|
const moreOptionsBtn = comfyPage.page.locator(
|
|
'[data-testid="more-options-button"]'
|
|
)
|
|
await expect(moreOptionsBtn).toBeVisible()
|
|
await moreOptionsBtn.click()
|
|
await comfyPage.nextFrame()
|
|
|
|
const menu = comfyPage.page.locator('.p-contextmenu')
|
|
await expect(menu).toBeVisible()
|
|
|
|
// Wait for constrainMenuHeight (runs via requestAnimationFrame in onMenuShow)
|
|
await comfyPage.nextFrame()
|
|
|
|
return menu
|
|
}
|
|
|
|
test('last menu item "Remove" is reachable via scroll', async ({
|
|
comfyPage
|
|
}) => {
|
|
const menu = await openMoreOptions(comfyPage)
|
|
const rootList = menu.locator(':scope > ul')
|
|
|
|
await expect
|
|
.poll(
|
|
() => rootList.evaluate((el) => el.scrollHeight > el.clientHeight),
|
|
{
|
|
message:
|
|
'Menu should overflow vertically so this test exercises the viewport clamp'
|
|
}
|
|
)
|
|
.toBe(true)
|
|
|
|
// "Remove" is the last item in the More Options menu.
|
|
// It must become reachable by scrolling the bounded menu list.
|
|
const removeItem = menu.getByText('Remove', { exact: true })
|
|
const didScroll = await rootList.evaluate((el) => {
|
|
const previousScrollTop = el.scrollTop
|
|
el.scrollTo({ top: el.scrollHeight })
|
|
return el.scrollTop > previousScrollTop
|
|
})
|
|
expect(didScroll).toBe(true)
|
|
await expect(removeItem).toBeVisible()
|
|
})
|
|
|
|
test('last menu item "Remove" is clickable and removes the node', async ({
|
|
comfyPage
|
|
}) => {
|
|
const menu = await openMoreOptions(comfyPage)
|
|
|
|
const removeItem = menu.getByText('Remove', { exact: true })
|
|
await removeItem.scrollIntoViewIfNeeded()
|
|
await removeItem.click()
|
|
await comfyPage.nextFrame()
|
|
|
|
// The node should be removed from the graph
|
|
await expect.poll(() => comfyPage.nodeOps.getGraphNodesCount()).toBe(0)
|
|
})
|
|
}
|
|
)
|