test: add mock data fixtures for backend API responses#10662
test: add mock data fixtures for backend API responses#10662christian-byrne merged 6 commits intomainfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughAdds deterministic Playwright test fixtures and documentation: a typed node definitions fixture (+factory) and a system stats fixture; updates package dependency and CI license-checker exclusion. README notes route handlers must be registered before the fixture's navigation occurs. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
🎨 Storybook: ✅ Built — View Storybook |
🎭 Playwright: ✅ 770 passed, 0 failed · 2 flaky📊 Browser Reports
|
📦 Bundle: 5.09 MB gzip 🔴 +81 BDetailsSummary
Category Glance App Entry Points — 22.3 kB (baseline 22.3 kB) • ⚪ 0 BMain entry bundles and manifests
Status: 1 added / 1 removed Graph Workspace — 1.14 MB (baseline 1.14 MB) • ⚪ 0 BGraph editor runtime, canvas, workflow orchestration
Status: 1 added / 1 removed Views & Navigation — 76.6 kB (baseline 76.6 kB) • ⚪ 0 BTop-level views, pages, and routed surfaces
Status: 9 added / 9 removed / 2 unchanged Panels & Settings — 484 kB (baseline 484 kB) • ⚪ 0 BConfiguration panels, inspectors, and settings screens
Status: 10 added / 10 removed / 12 unchanged User & Accounts — 17.1 kB (baseline 17.1 kB) • ⚪ 0 BAuthentication, profile, and account management bundles
Status: 5 added / 5 removed / 2 unchanged Editors & Dialogs — 109 kB (baseline 109 kB) • ⚪ 0 BModals, dialogs, drawers, and in-app editors
Status: 2 added / 2 removed UI Components — 60.3 kB (baseline 60.3 kB) • ⚪ 0 BReusable component library chunks
Status: 5 added / 5 removed / 8 unchanged Data & Services — 2.96 MB (baseline 2.96 MB) • ⚪ 0 BStores, services, APIs, and repositories
Status: 13 added / 13 removed / 4 unchanged Utilities & Hooks — 334 kB (baseline 334 kB) • ⚪ 0 BHelpers, composables, and utility bundles
Status: 13 added / 13 removed / 12 unchanged Vendor & Third-Party — 9.8 MB (baseline 9.8 MB) • ⚪ 0 BExternal libraries and shared vendor chunks Status: 16 unchanged Other — 8.45 MB (baseline 8.45 MB) • ⚪ 0 BBundles that do not match a named category
Status: 55 added / 55 removed / 79 unchanged ⚡ Performance Report
All metrics
Historical variance (last 15 runs)
Trend (last 15 commits on main)
Raw data{
"timestamp": "2026-03-29T22:06:55.651Z",
"gitSha": "aa8e94f73219b41c976b6fea3dd37ff0165b17d7",
"branch": "mai-15-backend-data-fixtures",
"measurements": [
{
"name": "canvas-idle",
"durationMs": 2006.668000000019,
"styleRecalcs": 10,
"styleRecalcDurationMs": 9.662,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 342.69000000000005,
"heapDeltaBytes": 20408520,
"heapUsedBytes": 63091012,
"domNodes": 20,
"jsHeapTotalBytes": 23068672,
"scriptDurationMs": 22.759999999999994,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-idle",
"durationMs": 2025.2340000000117,
"styleRecalcs": 11,
"styleRecalcDurationMs": 11.159,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 357.734,
"heapDeltaBytes": 20999836,
"heapUsedBytes": 63511480,
"domNodes": 22,
"jsHeapTotalBytes": 23068672,
"scriptDurationMs": 22.226999999999997,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-idle",
"durationMs": 2013.1640000000743,
"styleRecalcs": 13,
"styleRecalcDurationMs": 12.639000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 365.84900000000005,
"heapDeltaBytes": 21058628,
"heapUsedBytes": 64745496,
"domNodes": 25,
"jsHeapTotalBytes": 22544384,
"scriptDurationMs": 23.151999999999997,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1910.6960000000015,
"styleRecalcs": 76,
"styleRecalcDurationMs": 45.924,
"layouts": 12,
"layoutDurationMs": 4.005000000000001,
"taskDurationMs": 850.2189999999999,
"heapDeltaBytes": 16311984,
"heapUsedBytes": 58753116,
"domNodes": 61,
"jsHeapTotalBytes": 23330816,
"scriptDurationMs": 153.576,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1784.7550000000183,
"styleRecalcs": 73,
"styleRecalcDurationMs": 36.23500000000001,
"layouts": 12,
"layoutDurationMs": 3.613,
"taskDurationMs": 747.9440000000001,
"heapDeltaBytes": 16666164,
"heapUsedBytes": 59043056,
"domNodes": 56,
"jsHeapTotalBytes": 23592960,
"scriptDurationMs": 133.135,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1781.052999999929,
"styleRecalcs": 73,
"styleRecalcDurationMs": 35.354,
"layouts": 12,
"layoutDurationMs": 3.639,
"taskDurationMs": 746.167,
"heapDeltaBytes": 15897604,
"heapUsedBytes": 58700072,
"domNodes": 56,
"jsHeapTotalBytes": 23592960,
"scriptDurationMs": 133.513,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1732.7699999999595,
"styleRecalcs": 32,
"styleRecalcDurationMs": 19.031,
"layouts": 6,
"layoutDurationMs": 0.6249999999999999,
"taskDurationMs": 319.61899999999997,
"heapDeltaBytes": 24628916,
"heapUsedBytes": 67094168,
"domNodes": 80,
"jsHeapTotalBytes": 20971520,
"scriptDurationMs": 29.399,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1722.5349999999935,
"styleRecalcs": 31,
"styleRecalcDurationMs": 19.729999999999997,
"layouts": 6,
"layoutDurationMs": 0.68,
"taskDurationMs": 315.801,
"heapDeltaBytes": 24682568,
"heapUsedBytes": 67410888,
"domNodes": 79,
"jsHeapTotalBytes": 20971520,
"scriptDurationMs": 28.507000000000005,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1762.2840000000224,
"styleRecalcs": 32,
"styleRecalcDurationMs": 20.631999999999998,
"layouts": 6,
"layoutDurationMs": 0.6630000000000001,
"taskDurationMs": 332.382,
"heapDeltaBytes": 24737928,
"heapUsedBytes": 67245468,
"domNodes": 80,
"jsHeapTotalBytes": 20185088,
"scriptDurationMs": 33.219,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "dom-widget-clipping",
"durationMs": 592.0689999999809,
"styleRecalcs": 13,
"styleRecalcDurationMs": 10.453000000000003,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 365.46,
"heapDeltaBytes": 6751508,
"heapUsedBytes": 49087160,
"domNodes": 22,
"jsHeapTotalBytes": 13369344,
"scriptDurationMs": 71.52799999999999,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "dom-widget-clipping",
"durationMs": 573.3050000000048,
"styleRecalcs": 12,
"styleRecalcDurationMs": 8.072,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 349.58,
"heapDeltaBytes": -1920452,
"heapUsedBytes": 49383976,
"domNodes": 19,
"jsHeapTotalBytes": 15466496,
"scriptDurationMs": 69.50200000000001,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "dom-widget-clipping",
"durationMs": 591.6609999999309,
"styleRecalcs": 13,
"styleRecalcDurationMs": 9.523,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 343.37800000000004,
"heapDeltaBytes": 6800804,
"heapUsedBytes": 49250564,
"domNodes": 22,
"jsHeapTotalBytes": 12582912,
"scriptDurationMs": 67.394,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "large-graph-idle",
"durationMs": 2028.2320000000027,
"styleRecalcs": 10,
"styleRecalcDurationMs": 10.354000000000003,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 570.088,
"heapDeltaBytes": 4351692,
"heapUsedBytes": 55637356,
"domNodes": -257,
"jsHeapTotalBytes": 16453632,
"scriptDurationMs": 113.65899999999999,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-idle",
"durationMs": 2020.3239999999596,
"styleRecalcs": 11,
"styleRecalcDurationMs": 11.763000000000003,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 562.07,
"heapDeltaBytes": 4673008,
"heapUsedBytes": 55503084,
"domNodes": -256,
"jsHeapTotalBytes": 15929344,
"scriptDurationMs": 103.02100000000002,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-idle",
"durationMs": 2033.9079999999967,
"styleRecalcs": 11,
"styleRecalcDurationMs": 10.979000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 553.508,
"heapDeltaBytes": 4414940,
"heapUsedBytes": 54802240,
"domNodes": -255,
"jsHeapTotalBytes": 16191488,
"scriptDurationMs": 102.522,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-pan",
"durationMs": 2143.688000000054,
"styleRecalcs": 68,
"styleRecalcDurationMs": 15.38,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1110.8020000000001,
"heapDeltaBytes": 14866732,
"heapUsedBytes": 68238756,
"domNodes": -262,
"jsHeapTotalBytes": 18755584,
"scriptDurationMs": 399.48300000000006,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-pan",
"durationMs": 2156.177000000014,
"styleRecalcs": 69,
"styleRecalcDurationMs": 16.352,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1126.356,
"heapDeltaBytes": 15380012,
"heapUsedBytes": 68320532,
"domNodes": -259,
"jsHeapTotalBytes": 19804160,
"scriptDurationMs": 404.831,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-pan",
"durationMs": 2174.841000000015,
"styleRecalcs": 69,
"styleRecalcDurationMs": 15.795,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1205.045,
"heapDeltaBytes": 20893420,
"heapUsedBytes": 74157940,
"domNodes": -262,
"jsHeapTotalBytes": 17444864,
"scriptDurationMs": 445.949,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-zoom",
"durationMs": 3175.5810000000224,
"styleRecalcs": 67,
"styleRecalcDurationMs": 17.844,
"layouts": 60,
"layoutDurationMs": 7.545999999999999,
"taskDurationMs": 1319.12,
"heapDeltaBytes": 11468160,
"heapUsedBytes": 66784768,
"domNodes": -259,
"jsHeapTotalBytes": 18083840,
"scriptDurationMs": 488.40199999999993,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-zoom",
"durationMs": 3166.825000000017,
"styleRecalcs": 65,
"styleRecalcDurationMs": 17.166,
"layouts": 60,
"layoutDurationMs": 7.582,
"taskDurationMs": 1345.358,
"heapDeltaBytes": 9057104,
"heapUsedBytes": 64238204,
"domNodes": -267,
"jsHeapTotalBytes": 15667200,
"scriptDurationMs": 498.4,
"eventListeners": -123,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-zoom",
"durationMs": 3127.157000000011,
"styleRecalcs": 67,
"styleRecalcDurationMs": 18.735,
"layouts": 60,
"layoutDurationMs": 7.561,
"taskDurationMs": 1338.7279999999998,
"heapDeltaBytes": 4107936,
"heapUsedBytes": 58396800,
"domNodes": -262,
"jsHeapTotalBytes": 17240064,
"scriptDurationMs": 497.13,
"eventListeners": -123,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "minimap-idle",
"durationMs": 2016.854999999964,
"styleRecalcs": 7,
"styleRecalcDurationMs": 8.28,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 566.7930000000001,
"heapDeltaBytes": 17183192,
"heapUsedBytes": 72418992,
"domNodes": -264,
"jsHeapTotalBytes": 15462400,
"scriptDurationMs": 102.408,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "minimap-idle",
"durationMs": 2024.4120000000407,
"styleRecalcs": 9,
"styleRecalcDurationMs": 9.482999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 545.0999999999999,
"heapDeltaBytes": 4606832,
"heapUsedBytes": 56751752,
"domNodes": -261,
"jsHeapTotalBytes": 15142912,
"scriptDurationMs": 101.77099999999999,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "minimap-idle",
"durationMs": 2017.2109999999748,
"styleRecalcs": 10,
"styleRecalcDurationMs": 11.164,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 569.428,
"heapDeltaBytes": 17809656,
"heapUsedBytes": 71528676,
"domNodes": -257,
"jsHeapTotalBytes": 14151680,
"scriptDurationMs": 102.61000000000001,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 573.6190000000079,
"styleRecalcs": 47,
"styleRecalcDurationMs": 11.484,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 372.60200000000003,
"heapDeltaBytes": 6153092,
"heapUsedBytes": 49178328,
"domNodes": 20,
"jsHeapTotalBytes": 13893632,
"scriptDurationMs": 137.875,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 532.7340000000049,
"styleRecalcs": 47,
"styleRecalcDurationMs": 11.738000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 365.59999999999997,
"heapDeltaBytes": 6173092,
"heapUsedBytes": 49253200,
"domNodes": 20,
"jsHeapTotalBytes": 13893632,
"scriptDurationMs": 125.91,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 558.4139999999707,
"styleRecalcs": 48,
"styleRecalcDurationMs": 12.624999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 360.36100000000005,
"heapDeltaBytes": 6525680,
"heapUsedBytes": 49514124,
"domNodes": 22,
"jsHeapTotalBytes": 13369344,
"scriptDurationMs": 123.166,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.663333333333338,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "subgraph-idle",
"durationMs": 1992.0900000000188,
"styleRecalcs": 11,
"styleRecalcDurationMs": 10.628000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 367.446,
"heapDeltaBytes": 19913676,
"heapUsedBytes": 62896928,
"domNodes": 22,
"jsHeapTotalBytes": 22806528,
"scriptDurationMs": 21.63,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-idle",
"durationMs": 2015.903000000037,
"styleRecalcs": 10,
"styleRecalcDurationMs": 9.447000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 378.04299999999995,
"heapDeltaBytes": 11288492,
"heapUsedBytes": 62994424,
"domNodes": 20,
"jsHeapTotalBytes": 26476544,
"scriptDurationMs": 21.387999999999998,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-idle",
"durationMs": 2011.8499999999813,
"styleRecalcs": 11,
"styleRecalcDurationMs": 10.649000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 343.493,
"heapDeltaBytes": 19935788,
"heapUsedBytes": 62934748,
"domNodes": 21,
"jsHeapTotalBytes": 22544384,
"scriptDurationMs": 17.56,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1969.1819999999893,
"styleRecalcs": 83,
"styleRecalcDurationMs": 46.933,
"layouts": 16,
"layoutDurationMs": 4.776000000000001,
"taskDurationMs": 941.453,
"heapDeltaBytes": 11902752,
"heapUsedBytes": 54913204,
"domNodes": 71,
"jsHeapTotalBytes": 22806528,
"scriptDurationMs": 109.21000000000002,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1990.4439999999681,
"styleRecalcs": 88,
"styleRecalcDurationMs": 54.562999999999995,
"layouts": 16,
"layoutDurationMs": 4.7749999999999995,
"taskDurationMs": 945.0679999999999,
"heapDeltaBytes": 11829388,
"heapUsedBytes": 55011476,
"domNodes": 75,
"jsHeapTotalBytes": 22544384,
"scriptDurationMs": 104.20400000000001,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1679.6709999999848,
"styleRecalcs": 75,
"styleRecalcDurationMs": 34.872,
"layouts": 16,
"layoutDurationMs": 4.4159999999999995,
"taskDurationMs": 662.6260000000001,
"heapDeltaBytes": 11513428,
"heapUsedBytes": 54496376,
"domNodes": 61,
"jsHeapTotalBytes": 23330816,
"scriptDurationMs": 98.981,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "viewport-pan-sweep",
"durationMs": 8241.211000000021,
"styleRecalcs": 251,
"styleRecalcDurationMs": 46.238,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 4024.5060000000008,
"heapDeltaBytes": 29084760,
"heapUsedBytes": 79786348,
"domNodes": -259,
"jsHeapTotalBytes": 21377024,
"scriptDurationMs": 1399.2839999999999,
"eventListeners": -111,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8151.135999999951,
"styleRecalcs": 250,
"styleRecalcDurationMs": 45.50600000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3825.135,
"heapDeltaBytes": 23293660,
"heapUsedBytes": 73522232,
"domNodes": -255,
"jsHeapTotalBytes": 20328448,
"scriptDurationMs": 1294.3600000000001,
"eventListeners": -107,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.80000000000109
},
{
"name": "viewport-pan-sweep",
"durationMs": 8206.699000000071,
"styleRecalcs": 251,
"styleRecalcDurationMs": 46.892,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3800.2560000000003,
"heapDeltaBytes": -8157376,
"heapUsedBytes": 52234236,
"domNodes": -259,
"jsHeapTotalBytes": 20762624,
"scriptDurationMs": 1298.4750000000001,
"eventListeners": -113,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-idle",
"durationMs": 12450.331999999946,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 12437.088000000002,
"heapDeltaBytes": -30863408,
"heapUsedBytes": 165745928,
"domNodes": -8331,
"jsHeapTotalBytes": 27877376,
"scriptDurationMs": 600.878,
"eventListeners": -16466,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.223333333333358,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-idle",
"durationMs": 12771.142999999995,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 12749.226999999997,
"heapDeltaBytes": -34900188,
"heapUsedBytes": 165882632,
"domNodes": -8331,
"jsHeapTotalBytes": 28139520,
"scriptDurationMs": 631.124,
"eventListeners": -16462,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.773333333333238,
"p95FrameDurationMs": 16.80000000000291
},
{
"name": "vue-large-graph-idle",
"durationMs": 12305.689999999913,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 12293.472,
"heapDeltaBytes": -44337712,
"heapUsedBytes": 165613408,
"domNodes": -8331,
"jsHeapTotalBytes": 27615232,
"scriptDurationMs": 590.0930000000001,
"eventListeners": -16462,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.220000000000073,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 14566.743999999971,
"styleRecalcs": 68,
"styleRecalcDurationMs": 14.620000000000022,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 14539.557,
"heapDeltaBytes": -65314132,
"heapUsedBytes": 147831288,
"domNodes": -8331,
"jsHeapTotalBytes": -172032,
"scriptDurationMs": 880.4190000000001,
"eventListeners": -16488,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.219999999999953,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 14390.137999999979,
"styleRecalcs": 68,
"styleRecalcDurationMs": 14.560000000000016,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 14367.654000000002,
"heapDeltaBytes": -36090272,
"heapUsedBytes": 172203044,
"domNodes": -8331,
"jsHeapTotalBytes": 25432064,
"scriptDurationMs": 873.6320000000001,
"eventListeners": -16462,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.219999999999953,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-pan",
"durationMs": 14652.395999999953,
"styleRecalcs": 68,
"styleRecalcDurationMs": 15.454000000000024,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 14628.614999999998,
"heapDeltaBytes": -22207000,
"heapUsedBytes": 172246584,
"domNodes": -8331,
"jsHeapTotalBytes": 24907776,
"scriptDurationMs": 898.3670000000001,
"eventListeners": -16462,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.780000000000047,
"p95FrameDurationMs": 33.39999999999782
},
{
"name": "workflow-execution",
"durationMs": 470.12300000000096,
"styleRecalcs": 24,
"styleRecalcDurationMs": 28.298000000000002,
"layouts": 5,
"layoutDurationMs": 1.4569999999999999,
"taskDurationMs": 140.69099999999997,
"heapDeltaBytes": 4738704,
"heapUsedBytes": 48307164,
"domNodes": 193,
"jsHeapTotalBytes": 262144,
"scriptDurationMs": 29.577999999999996,
"eventListeners": 71,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "workflow-execution",
"durationMs": 456.0040000000072,
"styleRecalcs": 19,
"styleRecalcDurationMs": 23.453,
"layouts": 4,
"layoutDurationMs": 1.1060000000000003,
"taskDurationMs": 119.03199999999997,
"heapDeltaBytes": 4379592,
"heapUsedBytes": 48424300,
"domNodes": 159,
"jsHeapTotalBytes": 0,
"scriptDurationMs": 25.221999999999994,
"eventListeners": 71,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.663333333333338,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "workflow-execution",
"durationMs": 465.5920000000151,
"styleRecalcs": 17,
"styleRecalcDurationMs": 21.972000000000005,
"layouts": 5,
"layoutDurationMs": 1.379,
"taskDurationMs": 122.53400000000002,
"heapDeltaBytes": 4490960,
"heapUsedBytes": 49027016,
"domNodes": 158,
"jsHeapTotalBytes": 262144,
"scriptDurationMs": 29.935999999999996,
"eventListeners": 71,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.663333333333338,
"p95FrameDurationMs": 16.700000000000273
}
]
} |
christian-byrne
left a comment
There was a problem hiding this comment.
Is there no types in ingest-types that we can use instead of the outdated/deprecated apiSchema.ts?
|
Re: the review comment about using The Since the cloud ingest API is supposed to mirror the ComfyUI backend, #10697 removes those exclusion filters so the types get generated. Plan:
|
| // Intercept the object_info API call | ||
| await page.route('**/api/object_info', (route) => | ||
| route.fulfill({ json: mockNodeDefinitions }) | ||
| ) | ||
|
|
||
| // Intercept the system_stats API call | ||
| await page.route('**/api/system_stats', (route) => | ||
| route.fulfill({ json: mockSystemStats }) | ||
| ) | ||
| ``` |
There was a problem hiding this comment.
note: comfyPageFixture navigates before test body, so this might need some updating
There was a problem hiding this comment.
good call - the README now documents that route handlers must be registered before navigating to the page, which covers the timing concern. the fixtures themselves are just data, so the navigation ordering is handled at the fixture/test level.
|
|
||
| export const mockSystemStats: SystemStats = { | ||
| system: { | ||
| os: 'posix', |
There was a problem hiding this comment.
note: systemStore interestingly does not detect posix, I was just curious because the values were a bit old (version warning), but there isn't too much value in fixing it.
There was a problem hiding this comment.
note: yeah the os value is just a placeholder for the mock - systemStore does not branch on it so any string works here. the type now comes from @comfyorg/ingest-types (SystemStatsResponse) so it will stay in sync with the backend schema.
There was a problem hiding this comment.
the direction is good, but right now this file can only be used on certain tests that work around these three nodes, the base default workflow would node def error because only half of the default ones are defined here, and tests can't customize/extend this as-is, maybe a factory for per-test customization pattern or something similar? wdyt?
|
Checked |
f213c80 to
5efcd94
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@browser_tests/fixtures/data/nodeDefinitions.ts`:
- Around line 150-156: mockNodeDefinitions currently exposes the mutable
baseNodeDefinitions by reference and createMockNodeDefinitions performs only a
shallow merge, risking cross-test state leakage when tests mutate nested fields;
change createMockNodeDefinitions to return a deep-cloned copy of
baseNodeDefinitions merged with overrides (e.g., deep clone baseNodeDefinitions
then apply overrides deeply) and replace mockNodeDefinitions with a function or
constant that also returns a deep clone rather than the original object, and
move the helper logic (createMockNodeDefinitions or any cloning utilities) out
of fixtures/data into fixtures/utils so fixtures/data remains static test data
only.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e2f90fa2-f319-498b-9f27-4cf3888a5cbd
📒 Files selected for processing (3)
browser_tests/fixtures/data/README.mdbrowser_tests/fixtures/data/nodeDefinitions.tsbrowser_tests/fixtures/data/systemStats.ts
✅ Files skipped from review due to trivial changes (1)
- browser_tests/fixtures/data/README.md
| } | ||
| } | ||
|
|
||
| export function createMockNodeDefinitions( |
There was a problem hiding this comment.
Feel like this can be confuse consumer which one should be use among mockNodeDefinitions andcreateMockNodeDefinitions. why don't we export single factory function and set createMockNodeDefinitions() as default
There was a problem hiding this comment.
fixed in 524c61f - removed the mutable mockNodeDefinitions export, now only exports createMockNodeDefinitions() which returns a structuredClone'd copy each time.
| @@ -0,0 +1,25 @@ | |||
| import type { SystemStats } from '@/schemas/apiSchema' | |||
There was a problem hiding this comment.
nit: SystemStats is imported from @/schemas/apiSchema which is on the deprecation path — Christian mentioned switching to generated types after #10697 lands. Might be worth noting as a follow-up.
| experimental: false | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
non-blocking: These fixtures aren't validated against the Zod schemas they claim to conform to. If ComfyNodeDef or SystemStats schemas change, the fixtures will silently drift. A simple parse test would catch that:
import { zComfyNodeDef } from '@/schemas/nodeDefSchema'
import { mockNodeDefinitions } from './nodeDefinitions'
it('fixtures conform to schema', () => {
Object.values(mockNodeDefinitions).forEach((def) =>
expect(() => zComfyNodeDef.parse(def)).not.toThrow()
)
}) There was a problem hiding this comment.
good idea - keeping this out of scope for this PR but worth tracking.
@coderabbitai Make an Issue to add schema validation tests for mock fixtures (parse fixtures against their Zod schemas to catch drift) in a followup PR on a future date
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
gh issue create \
--repo Comfy-Org/ComfyUI_frontend \
--title "test: add Zod schema validation tests for mock data fixtures to catch drift" \
--assignee christian-byrne \
--body "## Summary
Mock data fixtures in \`browser_tests/fixtures/data/\` (e.g., \`nodeDefinitions.ts\`, \`systemStats.ts\`) are typed against Zod schemas but are not validated at test time. If \`ComfyNodeDef\`, \`SystemStats\`, or any other schema changes, the fixtures can silently drift without any test failure.
## Proposed Fix
Add a Vitest unit test that parses each fixture against its corresponding Zod schema to ensure conformance:
\`\`\`ts
import { zComfyNodeDef } from '@/schemas/nodeDefSchema'
import { mockNodeDefinitions } from 'browser_tests/fixtures/data/nodeDefinitions'
it('fixtures conform to schema', () => {
Object.values(mockNodeDefinitions).forEach((def) =>
expect(() => zComfyNodeDef.parse(def)).not.toThrow()
)
})
\`\`\`
Similarly for \`mockSystemStats\` against the \`SystemStats\` Zod schema in \`src/schemas/apiSchema.ts\`.
## Context
- Raised during review of PR `#10662` (add mock data fixtures for backend API responses)
- Review comment: https://github.com/Comfy-Org/ComfyUI_frontend/pull/10662#discussion_r3005808060
- Originally suggested by `@dante01yoon`; deferred out of scope by `@christian-byrne` for a follow-up PR."
Length of output: 58
@christian-byrne, done! I've opened #10707 to track adding Zod schema validation tests for the mock data fixtures. It covers both mockNodeDefinitions (against zComfyNodeDef) and mockSystemStats (against the SystemStats schema), and links back to this PR and the original review comment from @dante01yoon.
🧠 Learnings used
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/AGENTS.md:0-0
Timestamp: 2026-03-29T06:11:58.061Z
Learning: Applies to browser_tests/fixtures/data/** : Place static test data (JSON workflows, mock API responses, node definitions) in `fixtures/data/` with no code or Playwright imports
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/AGENTS.md:0-0
Timestamp: 2026-02-03T20:33:39.759Z
Learning: Applies to browser_tests/**/*.spec.ts : Use premade JSON workflows in the `assets/` directory to load desired graph state in E2E tests
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 10548
File: browser_tests/tests/propertiesPanel/propertiesPanel.spec.ts:57-66
Timestamp: 2026-03-27T05:12:28.417Z
Learning: In Comfy-Org/ComfyUI_frontend browser tests for the properties panel (`browser_tests/tests/propertiesPanel/propertiesPanel.spec.ts`), do not assert that the rendered node-entry count in the Nodes tab matches `comfyPage.nodeOps.getNodeCount()`. The default workflow composition can change, making count-based assertions fragile. Prefer asserting that a known node (e.g., 'KSampler') is visible. For filter assertions, asserting the matching entry is visible is sufficient; a non-match disappearing assertion is deferred to a future iteration.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:22.621Z
Learning: In the Comfy-Org/ComfyUI_frontend repository test files: When testing components, import the real type definitions from the component files instead of duplicating interface definitions in the test files. This prevents type drift and maintains consistency.
Learnt from: viva-jinyi
Repo: Comfy-Org/ComfyUI_frontend PR: 9697
File: src/workbench/extensions/manager/composables/nodePack/useWorkflowPacks.ts:128-147
Timestamp: 2026-03-10T12:27:48.561Z
Learning: In Comfy-Org/ComfyUI_frontend, `nodeDefStore.nodeDefsByName` is guaranteed to be fully populated before any manager component (e.g., those using `useWorkflowPacks`, `useMissingNodes`) can execute. The initialization chain is: `comfyApp.setup()` awaits `registerNodes()` → `updateVueAppNodeDefs()` → populates `nodeDefsByName`, and `comfyAppReady` is set to true only after `setup()` completes. All manager/workflow-pack components are gated behind `v-if="comfyAppReady"`. Do not flag `nodeDefsByName` access as a potential timing/hydration race condition in these composables.
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: :0-0
Timestamp: 2026-03-27T05:26:01.429Z
Learning: In Comfy-Org/ComfyUI_frontend PR `#10526`, the async scope-disposal race in `src/platform/cloud/notification/components/DesktopCloudNotificationController.vue` (desktop/mac-only cloud promo flow) is intentionally covered only at the unit level via `DesktopCloudNotificationController.test.ts`, using a deferred `settingStore.load()` promise and fake timers to deterministically verify that the dialog is not scheduled or shown after the owning scope is disposed. A Playwright E2E test is not appropriate here because: (1) the non-deterministic ordering cannot be reliably reproduced in Playwright, (2) the feature requires a real macOS Electron environment not available in CI, and (3) a timing-driven pseudo-E2E would be flaky and weaker than the unit test. If broader coverage is needed later, the right approach is a separate desktop promo smoke test, not a race-specific E2E regression. Do not request a Playwright/E2E test for this specific race condition scenario.
Learnt from: pythongosssss
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: :0-0
Timestamp: 2026-03-18T15:38:16.169Z
Learning: In Comfy-Org/ComfyUI_frontend, race conditions between WebSocket events and HTTP responses (e.g., the WebSocket/HTTP race in job tracking in `src/renderer/extensions/linearMode/linearOutputStore.ts`) are not suitable candidates for E2E testing because the non-deterministic ordering cannot be reliably reproduced in Playwright. Unit tests (e.g., in `linearOutputStore.test.ts`) that deterministically simulate event ordering are the correct approach. Do not request E2E tests for such race condition scenarios.
Learnt from: jaeone94
Repo: Comfy-Org/ComfyUI_frontend PR: 10309
File: browser_tests/tests/missingMedia.spec.ts:141-145
Timestamp: 2026-03-25T15:30:09.361Z
Learning: In `browser_tests/tests/missingMedia.spec.ts` (Comfy-Org/ComfyUI_frontend PR `#10309`), the library-select E2E test uses `test.skip()` when no options are found because the OSS test server's input directory content varies per environment and cannot be guaranteed to contain specific library items. The upload flow test already covers the full 2-step confirm path. Do not flag this `test.skip()` guard as a regression risk or suggest pre-uploading files (which creates inter-test dependency). If deterministic coverage is needed in the future, suggest mocking the input-file list endpoint via Playwright's `page.route()` instead.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7746
File: src/platform/assets/services/assetService.ts:484-491
Timestamp: 2026-01-06T19:20:56.167Z
Learning: In `src/platform/assets/services/assetService.ts`, prefer using `schema.safeParse()` over `schema.parse()` for validating API responses to avoid throwing ZodError with internal schema details; follow the existing pattern: call `safeParse()`, check `result.success`, and use `fromZodError(result.error)` to format error messages for logging while throwing user-friendly errors.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-29T06:46:23.496Z
Learning: Applies to **/*.test.ts : Do not write tests that just test the mocks in Vitest; ensure tests fail when the code behaves unexpectedly
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 10547
File: browser_tests/tests/workflowPersistence.spec.ts:459-471
Timestamp: 2026-03-27T05:12:16.400Z
Learning: In `browser_tests/tests/workflowPersistence.spec.ts` (Comfy-Org/ComfyUI_frontend PR `#10547`), the G10 test for PR `#8715` (transient blob:/api-view URL serialization) intentionally validates only the static/default workflow export — not an executed/transient widget state. Putting an image widget into its executed state requires actual model inference (image output generation), which is not available in the current E2E test infrastructure. The test still covers the regression if the `widget.serialize` disable path breaks. Do not flag the absence of transient-state setup in this test; full integration coverage is tracked separately.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-29T06:46:23.496Z
Learning: Applies to **/*.{test,spec}.ts : Do not mock what you don't own in tests
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 10140
File: apps/website/package.json:1-79
Timestamp: 2026-03-17T07:28:27.677Z
Learning: In Comfy-Org/ComfyUI_frontend, the narrow-scope learning (PRs should stay focused on the stated fix) applies to bug-fix PRs. It does not apply to intentional feature scaffold PRs that are part of a stacked PR series (e.g., [1/3], [2/3], [3/3] in the PR title managed via Graphite).
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 10694
File: tools/test-recorder/tsconfig.json:4-12
Timestamp: 2026-03-29T02:02:58.418Z
Learning: In Comfy-Org/ComfyUI_frontend, the `comfy-test` CLI in `tools/test-recorder/` is invoked via `tsx` (root `package.json` script: `tsx tools/test-recorder/src/index.ts`), not by running compiled `dist/index.js` with bare Node. Therefore `moduleResolution: "bundler"` in `tools/test-recorder/tsconfig.json` is correct and extensionless relative imports work fine at runtime. Do not flag this as a Node ESM incompatibility.
Learnt from: dante01yoon
Repo: Comfy-Org/ComfyUI_frontend PR: 10580
File: browser_tests/tests/sidebar/textSizeRename.spec.ts:20-20
Timestamp: 2026-03-27T13:58:48.000Z
Learning: In Comfy-Org/ComfyUI_frontend browser tests, `node-tree-leaf` is NOT defined in `TestIds` (`browser_tests/fixtures/selectors.ts`). Using the raw string `'node-tree-leaf'` with `getByTestId('node-tree-leaf')` in spec files (e.g., `browser_tests/tests/sidebar/textSizeRename.spec.ts`) is correct and intentional. Do not flag this as a violation of the centralized TestIds guideline.
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 10548
File: browser_tests/tests/propertiesPanel/propertiesPanel.spec.ts:361-367
Timestamp: 2026-03-27T05:12:28.706Z
Learning: In `browser_tests/tests/propertiesPanel/propertiesPanel.spec.ts` (Comfy-Org/ComfyUI_frontend), the Info tab test uses the regex `/Description|Inputs|Outputs/i` intentionally. NodeHelpContent sections rendered depend on the node type and available documentation; not every node has all three sections. The assertion is meant to verify that at least one info section renders, not that all three are present. Do not suggest splitting this into separate per-section assertions, as that would be brittle to node documentation differences.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/AGENTS.md:0-0
Timestamp: 2026-02-23T00:41:09.436Z
Learning: Applies to src/lib/litegraph/**/*.test.{ts,tsx} : Use test helper functions `createTestSubgraph()` and `createTestSubgraphNode()` from `./__fixtures__/subgraphHelpers` when setting up subgraph tests
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-03-29T04:06:22.754Z
Learning: Applies to {src/lib/litegraph/**,src/ecs/**}/*.{ts,tsx,js} : ADR compliance for entity/litegraph changes: Flag changes to extension-facing callbacks (onConnectionsChange, onRemoved, onAdded, onConfigure, onConnectInput/Output, onWidgetChanged), node.widgets access, node.serialize overrides, or graph._version++ without migration guidance. These affect 40+ custom node repos.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-29T06:46:23.496Z
Learning: Applies to **/*.test.ts : Leverage Vitest's utilities for mocking where possible
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-29T06:46:23.496Z
Learning: Applies to browser_tests/**/*.spec.ts : Type all API mock responses in Playwright `route.fulfill()` using generated types or schemas
Learnt from: jaeone94
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: :0-0
Timestamp: 2026-03-18T03:20:24.898Z
Learning: In Comfy-Org/ComfyUI_frontend PR `#10228`, E2E testing for the `toBrowsableUrl` clipboard copy behavior in `MissingModelRow.vue` is not practical because: (1) the Copy Url button is only visible under `!isCloud && model.representative.url && !isAssetSupported`, requiring a special fixture with a real HuggingFace/Civitai URL and local node definitions that mark the model unsupported; (2) `clipboard-read` permission must be explicitly granted in Playwright; (3) there are no existing clipboard E2E test patterns in the codebase. The pure function `toBrowsableUrl` is fully covered by unit tests instead. Do not request an E2E test for this clipboard URL-conversion feature.
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 10140
File: apps/website/package.json:1-79
Timestamp: 2026-03-17T07:28:27.677Z
Learning: In Comfy-Org/ComfyUI_frontend, PRs managed via Graphite stacked sets (using `gt split`) may show browser_tests/ files in the diff as artifacts of the split process. These files contain no actual changes relative to origin/main and should not be flagged as unrelated scope changes. Verify against the PR title/description stacking context before raising scope concerns.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-03-24T17:16:12.386Z
Learning: For bug-fix PRs, ensure end-to-end regression coverage by either: (1) changing at least one file under `browser_tests/`, or (2) providing a concrete, non-placeholder explanation in the PR description of why an end-to-end regression test was not added. Use only PR metadata available in the review context (PR title, commit subjects, files changed relative to base, PR description). Do not rely on shell commands or inspect files outside the PR.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-03-29T04:06:22.754Z
Learning: End-to-end regression coverage for fixes: For bug-fix PRs (identified by bug-fix language in title or commit subjects like 'fix', 'fixed', 'fixes', 'bugfix', 'hotfix'), ensure at least one of the following: changes to browser_tests/ files, or a concrete explanation in the PR description of why an end-to-end regression test is not practical.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2026-03-27T04:23:01.330Z
Learning: End-to-end regression coverage for fixes: For PRs that include bug-fix language in the title or commit subjects (fix, fixed, fixes, fixing, bugfix, hotfix), ensure at least one of the following: (1) files are changed under browser_tests/, or (2) the PR description includes a concrete, non-placeholder explanation of why an end-to-end regression test was not added. Only use PR metadata available in the review context (PR title, commit subjects, files changed relative to base, PR description). Do not rely on shell commands, reverse diffs, or files outside the PR.
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.
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.
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.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 8248
File: src/platform/assets/schemas/assetSchema.ts:109-118
Timestamp: 2026-01-22T23:44:59.888Z
Learning: Do not export declarations (e.g., schemas, constants, types) unless they are actually used elsewhere in the codebase. Keep the public API surface minimal by exporting only items with concrete usage. This reduces coupling and keeps imports explicit. In src/platform/assets/schemas/assetSchema.ts, ensure only necessary exports are exposed; remove unused exports or switch to non-exported/internal where appropriate.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 8722
File: src/composables/maskeditor/useBrushDrawing.ts:5-5
Timestamp: 2026-02-08T03:19:12.009Z
Learning: Treat unresolved import warnings caused by pnpm workspace catalog mappings (pnpm-workspace.yaml) and unplugin-typegpu in vite.config.mts as false positives. Do not flag these in PR reviews; they are expected in sandboxes without node_modules and are not indicative of actual missing dependencies in the TS codebase.
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 8966
File: src/extensions/core/load3d.ts:427-430
Timestamp: 2026-02-19T02:06:23.468Z
Learning: In TypeScript, you can use typeof SomeClass in type annotation positions (e.g., param: typeof LGraphNode) even when SomeClass is imported with import type. This is a type query that only exists at compile time and is erased in runtime, so it is safe to combine with type-only imports. Apply this pattern to TS files broadly when you need a type that references the shape of a class or constructor function without importing the value at runtime.
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 8966
File: src/extensions/core/uploadAudio.ts:91-94
Timestamp: 2026-02-19T02:06:38.395Z
Learning: In TypeScript files, you can use a type annotation like 'nodeType: typeof MyClass' even if MyClass is imported via 'import type'. Both the type-only import and 'typeof' operate at the type level and are erased at compile time. This pattern is commonly used for constructor types (e.g., 'nodeType: typeof LGraphNode'). Apply this pattern across TypeScript files in the repository (src/**/*.ts) as appropriate, ensuring the imported symbol is a type-only import when possible for clarity and to avoid runtime imports.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 8992
File: src/lib/litegraph/src/widgets/GradientSliderWidget.ts:18-18
Timestamp: 2026-02-20T21:08:19.814Z
Learning: When drawing with CanvasRenderingContext2D in TypeScript/JavaScript, wrap the drawing logic with ctx.save() at the start and ctx.restore() at the end to preserve and restore the canvas state. Do not manually destructure and restore individual properties (e.g., fillStyle, strokeStyle); rely on save/restore to manage state changes in a scoped manner. This should be applied to all TS files that perform canvas drawing.
Learnt from: dante01yoon
Repo: Comfy-Org/ComfyUI_frontend PR: 9075
File: src/scripts/api.featureFlags.test.ts:237-268
Timestamp: 2026-02-22T04:27:33.379Z
Learning: In Vite/Vitest, import.meta.env.DEV is true for any mode that is not 'production' (i.e., DEV is the opposite of PROD, and can be true in 'test', 'development', etc.). Do not assume DEV implies only 'development' mode. When reviewing code and tests, treat DEV as a non-production flag and verify environment-specific logic accordingly. Reference: https://vite.dev/guide/env-and-mode#modes
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 9427
File: src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuFilter.vue:33-33
Timestamp: 2026-03-06T00:53:28.835Z
Learning: When reviewing code, note that the enforce-canonical-classes (better-tailwindcss) rule may auto-fix Tailwind v3 !class-name syntax by converting it to v4 class-name! syntax. Do not treat these auto-fixed class-name! instances as newly introduced issues; the perceived change is in syntax placement, not in usage or intent. This guidance applies across all .vue and .ts files in the repository.
Learnt from: sonnybox
Repo: Comfy-Org/ComfyUI_frontend PR: 9446
File: src/renderer/extensions/vueNodes/widgets/components/WidgetTextarea.vue:45-45
Timestamp: 2026-03-06T01:55:00.013Z
Learning: Treat wrap-break-word as a valid Tailwind CSS utility for overflow-wrap: break-word in Tailwind v4+ projects. Do not flag this class as invalid in any Vue (.vue) or TypeScript (.ts/.tsx) files within the repository (e.g., Comfy-Org/ComfyUI_frontend) or other Tailwind v4+ projects. When reviewing, verify that the class is used to enable word breaking in long text content and reference the Tailwind docs: https://tailwindcss.com/docs/overflow-wrap.
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 9554
File: browser_tests/fixtures/ComfyPage.ts:189-193
Timestamp: 2026-03-12T10:03:55.383Z
Learning: In browser_tests, seed localStorage-based feature flags at init time using FeatureFlagHelper.seedFlags() (which uses page.addInitScript) before any navigation. Ensure this happens before comfyPage.setup() is called. The comfyPageFixture currently yields after calling comfyPage.setup(), so do not defer setup() from the fixture or add a pre-setup hook, as changing this would break existing tests.
Learnt from: Yourz
Repo: Comfy-Org/ComfyUI_frontend PR: 10310
File: browser_tests/tests/topbarMenuDismissal.spec.ts:0-0
Timestamp: 2026-03-19T16:16:40.350Z
Learning: In Comfy-Org/ComfyUI_frontend, when reviewing changes limited to adding/revising `:modal="false"` (or similar modal/non-modal behavior props) on reakit-ui/reka-ui primitives such as `ContextMenuRoot` and `DropdownMenuRoot`, do not request Playwright/E2E regression coverage solely for that prop-level change. The dismissal behavior for modal vs non-modal is documented and tested upstream in the reka-ui library; only ask for E2E tests when the change affects ComfyUI_frontend behavior beyond these primitive prop wiring differences (e.g., custom logic, integration behavior, or new user flows not covered upstream).
…10697) ## Summary Remove the exclusion filter that prevented backend-mirrored endpoint types from being generated in `@comfyorg/ingest-types`. ## Changes - **What**: The `openapi-ts.config.ts` excluded all endpoints shared with the ComfyUI Python backend (system_stats, object_info, prompt, queue, history, settings, userdata, etc.). Since the cloud ingest API mirrors the backend, these types should be generated from the OpenAPI spec as the canonical source. This adds ~250 new types and Zod schemas covering previously excluded endpoints. - **Breaking**: None. This only adds new exported types — no existing types or imports are changed. ## Review Focus - The cloud ingest API is designed to mirror the ComfyUI Python backend. The original exclusion filter was added to avoid duplication with `src/schemas/apiSchema.ts`, but the generated types should be the canonical source since they are auto-generated from the OpenAPI spec. - A follow-up PR will migrate imports in `src/` from `apiSchema.ts` to `@comfyorg/ingest-types` where applicable. - Webhooks and internal analytics endpoints remain excluded (server-to-server, not frontend-relevant). Related: #10662 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-10697-refactor-include-backend-mirrored-endpoints-in-ingest-types-codegen-3326d73d365081569614f743ab6f074d) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.com>
Add deterministic mock data fixtures for browser tests to decouple them from backend changes: - nodeDefinitions.ts: KSampler, CheckpointLoaderSimple, CLIPTextEncode - systemStats.ts: realistic GPU info matching SystemStats schema - README.md: usage guide for page.route() interception
…ixtures Address review feedback: - Add createMockNodeDefinitions() factory for per-test customization - Add EmptyLatentImage, VAEDecode, SaveImage to cover full default workflow - Update README to note comfyPageFixture navigation timing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Addresses review feedback: #10662 (comment)
Consolidates to single createMockNodeDefinitions factory function with deep clone to prevent cross-test state leakage. Addresses review feedback: #10662 (comment) #10662 (comment)
87119ab to
524c61f
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
browser_tests/fixtures/data/nodeDefinitions.ts (1)
150-155: 🛠️ Refactor suggestion | 🟠 MajorMove factory logic out of
fixtures/data(data-only directory).
createMockNodeDefinitionsis executable helper logic in a folder reserved for static fixture data. Please move this factory tobrowser_tests/fixtures/utils/(or another helper module) and keep this file as data-only exports.As per coding guidelines,
browser_tests/fixtures/data/**must “Place static test data (JSON workflows, mock API responses, node definitions) infixtures/data/with no code or Playwright imports”. Based on learnings, pure utility functions with noPagedependency should live inbrowser_tests/fixtures/utils/**.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_tests/fixtures/data/nodeDefinitions.ts` around lines 150 - 155, Move the executable factory createMockNodeDefinitions out of the data-only directory and into a utility module under browser_tests/fixtures/utils/; specifically, create a new helper file (e.g., nodeDefinitionsFactory.ts) that imports baseNodeDefinitions and exports createMockNodeDefinitions, then update any imports in tests to reference the new utils module and leave the original nodeDefinitions.ts containing only the static baseNodeDefinitions export (no functions) so browser_tests/fixtures/data/** remains data-only.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@browser_tests/fixtures/data/nodeDefinitions.ts`:
- Around line 150-155: Move the executable factory createMockNodeDefinitions out
of the data-only directory and into a utility module under
browser_tests/fixtures/utils/; specifically, create a new helper file (e.g.,
nodeDefinitionsFactory.ts) that imports baseNodeDefinitions and exports
createMockNodeDefinitions, then update any imports in tests to reference the new
utils module and leave the original nodeDefinitions.ts containing only the
static baseNodeDefinitions export (no functions) so
browser_tests/fixtures/data/** remains data-only.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 8f40e71e-1f2d-4dec-86ad-bc323b54e5af
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (4)
browser_tests/fixtures/data/README.mdbrowser_tests/fixtures/data/nodeDefinitions.tsbrowser_tests/fixtures/data/systemStats.tspackage.json
✅ Files skipped from review due to trivial changes (2)
- package.json
- browser_tests/fixtures/data/README.md
Summary
Add deterministic mock data fixtures for browser tests so they can use
page.route()to intercept API calls without depending on a live backend.Changes
browser_tests/fixtures/data/nodeDefinitions.ts— MockComfyNodeDefobjects for KSampler, CheckpointLoaderSimple, and CLIPTextEncodebrowser_tests/fixtures/data/systemStats.ts— MockSystemStatswith realistic RTX 4090 GPU infobrowser_tests/fixtures/data/README.md— Usage guide forpage.route()interceptionAll fixtures are typed against the Zod schemas in
src/schemas/and passpnpm typecheck:browser.┆Issue is synchronized with this Notion page by Unito