*PR Created by the Glary-Bot Agent*
---
## Summary
- Replace all `as unknown as Type` assertions in 59 unit test files with
type-safe `@total-typescript/shoehorn` functions
- Use `fromPartial<Type>()` for partial mock objects where deep-partial
type-checks (21 files)
- Use `fromAny<Type>()` for fundamentally incompatible types: null,
undefined, primitives, variables, class expressions, and mocks with
test-specific extra properties that `PartialDeepObject` rejects
(remaining files)
- All explicit type parameters preserved so TypeScript return types are
correct
- Browser test `.spec.ts` files excluded (shoehorn unavailable in
`page.evaluate` browser context)
## Verification
- `pnpm typecheck` ✅
- `pnpm lint` ✅
- `pnpm format` ✅
- Pre-commit hooks passed (format + oxlint + eslint + typecheck)
- Migrated test files verified passing (ran representative subset)
- No test behavior changes — only type assertion syntax changed
- No UI changes — screenshots not applicable
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10761-test-migrate-as-unknown-as-to-total-typescript-shoehorn-3336d73d365081f6b8adc44db5dcc380)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com>
Co-authored-by: Amp <amp@ampcode.com>
## Summary
Replace `app.rootGraph.getNodeById()` with `resolveNode()` so node
lookups search subgraphs, fixing broken image copy/paste and display for
nodes inside subgraphs.
## Changes
- **What**: Updated 7 call sites across 5 files to use `resolveNode()`
from `litegraphUtil.ts` instead of `app.rootGraph.getNodeById()`. The
`resolveNode` function already existed and searches both the root graph
and all subgraphs. Added a unit test verifying subgraph node resolution
in `nodeOutputStore`.
## Review Focus
The fix is mechanical — each call site simply swaps
`app.rootGraph?.getNodeById(id)` for `resolveNode(id)`. The
`resolveNode` utility iterates `graph.subgraphs` if the node is not
found in the root graph.
Fixes#9993
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10009-fix-resolve-nodes-in-subgraphs-for-image-copy-paste-and-display-3256d73d3650814f9467c53999f5d755)
by [Unito](https://www.unito.io)
## Summary
Fix input asset previews (images/videos) disappearing from
LoadImage/LoadVideo nodes after execution and a browser tab switch.
## Changes
- **What**: Guard `setOutputsByLocatorId` in `imagePreviewStore` to
preserve existing input-type preview images (`type: 'input'`) when the
incoming execution output has no images. Execution outputs with actual
images still overwrite as expected.
## Review Focus
- The guard only applies when existing output is an input preview (`type
=== 'input'` for all images) AND incoming output has no images — this is
the exact scenario where execution clobbers upload widget previews.
- Root cause: execution results from the backend overwrite the upload
widget's synthetic preview for LoadImage/LoadVideo nodes (which produce
no output images). Combined with the deferred resize-observer
re-observation from PR #8805, returning to a hidden tab reads the
now-empty store entry.
## Summary
Rename `imagePreviewStore.ts` → `nodeOutputStore.ts` to match the store
it houses (`useNodeOutputStore`, Pinia ID `nodeOutput`).
## Changes
- **What**: Rename file + test file, update all 21 import paths, mock
paths, and describe labels
- **Breaking**: None — exported symbol (`useNodeOutputStore`) and Pinia
store ID (`nodeOutput`) are unchanged
## Custom Node Ecosystem Audit
Searched the ComfyUI custom node ecosystem for `imagePreviewStore` and
`useNodeOutputStore`:
- **Not part of the public API** — neither filename nor export appear in
`comfyui_frontend_package` or `vite.types.config.mts`
- **1 external repo found:** `wallen0322/ComfyUI-AE-Animation` —
contains a full fork of the frontend source tree; it copies the file
internally and does not import from the published package. **No
breakage.**
- **No custom nodes import this store via the extension API.** This is a
safe internal-only rename.
## Review Focus
Pure mechanical rename — no logic changes. Verify no stale
`imagePreviewStore` references remain.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-9416-refactor-rename-imagePreviewStore-to-nodeOutputStore-31a6d73d3650816086c5e62959861ddb)
by [Unito](https://www.unito.io)
Co-authored-by: Alexander Brown <drjkl@comfy.org>