Skip to content

fix: inner groups being moved double when moving outer group (in vue mode)#7447

Merged
christian-byrne merged 5 commits intomainfrom
fix-nested-groups-vue
Dec 15, 2025
Merged

fix: inner groups being moved double when moving outer group (in vue mode)#7447
christian-byrne merged 5 commits intomainfrom
fix-nested-groups-vue

Conversation

@christian-byrne
Copy link
Contributor

@christian-byrne christian-byrne commented Dec 13, 2025

Summary

Fixes issue when dragging a group that had inner groups when in vue mode.

When dragging the outer group in Vue mode:

  1. getAllNestedItems(selected) returns ALL items: outer group + inner groups + nodes
  2. moveChildNodesInGroupVueMode loops through all items
  3. For outer group G1: calls G1.move(delta, true) then moveGroupChildren(G1, ...)
  4. moveGroupChildren calls G2.move(delta) (no skipChildren) - this moves G2 AND G2's children!
  5. Then the loop reaches G2: calls G2.move(delta, true) - moves G2 again
  6. Plus moveGroupChildren(G2, ...) processes G2's children again

This PR fixes it by adding skipChildren=true to the move call.

┆Issue is synchronized with this Notion page by Unito

@christian-byrne christian-byrne requested a review from a team as a code owner December 13, 2025 11:36
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Dec 13, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 13, 2025

📝 Walkthrough

Walkthrough

This pull request adds support for properly moving nested groups together during drag operations. It includes a test asset with nested groups, new test case validating the behavior, fixture helper methods for group interaction, and a modification to the graph canvas movement logic to defer group children processing to the main Vue-mode loop.

Changes

Cohort / File(s) Summary
Test Infrastructure
browser_tests/fixtures/ComfyPage.ts
Added getGroupPosition(title: string) and dragGroup(options) helper methods to retrieve group positions and perform drag operations on groups by name
Test Assets and Specifications
browser_tests/assets/groups/nested-groups-1-inner-node.json, browser_tests/tests/vueNodes/groups/groups.spec.ts
Added test asset file with nested group layout containing VAEDecode node; added test case validating that nested groups maintain their relative position when outer group is dragged
Core Logic
src/lib/litegraph/src/LGraphCanvas.ts
Modified moveGroupChildren to skip LGraphGroup instances during non-node child processing, deferring group movement to the main Vue-mode loop; non-group children are moved with skip-nested flag to prevent double-movement

Possibly related PRs

  • #7306 — Implements moving selected LGraphGroup items during drag operations, complementing this PR's changes to nested group movement handling.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-nested-groups-vue

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Dec 13, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 12/14/2025, 04:17:18 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Dec 13, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 12/14/2025, 04:25:47 AM UTC

📈 Summary

  • Total Tests: 507
  • Passed: 497 ✅
  • Failed: 0
  • Flaky: 1 ⚠️
  • Skipped: 9 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 485 / ❌ 0 / ⚠️ 1 / ⏭️ 9
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 9 / ❌ 0 / ⚠️ 0 / ⏭️ 0

🎉 Click on the links above to view detailed test results for each browser configuration.

@github-actions
Copy link

github-actions bot commented Dec 13, 2025

Bundle Size Report

Summary

  • Raw size: 17.1 MB baseline 17.1 MB — 🔴 +43 B
  • Gzip: 3.39 MB baseline 3.39 MB — 🔴 +10 B
  • Brotli: 2.6 MB baseline 2.6 MB — 🟢 -136 B
  • Bundles: 98 current • 98 baseline • 40 added / 40 removed

