add test for scrolling outputs

refactor execution helper to use assets helper for mock jobs
This commit is contained in:
pythongosssss
2026-04-01 08:54:13 -07:00
parent e1455ef3bb
commit 63b611a844
2 changed files with 76 additions and 37 deletions

View File

@@ -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)

View File

@@ -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