mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
add test for scrolling outputs
refactor execution helper to use assets helper for mock jobs
This commit is contained in:
@@ -1,18 +1,24 @@
|
||||
import type { Page } from '@playwright/test'
|
||||
|
||||
import type { RawJobListItem } from '../../../src/platform/remote/comfyui/jobs/jobTypes'
|
||||
import type { ComfyPage } from '../ComfyPage'
|
||||
import type { MockWebSocket } from '../ws'
|
||||
import { createMockJob } from './AssetsHelper'
|
||||
|
||||
/**
|
||||
* Helper for simulating prompt execution in e2e tests.
|
||||
*/
|
||||
export class ExecutionHelper {
|
||||
private jobCounter = 0
|
||||
private readonly completedJobs: RawJobListItem[] = []
|
||||
private readonly page: ComfyPage['page']
|
||||
private readonly assets: ComfyPage['assets']
|
||||
|
||||
constructor(
|
||||
private readonly page: Page,
|
||||
comfyPage: ComfyPage,
|
||||
private readonly mock: MockWebSocket
|
||||
) {}
|
||||
) {
|
||||
this.page = comfyPage.page
|
||||
this.assets = comfyPage.assets
|
||||
}
|
||||
|
||||
private get ws() {
|
||||
return this.mock.ws
|
||||
@@ -160,44 +166,30 @@ export class ExecutionHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock the history API to return the given job as completed,
|
||||
* then send execution_success and a status event to trigger
|
||||
* the history refresh that resolves in-progress items.
|
||||
* Complete a job by adding it to mock history, sending execution_success,
|
||||
* and triggering a history refresh via a status event.
|
||||
*
|
||||
* Requires an {@link AssetsHelper} to be passed in the constructor.
|
||||
*/
|
||||
async completeWithHistory(
|
||||
jobId: string,
|
||||
nodeId: string,
|
||||
filename: string
|
||||
): Promise<void> {
|
||||
const now = Date.now() / 1000
|
||||
const job: RawJobListItem = {
|
||||
id: jobId,
|
||||
status: 'completed',
|
||||
create_time: now,
|
||||
execution_start_time: now,
|
||||
execution_end_time: now + 1,
|
||||
priority: 0,
|
||||
outputs_count: 1,
|
||||
preview_output: {
|
||||
filename,
|
||||
subfolder: '',
|
||||
type: 'output',
|
||||
nodeId,
|
||||
mediaType: 'images'
|
||||
}
|
||||
}
|
||||
|
||||
await this.page.route(/\/api\/jobs\?status=completed/, async (route) => {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({
|
||||
jobs: [job],
|
||||
pagination: { offset: 0, limit: 200, total: 1, has_more: false }
|
||||
})
|
||||
this.completedJobs.push(
|
||||
createMockJob({
|
||||
id: jobId,
|
||||
preview_output: {
|
||||
filename,
|
||||
subfolder: '',
|
||||
type: 'output',
|
||||
nodeId,
|
||||
mediaType: 'images'
|
||||
}
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
await this.assets.mockOutputHistory(this.completedJobs)
|
||||
this.executionSuccess(jobId)
|
||||
// Trigger queue/history refresh
|
||||
this.status(0)
|
||||
|
||||
@@ -14,7 +14,7 @@ const KSAMPLER_NODE = '3'
|
||||
|
||||
/** Queue a prompt, intercept it, and send execution_start. */
|
||||
async function startExecution(comfyPage: ComfyPage, mock: MockWebSocket) {
|
||||
const exec = new ExecutionHelper(comfyPage.page, mock)
|
||||
const exec = new ExecutionHelper(comfyPage, mock)
|
||||
const jobId = await exec.run()
|
||||
// Allow storeJob() to complete before sending WS events
|
||||
await comfyPage.nextFrame()
|
||||
@@ -22,9 +22,13 @@ async function startExecution(comfyPage: ComfyPage, mock: MockWebSocket) {
|
||||
return { exec, jobId }
|
||||
}
|
||||
|
||||
function imageOutput(filename: string) {
|
||||
function imageOutput(...filenames: string[]) {
|
||||
return {
|
||||
images: [{ filename, subfolder: '', type: 'output' }]
|
||||
images: filenames.map((filename) => ({
|
||||
filename,
|
||||
subfolder: '',
|
||||
type: 'output'
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,6 +281,49 @@ test.describe('Output History', { tag: '@ui' }, () => {
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
test('In-progress items are outside the scrollable area', async ({
|
||||
comfyPage,
|
||||
getWebSocket
|
||||
}) => {
|
||||
const mock = await getWebSocket()
|
||||
|
||||
// Complete one execution with 100 image outputs
|
||||
const { exec, jobId } = await startExecution(comfyPage, mock)
|
||||
exec.executed(
|
||||
jobId,
|
||||
SAVE_IMAGE_NODE,
|
||||
imageOutput(
|
||||
...Array.from(
|
||||
{ length: 100 },
|
||||
(_, i) => `image_${String(i).padStart(3, '0')}.png`
|
||||
)
|
||||
)
|
||||
)
|
||||
await exec.completeWithHistory(jobId, SAVE_IMAGE_NODE, 'image_000.png')
|
||||
|
||||
await expect(comfyPage.appMode.outputHistory.historyItems).toHaveCount(100)
|
||||
|
||||
// First history item is visible before scrolling
|
||||
const firstItem = comfyPage.appMode.outputHistory.historyItems.first()
|
||||
await expect(firstItem).toBeInViewport()
|
||||
|
||||
// Scroll the history feed all the way to the right
|
||||
await comfyPage.appMode.outputHistory.outputs.evaluate((el) => {
|
||||
el.scrollLeft = el.scrollWidth
|
||||
})
|
||||
|
||||
// First history item is now off-screen
|
||||
await expect(firstItem).not.toBeInViewport()
|
||||
|
||||
// Start a new execution to get an in-progress item
|
||||
await startExecution(comfyPage, mock)
|
||||
|
||||
// In-progress item is visible despite scrolling
|
||||
await expect(
|
||||
comfyPage.appMode.outputHistory.inProgressItems.first()
|
||||
).toBeInViewport()
|
||||
})
|
||||
|
||||
test('Execution error cleans up in-progress items', async ({
|
||||
comfyPage,
|
||||
getWebSocket
|
||||
|
||||
Reference in New Issue
Block a user