Category Glance
App Entry Points 🔴 +43 B (3.25 MB) · Vendor & Third-Party ⚪ 0 B (8.56 MB) · Other ⚪ 0 B (3.82 MB) · Graph Workspace ⚪ 0 B (986 kB) · Panels & Settings ⚪ 0 B (298 kB) · UI Components ⚪ 0 B (184 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.25 MB (baseline 3.25 MB) • 🔴 +43 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-BoyzF4fZ.js (new) 3.02 MB 🔴 +3.02 MB 🔴 +627 kB 🔴 +477 kB
assets/index-CVb8EnlH.js (removed) 3.02 MB 🟢 -3.02 MB 🟢 -627 kB 🟢 -477 kB
assets/index-Bs6vyVC0.js (removed) 227 kB 🟢 -227 kB 🟢 -48.6 kB 🟢 -39.9 kB
assets/index-Qk0e3G5d.js (new) 227 kB 🔴 +227 kB 🔴 +48.6 kB 🔴 +39.8 kB
assets/index-DB0d12c0.js (removed) 345 B 🟢 -345 B 🟢 -245 B 🟢 -234 B
assets/index-htiUnurK.js (new) 345 B 🔴 +345 B 🔴 +244 B 🔴 +202 B

Status: 3 added / 3 removed

Graph Workspace — 986 kB (baseline 986 kB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-BxPkzzKF.js (removed) 986 kB 🟢 -986 kB 🟢 -191 kB 🟢 -146 kB
assets/GraphView-Df65dZZ3.js (new) 986 kB 🔴 +986 kB 🔴 +191 kB 🔴 +146 kB

Status: 1 added / 1 removed

Views & Navigation — 6.54 kB (baseline 6.54 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-CnPYqUjy.js (new) 6.54 kB 🔴 +6.54 kB 🔴 +2.14 kB 🔴 +1.89 kB
assets/UserSelectView-CO6zfYjR.js (removed) 6.54 kB 🟢 -6.54 kB 🟢 -2.14 kB 🟢 -1.89 kB

Status: 1 added / 1 removed

Panels & Settings — 298 kB (baseline 298 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/LegacyCreditsPanel-BDRIchm_.js (removed) 21.4 kB 🟢 -21.4 kB 🟢 -5.15 kB 🟢 -4.5 kB
assets/LegacyCreditsPanel-Cl3VDCja.js (new) 21.4 kB 🔴 +21.4 kB 🔴 +5.16 kB 🔴 +4.5 kB
assets/KeybindingPanel-C3oaKvWL.js (new) 13.6 kB 🔴 +13.6 kB 🔴 +3.42 kB 🔴 +3.02 kB
assets/KeybindingPanel-CIyILn5k.js (removed) 13.6 kB 🟢 -13.6 kB 🟢 -3.42 kB 🟢 -3.02 kB
assets/ExtensionPanel-BjXvff-i.js (new) 10.8 kB 🔴 +10.8 kB 🔴 +2.57 kB 🔴 +2.26 kB
assets/ExtensionPanel-C2bddvUn.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -2.57 kB 🟢 -2.26 kB
assets/AboutPanel-CENIVG9O.js (new) 9.16 kB 🔴 +9.16 kB 🔴 +2.46 kB 🔴 +2.21 kB
assets/AboutPanel-Dz6bcopT.js (removed) 9.16 kB 🟢 -9.16 kB 🟢 -2.46 kB 🟢 -2.21 kB
assets/ServerConfigPanel-3DzH9se-.js (removed) 6.56 kB 🟢 -6.56 kB 🟢 -1.83 kB 🟢 -1.63 kB
assets/ServerConfigPanel-CfOlCAEL.js (new) 6.56 kB 🔴 +6.56 kB 🔴 +1.83 kB 🔴 +1.63 kB
assets/UserPanel-D1qviqyg.js (new) 6.23 kB 🔴 +6.23 kB 🔴 +1.72 kB 🔴 +1.51 kB
assets/UserPanel-D59w_JBc.js (removed) 6.23 kB 🟢 -6.23 kB 🟢 -1.72 kB 🟢 -1.51 kB
assets/settings-B_sqawkt.js 27.3 kB 27.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BhbWhsRg.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BlDXT7wp.js 21.7 kB 21.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Bz8HAvJu.js 21.1 kB 21.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C2vW8UNv.js 24.2 kB 24.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C9vsDM17.js 25.1 kB 25.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DWD49kQp.js 33.3 kB 33.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DZE27_Iz.js 25.9 kB 25.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-OXaZPcZF.js 26.6 kB 26.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-RbkKsnDG.js 25.2 kB 25.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

UI Components — 184 kB (baseline 184 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/Load3D.vue_vue_type_script_setup_true_lang-BSOs7fSr.js (new) 53.7 kB 🔴 +53.7 kB 🔴 +8.49 kB 🔴 +7.29 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-C0Ivs4oZ.js (removed) 53.7 kB 🟢 -53.7 kB 🟢 -8.49 kB 🟢 -7.29 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-CwdTAkBP.js (new) 48 kB 🔴 +48 kB 🔴 +10.3 kB 🔴 +8.97 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-DTSzVFLi.js (removed) 48 kB 🟢 -48 kB 🟢 -10.3 kB 🟢 -8.98 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-CsQ2fi9w.js (new) 48 kB 🔴 +48 kB 🔴 +10.7 kB 🔴 +9.32 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-DIRdmV8Y.js (removed) 48 kB 🟢 -48 kB 🟢 -10.6 kB 🟢 -9.32 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-Bc_ezWOr.js (new) 19.5 kB 🔴 +19.5 kB 🔴 +5.04 kB 🔴 +4.46 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-CCkUK3ed.js (removed) 19.5 kB 🟢 -19.5 kB 🟢 -5.04 kB 🟢 -4.47 kB
assets/ComfyQueueButton-BPIQ9P4W.js (new) 8.44 kB 🔴 +8.44 kB 🔴 +2.48 kB 🔴 +2.21 kB
assets/ComfyQueueButton-DDLfocNi.js (removed) 8.44 kB 🟢 -8.44 kB 🟢 -2.48 kB 🟢 -2.21 kB
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-7LywPWq3.js (removed) 2.14 kB 🟢 -2.14 kB 🟢 -890 B 🟢 -761 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-CJx6ljg0.js (new) 2.14 kB 🔴 +2.14 kB 🔴 +890 B 🔴 +768 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-BbSLAmH0.js (new) 897 B 🔴 +897 B 🔴 +503 B 🔴 +438 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-Dmlsm5s-.js (removed) 897 B 🟢 -897 B 🟢 -500 B 🟢 -435 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-Bjfb_hoW.js 1.34 kB 1.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-Bm2lwPFd.js 2.04 kB 2.04 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 7 added / 7 removed

Data & Services — 12.5 kB (baseline 12.5 kB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/keybindingService-BUX7_c3j.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -1.84 kB 🟢 -1.58 kB
assets/keybindingService-CbmwvzbO.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +1.83 kB 🔴 +1.58 kB
assets/audioService-DkXHu7Mw.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +964 B 🔴 +826 B
assets/audioService-Dreh9PzW.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -961 B 🟢 -824 B
assets/serverConfigStore-BP9UaJXd.js 2.83 kB 2.83 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 2 added / 2 removed

Utilities & Hooks — 3.18 kB (baseline 3.18 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-CHN_8MT6.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -651 B 🟢 -553 B
assets/audioUtils-CNKNm9dq.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +652 B 🔴 +549 B
assets/mathUtil-CD4DsosH.js 1.32 kB 1.32 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeFilterUtil-CXKCRJ-m.js 460 B 460 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

Vendor & Third-Party — 8.56 MB (baseline 8.56 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-W_3Knk2t.js 452 kB 452 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-BzuNIfYH.js 3.98 MB 3.98 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-CmhMHYBF.js 1.96 MB 1.96 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-aR6ntw5X.js 1.37 MB 1.37 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-DCLYW5rb.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-C3MDzIsc.js 160 kB 160 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BZLod3g9.js 407 kB 407 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 3.82 MB (baseline 3.82 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/WidgetRecordAudio-C3Wk1JrN.js (new) 20.4 kB 🔴 +20.4 kB 🔴 +5.24 kB 🔴 +4.63 kB
assets/WidgetRecordAudio-CvcTGqv9.js (removed) 20.4 kB 🟢 -20.4 kB 🟢 -5.23 kB 🟢 -4.63 kB
assets/AudioPreviewPlayer-BXNm6oQq.js (new) 13.4 kB 🔴 +13.4 kB 🔴 +3.37 kB 🔴 +3.01 kB
assets/AudioPreviewPlayer-pr9xxIO1.js (removed) 13.4 kB 🟢 -13.4 kB 🟢 -3.37 kB 🟢 -3.01 kB
assets/NumberControlPopover-CiDl5LGa.js (removed) 7.49 kB 🟢 -7.49 kB 🟢 -2.16 kB 🟢 -1.91 kB
assets/NumberControlPopover-COERsUC1.js (new) 7.49 kB 🔴 +7.49 kB 🔴 +2.16 kB 🔴 +1.91 kB
assets/WidgetGalleria-B0MqsaKj.js (removed) 4.1 kB 🟢 -4.1 kB 🟢 -1.44 kB 🟢 -1.3 kB
assets/WidgetGalleria-DMmVphES.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.44 kB 🔴 +1.3 kB
assets/WidgetColorPicker-CFguFo0i.js (removed) 3.41 kB 🟢 -3.41 kB 🟢 -1.38 kB 🟢 -1.23 kB
assets/WidgetColorPicker-DDXZmBzG.js (new) 3.41 kB 🔴 +3.41 kB 🔴 +1.38 kB 🔴 +1.23 kB
assets/WidgetTextarea-B01BJXOD.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.21 kB 🟢 -1.07 kB
assets/WidgetTextarea-Cypt4YA8.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.21 kB 🔴 +1.08 kB
assets/WidgetMarkdown-BC_ENfhv.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.28 kB 🟢 -1.13 kB
assets/WidgetMarkdown-DD0nALSo.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.28 kB 🔴 +1.13 kB
assets/WidgetAudioUI-BbUpcoCv.js (new) 2.86 kB 🔴 +2.86 kB 🔴 +1.16 kB 🔴 +1.05 kB
assets/WidgetAudioUI-BZ_BojmQ.js (removed) 2.86 kB 🟢 -2.86 kB 🟢 -1.17 kB 🟢 -1.06 kB
assets/WidgetInputText-BinCoEXu.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +918 B 🔴 +827 B
assets/WidgetInputText-CX0R4NLK.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -919 B 🟢 -850 B
assets/WidgetToggleSwitch-BECN8goW.js (new) 1.76 kB 🔴 +1.76 kB 🔴 +835 B 🔴 +734 B
assets/WidgetToggleSwitch-D1KJS8o9.js (removed) 1.76 kB 🟢 -1.76 kB 🟢 -834 B 🟢 -731 B
assets/MediaImageBottom-DdtIdxg7.js (new) 1.55 kB 🔴 +1.55 kB 🔴 +735 B 🔴 +643 B
assets/MediaImageBottom-DlrdXEfR.js (removed) 1.55 kB 🟢 -1.55 kB 🟢 -733 B 🟢 -640 B
assets/MediaAudioBottom-B_vshrDy.js (new) 1.51 kB 🔴 +1.51 kB 🔴 +734 B 🔴 +651 B
assets/MediaAudioBottom-oHNzRhby.js (removed) 1.51 kB 🟢 -1.51 kB 🟢 -735 B 🟢 -647 B
assets/Media3DBottom-BAVjTeG8.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +736 B 🔴 +652 B
assets/Media3DBottom-ChwB1BFM.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -733 B 🟢 -657 B
assets/MediaVideoBottom-CRXjSRmK.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -733 B 🟢 -647 B
assets/MediaVideoBottom-Dp8hjQjG.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +734 B 🔴 +654 B
assets/Media3DTop-CQGpH-CR.js (removed) 1.49 kB 🟢 -1.49 kB 🟢 -765 B 🟢 -655 B
assets/Media3DTop-l3xntXU1.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +765 B 🔴 +656 B
assets/WidgetSelect-CzOMjqIA.js (removed) 655 B 🟢 -655 B 🟢 -344 B 🟢 -289 B
assets/WidgetSelect-DR8RMIm8.js (new) 655 B 🔴 +655 B 🔴 +342 B 🔴 +287 B
assets/WidgetInputNumber-C1puxXDu.js (new) 595 B 🔴 +595 B 🔴 +328 B 🔴 +276 B
assets/WidgetInputNumber-Cr-yV4RR.js (removed) 595 B 🟢 -595 B 🟢 -333 B 🟢 -274 B
assets/Load3D-Dq9ys3xu.js (removed) 424 B 🟢 -424 B 🟢 -266 B 🟢 -225 B
assets/Load3D-DS_vEKgo.js (new) 424 B 🔴 +424 B 🔴 +267 B 🔴 +227 B
assets/WidgetLegacy-BYTO2VxM.js (new) 364 B 🔴 +364 B 🔴 +237 B 🔴 +194 B
assets/WidgetLegacy-CV_BoGvV.js (removed) 364 B 🟢 -364 B 🟢 -236 B 🟢 -223 B
assets/commands-_s-RvhJR.js 13.6 kB 13.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BuUILW6P.js 13 kB 13 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BV4R6fLx.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BWp4HdfU.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CLwPdnT6.js 14.2 kB 14.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CWMchBmd.js 15.9 kB 15.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DazTQhtc.js 12.9 kB 12.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DmWrOe93.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwiH7Kr6.js 13.8 kB 13.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-mS3LCNPn.js 14.5 kB 14.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BMi-Aksj.js 99 kB 99 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CqR8skJT.js 73.1 kB 73.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cw9RZWRY.js 89 B 89 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DcRHAFEy.js 81.7 kB 81.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DdFdLxku.js 72.2 kB 72.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DJAtuVu5.js 84.3 kB 84.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DK8I9Rk3.js 114 kB 114 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-gP_ssnMb.js 83.4 kB 83.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-nxXY9vGp.js 94 kB 94 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Ycd3gqkA.js 86.5 kB 86.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-taU5Yj_Q.js 1.46 kB 1.46 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-BoT3yC-l.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-Csf8f_9c.js 2.65 kB 2.65 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-_qLI3Y-X.js 317 kB 317 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BoBMp_wf.js 307 kB 307 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bw_Jitw_.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Ce9u3PlO.js 342 kB 342 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CgjGEDDp.js 285 kB 285 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CL3A8ieS.js 306 kB 306 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DNUc-sw4.js 303 kB 303 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DxUbhTnC.js 282 kB 282 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-i8mv_3Jj.js 369 kB 369 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-wCFicyab.js 310 kB 310 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-CWEwKtMY.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-DSf2ZEwg.js 2.21 kB 2.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 19 added / 19 removed

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aab9a30 and 208e1b1.

📒 Files selected for processing (3)
  • browser_tests/assets/groups/nested-groups-1-inner-node.json (1 hunks)
  • browser_tests/tests/vueNodes/groups/groups.spec.ts (1 hunks)
  • src/lib/litegraph/src/LGraphCanvas.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (browser_tests/CLAUDE.md)

browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx}: Test user workflows in browser tests
Use Playwright fixtures for browser tests
Follow naming conventions for browser tests
Check assets/ directory for test data when writing tests
Prefer specific selectors in browser tests
Test across multiple viewports

Files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
**/*.{ts,tsx,js,jsx,vue,json}

📄 CodeRabbit inference engine (AGENTS.md)

Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see .prettierrc)

Files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
  • src/lib/litegraph/src/LGraphCanvas.ts
  • browser_tests/assets/groups/nested-groups-1-inner-node.json
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; run pnpm format before committing
Use TypeScript for type safety; never use any type - use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nested if or for statements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
  • src/lib/litegraph/src/LGraphCanvas.ts
browser_tests/**/*.spec.ts

📄 CodeRabbit inference engine (AGENTS.md)

browser_tests/**/*.spec.ts: E2E test files must be named browser_tests/**/*.spec.ts and use Playwright
Follow Playwright best practices described in the official documentation for E2E tests
Do not use waitForTimeout in Playwright tests; use Locator actions and retrying assertions instead
Use tags like @mobile and @2x in Playwright tests for relevant test scenarios

Files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/lib/litegraph/src/LGraphCanvas.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Minimize the surface area (exported values) of each module and composable

Files:

  • src/lib/litegraph/src/LGraphCanvas.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/lib/litegraph/src/LGraphCanvas.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/lib/litegraph/src/LGraphCanvas.ts
src/lib/litegraph/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (src/lib/litegraph/CLAUDE.md)

src/lib/litegraph/**/*.{js,ts,jsx,tsx}: Run ESLint instead of manually figuring out whitespace fixes or other trivial style concerns using the pnpm lint:fix command
Take advantage of TypedArray subarray when appropriate
The size and pos properties of Rectangle share the same array buffer (subarray); they may be used to set the rectangle's size and position
Prefer single line if syntax over adding curly braces, when the statement has a very concise expression and concise, single line statement
Do not replace &&= or ||= with = when there is no reason to do so. If you do find a reason to remove either &&= or ||=, leave a comment explaining why the removal occurred
When writing methods, prefer returning idiomatic JavaScript undefined over null

Files:

  • src/lib/litegraph/src/LGraphCanvas.ts
src/lib/litegraph/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/lib/litegraph/CLAUDE.md)

Type assertions are an absolute last resort. In almost all cases, they are a crutch that leads to brittle code

Files:

  • src/lib/litegraph/src/LGraphCanvas.ts
🧠 Learnings (10)
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-13T05:54:28.225Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7415
File: browser_tests/tests/mobileBaseline.spec.ts:17-22
Timestamp: 2025-12-13T05:54:28.225Z
Learning: In browser_tests tests for the Comfy-Org/ComfyUI_frontend repository, the `comfyPage.loadWorkflow()` method already handles all necessary synchronization and waiting. No additional `await comfyPage.nextFrame()` call is needed before taking screenshots after loading a workflow.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
  • src/lib/litegraph/src/LGraphCanvas.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
  • src/lib/litegraph/src/LGraphCanvas.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
  • src/lib/litegraph/src/LGraphCanvas.ts
📚 Learning: 2025-12-13T05:34:15.488Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7415
File: browser_tests/tests/mobileBaseline.spec.ts:7-15
Timestamp: 2025-12-13T05:34:15.488Z
Learning: In Playwright tests for the ComfyUI frontend, the toPass() assertion uses incremental backoff during retries. When a test may involve async operations, increasing the timeout (e.g., to 5000 ms) can be sufficient instead of aggressively extending timeouts. Apply this understanding to tests under browser_tests/tests/; if not resolved, review the toPass() backoff behavior and ensure timeouts align with expected async completion without masking issues.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Take advantage of `TypedArray` `subarray` when appropriate

Applied to files:

  • src/lib/litegraph/src/LGraphCanvas.ts
📚 Learning: 2025-12-11T03:55:57.926Z
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.

Applied to files:

  • src/lib/litegraph/src/LGraphCanvas.ts
🧬 Code graph analysis (1)
browser_tests/tests/vueNodes/groups/groups.spec.ts (1)
src/lib/litegraph/src/LGraph.ts (1)
  • groups (391-393)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test
  • GitHub Check: setup
  • GitHub Check: lint-and-format
  • GitHub Check: collect
🔇 Additional comments (2)
src/lib/litegraph/src/LGraphCanvas.ts (1)

8554-8573: Correct fix for the double-move; consider guarding against duplicate node moves in nested scenarios.

Passing skipChildren=true for non-node children matches the root-cause description and should prevent nested groups’ children from being moved twice. If LGraphGroup._children can ever include nodes that also belong to nested groups, nodesToMove.push(...) could still duplicate per-node updates—worth confirming and, if needed, deduping by node.id before applying mutations.

browser_tests/assets/groups/nested-groups-1-inner-node.json (1)

1-92: Test asset looks fit for purpose (nested group bounds + stable titles).
No issues spotted for its intended use in the new E2E test.

DrJKL
DrJKL previously approved these changes Dec 14, 2025
@DrJKL DrJKL force-pushed the fix-nested-groups-vue branch from 775140a to ee72ce5 Compare December 14, 2025 02:37
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
browser_tests/tests/vueNodes/groups/groups.spec.ts (2)

40-40: Remove redundant nextFrame() call.

Based on learnings, comfyPage.loadWorkflow() already handles all necessary synchronization and waiting. The additional nextFrame() call is redundant.

Apply this diff:

   await comfyPage.loadWorkflow('groups/nested-groups-1-inner-node')
-  await comfyPage.nextFrame()

78-90: Add retrying assertions to handle async state updates after drag.

After dragAndDrop, the canvas state may update asynchronously. Reading positions immediately can cause flakiness. Use expect.poll() or toPass() to retry until the positions stabilize.

Apply this diff:

-  // Get final positions
-  const final = await getGroupData()
-  const finalOffsetX = final.inner.x - final.outer.x
-  const finalOffsetY = final.inner.y - final.outer.y
-
-  // The relative offset should be maintained (inner group moved with outer)
-  expect(finalOffsetX).toBeCloseTo(initialOffsetX, 0)
-  expect(finalOffsetY).toBeCloseTo(initialOffsetY, 0)
-
-  // Both groups should have moved
-  expect(final.outer.x).not.toBe(initial.outer.x)
-  expect(final.inner.x).not.toBe(initial.inner.x)
+  // Wait for positions to settle after drag
+  await expect(async () => {
+    const final = await getGroupData()
+    const finalOffsetX = final.inner.x - final.outer.x
+    const finalOffsetY = final.inner.y - final.outer.y
+
+    // The relative offset should be maintained (inner group moved with outer)
+    expect(finalOffsetX).toBeCloseTo(initialOffsetX, 0)
+    expect(finalOffsetY).toBeCloseTo(initialOffsetY, 0)
+
+    // Both groups should have moved
+    expect(final.outer.x).not.toBe(initial.outer.x)
+    expect(final.inner.x).not.toBe(initial.inner.x)
+  }).toPass({ timeout: 5000 })

Based on learnings, toPass() uses incremental backoff during retries, making this approach robust for async operations.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ee72ce5 and 71e4254.

📒 Files selected for processing (2)
  • browser_tests/tests/vueNodes/groups/groups.spec.ts (1 hunks)
  • tt.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (browser_tests/CLAUDE.md)

browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx}: Test user workflows in browser tests
Use Playwright fixtures for browser tests
Follow naming conventions for browser tests
Check assets/ directory for test data when writing tests
Prefer specific selectors in browser tests
Test across multiple viewports

Files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
**/*.{ts,tsx,js,jsx,vue,json}

📄 CodeRabbit inference engine (AGENTS.md)

Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see .prettierrc)

Files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; run pnpm format before committing
Use TypeScript for type safety; never use any type - use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nested if or for statements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
browser_tests/**/*.spec.ts

📄 CodeRabbit inference engine (AGENTS.md)

browser_tests/**/*.spec.ts: E2E test files must be named browser_tests/**/*.spec.ts and use Playwright
Follow Playwright best practices described in the official documentation for E2E tests
Do not use waitForTimeout in Playwright tests; use Locator actions and retrying assertions instead
Use tags like @mobile and @2x in Playwright tests for relevant test scenarios

Files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
🧠 Learnings (15)
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-13T05:54:28.225Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7415
File: browser_tests/tests/mobileBaseline.spec.ts:17-22
Timestamp: 2025-12-13T05:54:28.225Z
Learning: In browser_tests tests for the Comfy-Org/ComfyUI_frontend repository, the `comfyPage.loadWorkflow()` method already handles all necessary synchronization and waiting. No additional `await comfyPage.nextFrame()` call is needed before taking screenshots after loading a workflow.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-13T05:34:15.488Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7415
File: browser_tests/tests/mobileBaseline.spec.ts:7-15
Timestamp: 2025-12-13T05:34:15.488Z
Learning: In Playwright tests for the ComfyUI frontend, the toPass() assertion uses incremental backoff during retries. When a test may involve async operations, increasing the timeout (e.g., to 5000 ms) can be sufficient instead of aggressively extending timeouts. Apply this understanding to tests under browser_tests/tests/; if not resolved, review the toPass() backoff behavior and ensure timeouts align with expected async completion without masking issues.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to browser_tests/**/*.spec.ts : Do not use `waitForTimeout` in Playwright tests; use Locator actions and retrying assertions instead

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to browser_tests/**/*.spec.ts : Follow Playwright best practices described in the official documentation for E2E tests

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Be parsimonious in testing; do not write redundant tests; see composable tests approach

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Prefer specific selectors in browser tests

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-10T03:09:19.636Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:19.636Z
Learning: For test files in the Comfy-Org/ComfyUI_frontend repository: When writing tests, prefer selecting elements by accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests verify actual user-facing behavior and accessibility compliance.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
🧬 Code graph analysis (1)
browser_tests/tests/vueNodes/groups/groups.spec.ts (2)
src/scripts/app.ts (1)
  • app (1761-1761)
src/lib/litegraph/src/LGraph.ts (1)
  • groups (391-393)
🪛 markdownlint-cli2 (0.18.1)
tt.md

1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: setup
  • GitHub Check: test
  • GitHub Check: lint-and-format
  • GitHub Check: collect
🔇 Additional comments (1)
tt.md (1)

1-10: Clarify if this file should be committed or removed before merge.

This file appears to be temporary developer notes explaining the bug during debugging. The non-descriptive filename "tt.md" and lack of formal structure suggest it may not be intended for the repository.

If this is meant as permanent documentation:

  • Add a descriptive filename (e.g., docs/nested-groups-bug-explanation.md)
  • Add a top-level heading to fix the markdown linting issue
  • Provide context about when/why this was written

If this is temporary:

  • Remove it before merging

Should this file be committed to the repository?

The inner group was being moved twice:
1. Once in moveGroupChildren when processing outer group's children
2. Once in the main loop when processing the inner group itself

Fix: Skip LGraphGroup children in moveGroupChildren since they're
already in allItems and will be processed in the main loop.

Also refactor test to use ComfyPage helpers and retrying assertions.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/litegraph/src/LGraphCanvas.ts (1)

8554-8573: Double-move bug confirmed for non-node children in groups.

Reroutes and other non-node children that belong to a moving group are moved twice: once in the moveChildNodesInGroupVueMode loop (line 8602, else branch) and again in moveGroupChildren (line 8571). This occurs because getAllNestedItems() recursively includes all reroutes from group._children, and the current collectNodesInGroups() only tracks nodes, leaving reroutes unprotected.

The proposed fix is sound: change collectNodesInGroups() to collectNonGroupItemsInGroups() to track all non-group items (nodes and reroutes), then skip any such item in the main loop at line 8600–8602.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 71e4254 and 350dc16.

📒 Files selected for processing (3)
  • browser_tests/fixtures/ComfyPage.ts (1 hunks)
  • browser_tests/tests/vueNodes/groups/groups.spec.ts (1 hunks)
  • src/lib/litegraph/src/LGraphCanvas.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (browser_tests/CLAUDE.md)

browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx}: Test user workflows in browser tests
Use Playwright fixtures for browser tests
Follow naming conventions for browser tests
Check assets/ directory for test data when writing tests
Prefer specific selectors in browser tests
Test across multiple viewports

Files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
**/*.{ts,tsx,js,jsx,vue,json}

📄 CodeRabbit inference engine (AGENTS.md)

Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see .prettierrc)

Files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
  • browser_tests/fixtures/ComfyPage.ts
  • src/lib/litegraph/src/LGraphCanvas.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; run pnpm format before committing
Use TypeScript for type safety; never use any type - use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nested if or for statements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
  • browser_tests/fixtures/ComfyPage.ts
  • src/lib/litegraph/src/LGraphCanvas.ts
browser_tests/**/*.spec.ts

📄 CodeRabbit inference engine (AGENTS.md)

browser_tests/**/*.spec.ts: E2E test files must be named browser_tests/**/*.spec.ts and use Playwright
Follow Playwright best practices described in the official documentation for E2E tests
Do not use waitForTimeout in Playwright tests; use Locator actions and retrying assertions instead
Use tags like @mobile and @2x in Playwright tests for relevant test scenarios

Files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/lib/litegraph/src/LGraphCanvas.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Minimize the surface area (exported values) of each module and composable

Files:

  • src/lib/litegraph/src/LGraphCanvas.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/lib/litegraph/src/LGraphCanvas.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/lib/litegraph/src/LGraphCanvas.ts
src/lib/litegraph/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (src/lib/litegraph/CLAUDE.md)

src/lib/litegraph/**/*.{js,ts,jsx,tsx}: Run ESLint instead of manually figuring out whitespace fixes or other trivial style concerns using the pnpm lint:fix command
Take advantage of TypedArray subarray when appropriate
The size and pos properties of Rectangle share the same array buffer (subarray); they may be used to set the rectangle's size and position
Prefer single line if syntax over adding curly braces, when the statement has a very concise expression and concise, single line statement
Do not replace &&= or ||= with = when there is no reason to do so. If you do find a reason to remove either &&= or ||=, leave a comment explaining why the removal occurred
When writing methods, prefer returning idiomatic JavaScript undefined over null

Files:

  • src/lib/litegraph/src/LGraphCanvas.ts
src/lib/litegraph/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/lib/litegraph/CLAUDE.md)

Type assertions are an absolute last resort. In almost all cases, they are a crutch that leads to brittle code

Files:

  • src/lib/litegraph/src/LGraphCanvas.ts
🧠 Learnings (19)
📓 Common learnings
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-13T05:54:28.225Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7415
File: browser_tests/tests/mobileBaseline.spec.ts:17-22
Timestamp: 2025-12-13T05:54:28.225Z
Learning: In browser_tests tests for the Comfy-Org/ComfyUI_frontend repository, the `comfyPage.loadWorkflow()` method already handles all necessary synchronization and waiting. No additional `await comfyPage.nextFrame()` call is needed before taking screenshots after loading a workflow.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-13T05:34:15.488Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7415
File: browser_tests/tests/mobileBaseline.spec.ts:7-15
Timestamp: 2025-12-13T05:34:15.488Z
Learning: In Playwright tests for the ComfyUI frontend, the toPass() assertion uses incremental backoff during retries. When a test may involve async operations, increasing the timeout (e.g., to 5000 ms) can be sufficient instead of aggressively extending timeouts. Apply this understanding to tests under browser_tests/tests/; if not resolved, review the toPass() backoff behavior and ensure timeouts align with expected async completion without masking issues.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test across multiple viewports

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to browser_tests/**/*.spec.ts : Follow Playwright best practices described in the official documentation for E2E tests

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.test.ts : Be parsimonious in testing; do not write redundant tests; see composable tests approach

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Prefer specific selectors in browser tests

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-10T03:09:19.636Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:19.636Z
Learning: For test files in the Comfy-Org/ComfyUI_frontend repository: When writing tests, prefer selecting elements by accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests verify actual user-facing behavior and accessibility compliance.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
  • browser_tests/fixtures/ComfyPage.ts
  • src/lib/litegraph/src/LGraphCanvas.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
  • browser_tests/fixtures/ComfyPage.ts
  • src/lib/litegraph/src/LGraphCanvas.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • browser_tests/tests/vueNodes/groups/groups.spec.ts
  • browser_tests/fixtures/ComfyPage.ts
  • src/lib/litegraph/src/LGraphCanvas.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Do not replace `&&=` or `||=` with `=` when there is no reason to do so. If you do find a reason to remove either `&&=` or `||=`, leave a comment explaining why the removal occurred

Applied to files:

  • src/lib/litegraph/src/LGraphCanvas.ts
📚 Learning: 2025-12-11T03:55:57.926Z
Learnt from: simula-r
Repo: Comfy-Org/ComfyUI_frontend PR: 7252
File: src/renderer/extensions/vueNodes/components/ImagePreview.vue:151-158
Timestamp: 2025-12-11T03:55:57.926Z
Learning: In src/renderer/extensions/vueNodes/components/ImagePreview.vue and LGraphNode.vue, keyboard navigation for image galleries should respond to node-level focus (via keyEvent injection from LGraphNode), not require focus within the image preview wrapper itself. This allows users to navigate the gallery with arrow keys immediately when the node is focused/selected.

Applied to files:

  • src/lib/litegraph/src/LGraphCanvas.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{js,ts,jsx,tsx} : Take advantage of `TypedArray` `subarray` when appropriate

Applied to files:

  • src/lib/litegraph/src/LGraphCanvas.ts
🧬 Code graph analysis (2)
browser_tests/tests/vueNodes/groups/groups.spec.ts (1)
tests-ui/tests/litegraph/core/fixtures/testExtensions.ts (1)
  • test (35-67)
browser_tests/fixtures/ComfyPage.ts (3)
src/lib/litegraph/src/subgraph/SubgraphIONodeBase.ts (2)
  • pos (57-59)
  • pos (61-63)
src/lib/litegraph/src/LGraph.ts (1)
  • groups (391-393)
src/scripts/app.ts (1)
  • app (1761-1761)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: deploy-and-comment
  • GitHub Check: lint-and-format
  • GitHub Check: setup
  • GitHub Check: collect
  • GitHub Check: test
🔇 Additional comments (1)
browser_tests/fixtures/ComfyPage.ts (1)

1657-1672: LGTM!

The method correctly retrieves a group's position by title and provides clear error handling when the group is not found. The implementation follows the existing patterns in this fixture file for similar lookup operations.

Comment on lines +1674 to +1704
/**
* Drag a group by its title.
* @param options.name The title of the group to drag
* @param options.deltaX Horizontal drag distance in screen pixels
* @param options.deltaY Vertical drag distance in screen pixels
*/
async dragGroup(options: {
name: string
deltaX: number
deltaY: number
}): Promise<void> {
const { name, deltaX, deltaY } = options
const screenPos = await this.page.evaluate((title) => {
const app = window['app']
const groups = app.graph.groups
const group = groups.find((g: { title: string }) => g.title === title)
if (!group) return null
// Position in the title area of the group
const clientPos = app.canvasPosToClientPos([
group.pos[0] + 50,
group.pos[1] + 15
])
return { x: clientPos[0], y: clientPos[1] }
}, name)
if (!screenPos) throw new Error(`Group "${name}" not found`)

await this.dragAndDrop(screenPos, {
x: screenPos.x + deltaX,
y: screenPos.y + deltaY
})
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

LGTM! Consider parameter naming consistency.

The method correctly locates the group, converts coordinates, and performs the drag operation. The magic numbers for the title area offset are appropriately documented.

Minor optional suggestion: For consistency with getGroupPosition, consider using title instead of name for the group identifier parameter. Both methods refer to the same concept (the group's title property), so using the same terminology would improve API consistency.

🤖 Prompt for AI Agents
In browser_tests/fixtures/ComfyPage.ts around lines 1674 to 1704, rename the
method parameter and all internal uses from name to title for consistency with
getGroupPosition: update the JSDoc param, the options type ({ title: string ...
}), the destructuring const { title, deltaX, deltaY }, the page.evaluate
parameter and usage, and the thrown error message to reference title; ensure
callers are updated to pass title instead of name and run tests to confirm no
call sites break.

Comment on lines +36 to +71
test('should move nested groups together when dragging outer group', async ({
comfyPage
}) => {
await comfyPage.loadWorkflow('groups/nested-groups-1-inner-node')

// Get initial positions with null guards
const outerInitial = await comfyPage.getGroupPosition('Outer Group')
const innerInitial = await comfyPage.getGroupPosition('Inner Group')

const initialOffsetX = innerInitial.x - outerInitial.x
const initialOffsetY = innerInitial.y - outerInitial.y

// Drag the outer group
const dragDelta = { x: 100, y: 80 }
await comfyPage.dragGroup({
name: 'Outer Group',
deltaX: dragDelta.x,
deltaY: dragDelta.y
})

// Use retrying assertion to wait for positions to update
await expect(async () => {
const outerFinal = await comfyPage.getGroupPosition('Outer Group')
const innerFinal = await comfyPage.getGroupPosition('Inner Group')

const finalOffsetX = innerFinal.x - outerFinal.x
const finalOffsetY = innerFinal.y - outerFinal.y

// Both groups should have moved
expect(outerFinal.x).not.toBe(outerInitial.x)
expect(innerFinal.x).not.toBe(innerInitial.x)

// The relative offset should be maintained (inner group moved with outer)
expect(finalOffsetX).toBeCloseTo(initialOffsetX, 0)
expect(finalOffsetY).toBeCloseTo(initialOffsetY, 0)
}).toPass({ timeout: 5000 })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add Y-axis movement assertions (currently only X is checked).

You drag by { x: 100, y: 80 } but only assert *.x changed (Line 64-67). Add y checks so a “no vertical move” regression can’t slip through.

@@
       // Both groups should have moved
       expect(outerFinal.x).not.toBe(outerInitial.x)
+      expect(outerFinal.y).not.toBe(outerInitial.y)
       expect(innerFinal.x).not.toBe(innerInitial.x)
+      expect(innerFinal.y).not.toBe(innerInitial.y)
🤖 Prompt for AI Agents
In browser_tests/tests/vueNodes/groups/groups.spec.ts around lines 36 to 71, the
test drags the outer group by { x: 100, y: 80 } but only asserts that the x
positions changed; add assertions that the y positions changed as well: after
computing outerFinal and innerFinal, add
expect(outerFinal.y).not.toBe(outerInitial.y) and
expect(innerFinal.y).not.toBe(innerInitial.y) so vertical movement regressions
are caught (keep the existing relative-offset assertions intact).

@christian-byrne christian-byrne added needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch core/1.35 labels Dec 14, 2025
@christian-byrne christian-byrne merged commit 585d46d into main Dec 15, 2025
37 of 38 checks passed
@christian-byrne christian-byrne deleted the fix-nested-groups-vue branch December 15, 2025 02:37
github-actions bot pushed a commit that referenced this pull request Dec 15, 2025
…mode) (#7447)

## Summary

Fixes issue when dragging a group that had inner groups when in vue
mode.

When dragging the outer group in Vue mode:

1. getAllNestedItems(selected) returns ALL items: outer group + inner
groups + nodes
2. moveChildNodesInGroupVueMode loops through all items
3. For outer group G1: calls G1.move(delta, true) then
moveGroupChildren(G1, ...)
4. moveGroupChildren calls G2.move(delta) (no skipChildren) - this moves
G2 AND G2's children!
5. Then the loop reaches G2: calls G2.move(delta, true) - moves G2 again
6. Plus moveGroupChildren(G2, ...) processes G2's children again

This PR fixes it by adding `skipChildren=true` to the `move` call.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7447-fix-inner-groups-being-moved-double-when-moving-outer-group-in-vue-mode-2c86d73d365081ce97abec682f2a8518)
by [Unito](https://www.unito.io)
@comfy-pr-bot
Copy link
Member

@christian-byrne Successfully backported to #7480

@github-actions github-actions bot removed the needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch label Dec 15, 2025
christian-byrne added a commit that referenced this pull request Dec 15, 2025
… outer group (in vue mode) (#7480)

Backport of #7447 to `core/1.35`

Automatically created by backport workflow.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7480-backport-core-1-35-fix-inner-groups-being-moved-double-when-moving-outer-group-in-vue-2ca6d73d365081b7a0ddf63abc119b1f)
by [Unito](https://www.unito.io)

Co-authored-by: Christian Byrne <cbyrne@comfy.org>
@christian-byrne christian-byrne added needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch core/1.34 labels Dec 15, 2025
github-actions bot pushed a commit that referenced this pull request Dec 15, 2025
…mode) (#7447)

## Summary

Fixes issue when dragging a group that had inner groups when in vue
mode.

When dragging the outer group in Vue mode:

1. getAllNestedItems(selected) returns ALL items: outer group + inner
groups + nodes
2. moveChildNodesInGroupVueMode loops through all items
3. For outer group G1: calls G1.move(delta, true) then
moveGroupChildren(G1, ...)
4. moveGroupChildren calls G2.move(delta) (no skipChildren) - this moves
G2 AND G2's children!
5. Then the loop reaches G2: calls G2.move(delta, true) - moves G2 again
6. Plus moveGroupChildren(G2, ...) processes G2's children again

This PR fixes it by adding `skipChildren=true` to the `move` call.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7447-fix-inner-groups-being-moved-double-when-moving-outer-group-in-vue-mode-2c86d73d365081ce97abec682f2a8518)
by [Unito](https://www.unito.io)
@github-actions
Copy link

⚠️ Backport to core/1.35 failed

Reason: Merge conflicts detected during cherry-pick of 585d46d

📄 Conflicting files

🤖 Prompt for AI Agents
Backport PR #7447 (https://github.com/Comfy-Org/ComfyUI_frontend/pull/7447) to core/1.35.
Cherry-pick merge commit 585d46d4fbd9b394f1caa30f4256999e25839850 onto new branch
backport-7447-to-core-1.35 from origin/core/1.35.
Resolve conflicts in: .
For test snapshots (browser_tests/**/*-snapshots/), accept PR version if
changed in original PR, else keep target. For package.json versions, keep
target branch. For pnpm-lock.yaml, regenerate with pnpm install.
Ask user for non-obvious conflicts.
Create PR titled "[backport core/1.35] <original title>" with label "backport".
See .github/workflows/pr-backport.yaml for workflow details.

cc @christian-byrne

github-actions bot pushed a commit that referenced this pull request Dec 15, 2025
…mode) (#7447)

## Summary

Fixes issue when dragging a group that had inner groups when in vue
mode.

When dragging the outer group in Vue mode:

1. getAllNestedItems(selected) returns ALL items: outer group + inner
groups + nodes
2. moveChildNodesInGroupVueMode loops through all items
3. For outer group G1: calls G1.move(delta, true) then
moveGroupChildren(G1, ...)
4. moveGroupChildren calls G2.move(delta) (no skipChildren) - this moves
G2 AND G2's children!
5. Then the loop reaches G2: calls G2.move(delta, true) - moves G2 again
6. Plus moveGroupChildren(G2, ...) processes G2's children again

This PR fixes it by adding `skipChildren=true` to the `move` call.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7447-fix-inner-groups-being-moved-double-when-moving-outer-group-in-vue-mode-2c86d73d365081ce97abec682f2a8518)
by [Unito](https://www.unito.io)
@github-actions
Copy link

⚠️ Backport to core/1.35 failed

Reason: Merge conflicts detected during cherry-pick of 585d46d

📄 Conflicting files

🤖 Prompt for AI Agents
Backport PR #7447 (https://github.com/Comfy-Org/ComfyUI_frontend/pull/7447) to core/1.35.
Cherry-pick merge commit 585d46d4fbd9b394f1caa30f4256999e25839850 onto new branch
backport-7447-to-core-1.35 from origin/core/1.35.
Resolve conflicts in: .
For test snapshots (browser_tests/**/*-snapshots/), accept PR version if
changed in original PR, else keep target. For package.json versions, keep
target branch. For pnpm-lock.yaml, regenerate with pnpm install.
Ask user for non-obvious conflicts.
Create PR titled "[backport core/1.35] <original title>" with label "backport".
See .github/workflows/pr-backport.yaml for workflow details.

cc @christian-byrne

christian-byrne added a commit that referenced this pull request Dec 15, 2025
…mode) (#7447)

## Summary

Fixes issue when dragging a group that had inner groups when in vue
mode.

When dragging the outer group in Vue mode:

1. getAllNestedItems(selected) returns ALL items: outer group + inner
groups + nodes
2. moveChildNodesInGroupVueMode loops through all items
3. For outer group G1: calls G1.move(delta, true) then
moveGroupChildren(G1, ...)
4. moveGroupChildren calls G2.move(delta) (no skipChildren) - this moves
G2 AND G2's children!
5. Then the loop reaches G2: calls G2.move(delta, true) - moves G2 again
6. Plus moveGroupChildren(G2, ...) processes G2's children again

This PR fixes it by adding `skipChildren=true` to the `move` call.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7447-fix-inner-groups-being-moved-double-when-moving-outer-group-in-vue-mode-2c86d73d365081ce97abec682f2a8518)
by [Unito](https://www.unito.io)
christian-byrne added a commit that referenced this pull request Dec 15, 2025
… outer group (in vue mode) (#7525)

## Summary

Backport of #7447 to core/1.34.

Fixes issue when dragging a group that had inner groups when in vue
mode.

When dragging the outer group in Vue mode:

1. getAllNestedItems(selected) returns ALL items: outer group + inner
groups + nodes
2. moveChildNodesInGroupVueMode loops through all items
3. For outer group G1: calls G1.move(delta, true) then
moveGroupChildren(G1, ...)
4. moveGroupChildren calls G2.move(delta) (no skipChildren) - this moves
G2 AND G2's children!
5. Then the loop reaches G2: calls G2.move(delta, true) - moves G2 again
6. Plus moveGroupChildren(G2, ...) processes G2's children again

This PR fixes it by adding `skipChildren=true` to the `move` call.
Enferlain pushed a commit to Enferlain/ComfyUI_frontend that referenced this pull request Dec 18, 2025
…mode) (Comfy-Org#7447)

## Summary

Fixes issue when dragging a group that had inner groups when in vue
mode.

When dragging the outer group in Vue mode:

1. getAllNestedItems(selected) returns ALL items: outer group + inner
groups + nodes
2. moveChildNodesInGroupVueMode loops through all items
3. For outer group G1: calls G1.move(delta, true) then
moveGroupChildren(G1, ...)
4. moveGroupChildren calls G2.move(delta) (no skipChildren) - this moves
G2 AND G2's children!
5. Then the loop reaches G2: calls G2.move(delta, true) - moves G2 again
6. Plus moveGroupChildren(G2, ...) processes G2's children again

This PR fixes it by adding `skipChildren=true` to the `move` call.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7447-fix-inner-groups-being-moved-double-when-moving-outer-group-in-vue-mode-2c86d73d365081ce97abec682f2a8518)
by [Unito](https://www.unito.io)
Yourz pushed a commit that referenced this pull request Dec 24, 2025
…mode) (#7447)

## Summary

Fixes issue when dragging a group that had inner groups when in vue
mode.

When dragging the outer group in Vue mode:

1. getAllNestedItems(selected) returns ALL items: outer group + inner
groups + nodes
2. moveChildNodesInGroupVueMode loops through all items
3. For outer group G1: calls G1.move(delta, true) then
moveGroupChildren(G1, ...)
4. moveGroupChildren calls G2.move(delta) (no skipChildren) - this moves
G2 AND G2's children!
5. Then the loop reaches G2: calls G2.move(delta, true) - moves G2 again
6. Plus moveGroupChildren(G2, ...) processes G2's children again

This PR fixes it by adding `skipChildren=true` to the `move` call.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7447-fix-inner-groups-being-moved-double-when-moving-outer-group-in-vue-mode-2c86d73d365081ce97abec682f2a8518)
by [Unito](https://www.unito.io)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:groups area:vue-migration needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants