Skip to content

Release 1.1.1#2

Merged
Zhen-Bo merged 9 commits into
masterfrom
release/1.1.1
Mar 10, 2026
Merged

Release 1.1.1#2
Zhen-Bo merged 9 commits into
masterfrom
release/1.1.1

Conversation

@Zhen-Bo

@Zhen-Bo Zhen-Bo commented Mar 10, 2026

Copy link
Copy Markdown
Owner

🎯 Overview

Bug-fix release focusing on queue rendering reliability — resolving card flickering, sort-order regressions, delayed UI updates, and a media-type collision that appeared after 1.1.0.


📋 Summary

Category Details
🐛 Bug Fixes 7 rendering / state-management / media-type fixes
Responsiveness Running card + badge now appear instantly via WS execution_start, no longer waiting for API poll
🧪 Testing 3 new + 3 updated unit tests, 5 Playwright E2E tests
🔧 Tooling Playwright E2E infrastructure

🐛 Bug Fixes

Card Reconciliation

Commit Fix
bcb64f1 Retain direct reference after card.replaceWith — store the makeCard() return value directly instead of re-querying by DOM index, preventing stale-reference mismatches
bb2e35d Coerce running task promptId to string — prevent unnecessary card rebuild caused by type mismatch (number vs string) during reconciliation
0d3ff9f Use prompt UUID as running task ID — use tuple[1] (UUID) instead of tuple[0] (numeric index) from queue_running, so the running card correctly reconciles across the pending → running transition

Sort Order & Timing

Commit Fix
419a55d Restore pending-before-running sort order — display pending tasks above running tasks in the grid, matching expected queue ordering
c13c933 Show badge and card immediately on execution_start — move the task from pending → running using the WebSocket event rather than waiting for the next /queue API poll; fixes fast/cached workflows completing before the UI updates
7d0576f Render existing state when panel opens — call render() inside buildSidebar() so cached state displays instantly without waiting for an API round-trip

Media Type

Commit Fix
54d89ad Replace .ogg with .oga in AUDIO_EXTS — resolve the .ogg collision between VIDEO_EXTS and AUDIO_EXTS by using the audio-specific .oga extension

🧪 Testing

Unit Tests — Vitest

3 new test cases + 3 existing tests updated to match new normalizeQueue tuple format:

  • normalizeQueue — running/pending promptId consistency across transition, single-element tuple fallback
  • Render reconciliation — pending-before-running DOM order regression test

E2E Tests — Playwright (7f94d11)

5 end-to-end tests running against a live ComfyUI instance, each with a strict assertion strategy that isolates the exact behavior being verified:

Test What it proves How
Cached state on reopen buildSidebar() calls render() before refresh() Block /api/queue + /api/history with 3 s delay → assert cards appear within 500 ms (must come from in-memory cache)
Pending before running Sort order [...pending, ...running, ...history] Queue 2 prompts → wait for both states visible → assert every pending DOM index < every running DOM index
No duplicate cards card.replaceWith fix doesn't create ghost nodes Poll DOM every 100 ms throughout execution → assert no duplicate data-id values at any point
Instant badge via WS onExecutionStart works independently of API poll Block /api/queue with 30 s delay → assert running card + badge still appear (only possible via WS execution_startrender())
No console warnings No type mismatches or malformed data warnings Collect all [QueueSidebar] console.warn during a full queue→complete cycle → assert empty
npm run test         # unit tests (vitest)
npm run test:e2e     # e2e tests (playwright, requires ComfyUI at 127.0.0.1:8188)

✅ Verification

  • 64 unit tests passing (vitest)
  • 5 E2E tests passing (playwright) — including route-blocking proof that WS path works
  • Sidebar opens with cached state — no loading flash
  • Pending → running transition: no flicker, no duplicate cards
  • Fast/cached workflows: badge + card appear instantly via WS

Zhen-Bo added 9 commits March 9, 2026 19:35
allTasks was assembled as [...running, ...pending, ...history],
causing the sidebar to display the running item before queued items.
Correct order is pending → running → history.

Added a regression test to prevent future recurrence.
queue_running tuples are [number, prompt_id, ...]. Using tuple[0]
(a number) as promptId caused a type mismatch with dataset.id (always
a string), so existing.get() never matched the running card and
makeCard() was called on every render — resetting the status tag
spinner on each b_preview step during K-Sampler execution.

Updated tests to reflect the correct [number, uuid, ...] tuple shape.
buildSidebar only called refresh() (async), leaving the panel blank
until the fetch completed. Events fired while the panel was closed
(status, b_preview) kept state up-to-date but couldn't render because
gridEl was null. On re-open, calling render() before refresh() shows
the current state instantly, then refresh() updates with fresh data.
normalizeQueue was returning tuple[0] as a number for queue_running
entries. Since dataset.id is always a string, the Map lookup in render()
never matched, causing every render to rebuild the card and reset the
spinner animation.

Fix: wrap tuple[0] with String() to ensure type consistency.
Also reverts the length<2 guard introduced in fix/spinner-reset back to
length<1 — the stricter guard was filtering out single-element tuples
that ComfyUI may send before full execution context is available,
causing running tasks to not appear at all before the K-sampler step.
Two root causes identified via Playwright instrumentation:

1. normalizeQueue used String(tuple[0]) (integer) for running tasks but
   tuple[1] (UUID) for pending tasks. The same task had different promptIds
   in each state, so render()'s keyed reconciliation never matched the
   existing pending card — rebuilding it on every render and resetting the
   spinner animation.

   Fix: prefer tuple[1] (UUID) for running tasks; fall back to
   String(tuple[0]) only for single-element tuples ComfyUI may send before
   full execution context is available.

2. onExecutionStart called render() without updating state. Because the
   /queue API fetch had not yet returned, state.running was empty and
   updateBadge() cleared the badge to 0. For fast or fully-cached workflows
   the task could complete before any fetch returned, so badge and card
   never appeared.

   Fix: read detail.prompt_id from the WS event and immediately move the
   task from state.pending to state.running (or create a running entry if
   not yet tracked). Badge and card now appear within ~10 ms of pressing
   Queue — no API round-trip required.

Adds regression tests for pending→running ID consistency and single-element
tuple fallback.
- 5 E2E tests: cached state, pending order, no duplicate cards,
  instant badge via WS execution_start, no console warnings
- Shared helpers with client_id-aware queuePrompt
- Playwright config (single worker, headless, failure traces)
- Add test:e2e script to package.json
@Zhen-Bo Zhen-Bo merged commit 08963cc into master Mar 10, 2026
1 check passed
@Zhen-Bo Zhen-Bo deleted the release/1.1.1 branch March 10, 2026 12:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant