Conversation
📝 WalkthroughWalkthroughThis pull request introduces comprehensive test infrastructure for a new Curve widget feature. It adds test assets, a helper class for Playwright-based widget interactions, fixture updates to support curve widget testing, and an extensive E2E test suite covering widget functionality including point manipulation, interpolation, and state management. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
🎨 Storybook: ✅ Built — View Storybook |
🎭 Playwright: ❌ 948 passed, 5 failed · 3 flaky❌ Failed Tests📊 Browser Reports
|
📦 Bundle: 5.11 MB gzip 🟢 -91 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.2 MB (baseline 1.2 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.97 MB (baseline 2.97 MB) • ⚪ 0 BStores, services, APIs, and repositories
Status: 13 added / 13 removed / 4 unchanged Utilities & Hooks — 338 kB (baseline 338 kB) • ⚪ 0 BHelpers, composables, and utility bundles
Status: 13 added / 13 removed / 13 unchanged Vendor & Third-Party — 9.8 MB (baseline 9.8 MB) • ⚪ 0 BExternal libraries and shared vendor chunks Status: 16 unchanged Other — 8.44 MB (baseline 8.44 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-04-03T08:35:02.717Z",
"gitSha": "e5ec4f2b2e272e70b400077741a8b433098d5bec",
"branch": "test/curve-widget-E2E-test-plan",
"measurements": [
{
"name": "canvas-idle",
"durationMs": 2013.3200000000215,
"styleRecalcs": 11,
"styleRecalcDurationMs": 8.717000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 333.801,
"heapDeltaBytes": 20305732,
"heapUsedBytes": 63153916,
"domNodes": 21,
"jsHeapTotalBytes": 23068672,
"scriptDurationMs": 21.816,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-idle",
"durationMs": 2038.657999999998,
"styleRecalcs": 11,
"styleRecalcDurationMs": 10.829000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 379.5230000000001,
"heapDeltaBytes": 20436280,
"heapUsedBytes": 63320356,
"domNodes": 22,
"jsHeapTotalBytes": 22806528,
"scriptDurationMs": 26.358,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-idle",
"durationMs": 2023.7509999999475,
"styleRecalcs": 10,
"styleRecalcDurationMs": 9.036999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 347.73900000000003,
"heapDeltaBytes": 20359628,
"heapUsedBytes": 63126440,
"domNodes": 20,
"jsHeapTotalBytes": 22806528,
"scriptDurationMs": 21.427000000000003,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-mouse-sweep",
"durationMs": 2054.3420000000197,
"styleRecalcs": 83,
"styleRecalcDurationMs": 47.64300000000001,
"layouts": 12,
"layoutDurationMs": 3.7720000000000002,
"taskDurationMs": 1016.5999999999999,
"heapDeltaBytes": 16728744,
"heapUsedBytes": 59206780,
"domNodes": 67,
"jsHeapTotalBytes": 23592960,
"scriptDurationMs": 141.22199999999998,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1999.2129999999975,
"styleRecalcs": 83,
"styleRecalcDurationMs": 45.557,
"layouts": 12,
"layoutDurationMs": 3.657,
"taskDurationMs": 975.782,
"heapDeltaBytes": 16746412,
"heapUsedBytes": 59237784,
"domNodes": 69,
"jsHeapTotalBytes": 22806528,
"scriptDurationMs": 133.422,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "canvas-mouse-sweep",
"durationMs": 2007.1920000000318,
"styleRecalcs": 81,
"styleRecalcDurationMs": 42.227000000000004,
"layouts": 12,
"layoutDurationMs": 3.58,
"taskDurationMs": 958.265,
"heapDeltaBytes": 16294628,
"heapUsedBytes": 59101876,
"domNodes": 65,
"jsHeapTotalBytes": 23068672,
"scriptDurationMs": 133.709,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1739.6160000000123,
"styleRecalcs": 31,
"styleRecalcDurationMs": 16.654000000000003,
"layouts": 6,
"layoutDurationMs": 0.6629999999999999,
"taskDurationMs": 285.073,
"heapDeltaBytes": 24976156,
"heapUsedBytes": 67552804,
"domNodes": 80,
"jsHeapTotalBytes": 20709376,
"scriptDurationMs": 24.758000000000003,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1748.646000000008,
"styleRecalcs": 32,
"styleRecalcDurationMs": 16.944,
"layouts": 6,
"layoutDurationMs": 0.49700000000000005,
"taskDurationMs": 285.023,
"heapDeltaBytes": 24722728,
"heapUsedBytes": 68554688,
"domNodes": 81,
"jsHeapTotalBytes": 20447232,
"scriptDurationMs": 23.526999999999997,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1755.1009999999678,
"styleRecalcs": 32,
"styleRecalcDurationMs": 18.401,
"layouts": 6,
"layoutDurationMs": 0.513,
"taskDurationMs": 317.14300000000003,
"heapDeltaBytes": 15361672,
"heapUsedBytes": 67171664,
"domNodes": 80,
"jsHeapTotalBytes": 23068672,
"scriptDurationMs": 26.01,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "dom-widget-clipping",
"durationMs": 581.1029999999846,
"styleRecalcs": 13,
"styleRecalcDurationMs": 9.009,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 357.382,
"heapDeltaBytes": 6476564,
"heapUsedBytes": 49061024,
"domNodes": 22,
"jsHeapTotalBytes": 13107200,
"scriptDurationMs": 66.19500000000001,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "dom-widget-clipping",
"durationMs": 587.1779999999944,
"styleRecalcs": 14,
"styleRecalcDurationMs": 10.303,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 345.472,
"heapDeltaBytes": 6893476,
"heapUsedBytes": 49373340,
"domNodes": 23,
"jsHeapTotalBytes": 13107200,
"scriptDurationMs": 66.10199999999999,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "dom-widget-clipping",
"durationMs": 569.927000000007,
"styleRecalcs": 14,
"styleRecalcDurationMs": 10.493,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 365.27099999999996,
"heapDeltaBytes": 6550796,
"heapUsedBytes": 49008420,
"domNodes": 24,
"jsHeapTotalBytes": 12845056,
"scriptDurationMs": 68.585,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "large-graph-idle",
"durationMs": 2028.3870000000093,
"styleRecalcs": 11,
"styleRecalcDurationMs": 11.113,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 564.508,
"heapDeltaBytes": 2827964,
"heapUsedBytes": 53428424,
"domNodes": -255,
"jsHeapTotalBytes": 15659008,
"scriptDurationMs": 106.274,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-idle",
"durationMs": 2034.421000000009,
"styleRecalcs": 11,
"styleRecalcDurationMs": 9.687999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 522.918,
"heapDeltaBytes": 5412084,
"heapUsedBytes": 55916892,
"domNodes": -255,
"jsHeapTotalBytes": 16183296,
"scriptDurationMs": 94.464,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-idle",
"durationMs": 2053.886000000034,
"styleRecalcs": 12,
"styleRecalcDurationMs": 10.362,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 531.1909999999999,
"heapDeltaBytes": 5018604,
"heapUsedBytes": 55840896,
"domNodes": -256,
"jsHeapTotalBytes": 15659008,
"scriptDurationMs": 96.327,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "large-graph-pan",
"durationMs": 2139.251999999999,
"styleRecalcs": 70,
"styleRecalcDurationMs": 18.258,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1050.691,
"heapDeltaBytes": 15925544,
"heapUsedBytes": 67808860,
"domNodes": -259,
"jsHeapTotalBytes": 18223104,
"scriptDurationMs": 384.88700000000006,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-pan",
"durationMs": 2151.235999999983,
"styleRecalcs": 70,
"styleRecalcDurationMs": 16.462,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1055.698,
"heapDeltaBytes": 19275300,
"heapUsedBytes": 71319408,
"domNodes": -260,
"jsHeapTotalBytes": 17960960,
"scriptDurationMs": 383.197,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "large-graph-pan",
"durationMs": 2163.6590000000524,
"styleRecalcs": 69,
"styleRecalcDurationMs": 16.618000000000006,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1097.223,
"heapDeltaBytes": 13531100,
"heapUsedBytes": 65614400,
"domNodes": -259,
"jsHeapTotalBytes": 19009536,
"scriptDurationMs": 400.818,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66999999999998,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "large-graph-zoom",
"durationMs": 3147.4570000000313,
"styleRecalcs": 67,
"styleRecalcDurationMs": 17.438000000000002,
"layouts": 60,
"layoutDurationMs": 7.116,
"taskDurationMs": 1299.216,
"heapDeltaBytes": 7758992,
"heapUsedBytes": 61982768,
"domNodes": -262,
"jsHeapTotalBytes": 17231872,
"scriptDurationMs": 488.205,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-zoom",
"durationMs": 3181.2590000000114,
"styleRecalcs": 65,
"styleRecalcDurationMs": 14.811000000000002,
"layouts": 60,
"layoutDurationMs": 6.7059999999999995,
"taskDurationMs": 1317.9270000000001,
"heapDeltaBytes": 10082856,
"heapUsedBytes": 65315988,
"domNodes": -266,
"jsHeapTotalBytes": 15921152,
"scriptDurationMs": 504.385,
"eventListeners": -123,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-zoom",
"durationMs": 3163.793000000055,
"styleRecalcs": 66,
"styleRecalcDurationMs": 17.556999999999995,
"layouts": 60,
"layoutDurationMs": 7.431,
"taskDurationMs": 1316.749,
"heapDeltaBytes": 7170400,
"heapUsedBytes": 61646104,
"domNodes": -263,
"jsHeapTotalBytes": 17494016,
"scriptDurationMs": 490.407,
"eventListeners": -123,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "minimap-idle",
"durationMs": 2017.4449999999524,
"styleRecalcs": 10,
"styleRecalcDurationMs": 8.434000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 518.5519999999999,
"heapDeltaBytes": 3820832,
"heapUsedBytes": 56436496,
"domNodes": -259,
"jsHeapTotalBytes": 16445440,
"scriptDurationMs": 94.81600000000002,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "minimap-idle",
"durationMs": 2047.2689999999716,
"styleRecalcs": 10,
"styleRecalcDurationMs": 8.333,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 521.679,
"heapDeltaBytes": 4301040,
"heapUsedBytes": 56469204,
"domNodes": -258,
"jsHeapTotalBytes": 16183296,
"scriptDurationMs": 98.858,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "minimap-idle",
"durationMs": 2054.8410000000104,
"styleRecalcs": 9,
"styleRecalcDurationMs": 9.006,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 565.529,
"heapDeltaBytes": 4462512,
"heapUsedBytes": 56798172,
"domNodes": -258,
"jsHeapTotalBytes": 15134720,
"scriptDurationMs": 110.85600000000001,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 538.5489999999891,
"styleRecalcs": 47,
"styleRecalcDurationMs": 10.267,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 342.623,
"heapDeltaBytes": 6226076,
"heapUsedBytes": 49320464,
"domNodes": 19,
"jsHeapTotalBytes": 13369344,
"scriptDurationMs": 123.313,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.663333333333338,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 550.0370000000316,
"styleRecalcs": 48,
"styleRecalcDurationMs": 12.158000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 354.895,
"heapDeltaBytes": 6681140,
"heapUsedBytes": 49704044,
"domNodes": 22,
"jsHeapTotalBytes": 13631488,
"scriptDurationMs": 123.295,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.663333333333338,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 581.7459999999528,
"styleRecalcs": 48,
"styleRecalcDurationMs": 13.13,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 378.444,
"heapDeltaBytes": 6819356,
"heapUsedBytes": 49565448,
"domNodes": 22,
"jsHeapTotalBytes": 13107200,
"scriptDurationMs": 129.53799999999998,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "subgraph-idle",
"durationMs": 2003.7649999999871,
"styleRecalcs": 11,
"styleRecalcDurationMs": 10.995,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 341.617,
"heapDeltaBytes": 19909764,
"heapUsedBytes": 62999584,
"domNodes": 22,
"jsHeapTotalBytes": 22806528,
"scriptDurationMs": 17.705,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "subgraph-idle",
"durationMs": 2013.875999999982,
"styleRecalcs": 11,
"styleRecalcDurationMs": 13.408999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 332.702,
"heapDeltaBytes": 19928432,
"heapUsedBytes": 63084412,
"domNodes": 22,
"jsHeapTotalBytes": 23330816,
"scriptDurationMs": 17.151,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-idle",
"durationMs": 1998.9799999999605,
"styleRecalcs": 11,
"styleRecalcDurationMs": 10.544999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 332.901,
"heapDeltaBytes": 19851672,
"heapUsedBytes": 63017620,
"domNodes": 22,
"jsHeapTotalBytes": 23068672,
"scriptDurationMs": 14.492,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1976.9929999999931,
"styleRecalcs": 84,
"styleRecalcDurationMs": 44.649,
"layouts": 16,
"layoutDurationMs": 4.2620000000000005,
"taskDurationMs": 879.5869999999999,
"heapDeltaBytes": 11905112,
"heapUsedBytes": 54599992,
"domNodes": 73,
"jsHeapTotalBytes": 22544384,
"scriptDurationMs": 100.08600000000001,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1992.7149999999756,
"styleRecalcs": 88,
"styleRecalcDurationMs": 48.016,
"layouts": 16,
"layoutDurationMs": 4.442000000000001,
"taskDurationMs": 906.6930000000001,
"heapDeltaBytes": 11898212,
"heapUsedBytes": 54644868,
"domNodes": 74,
"jsHeapTotalBytes": 22544384,
"scriptDurationMs": 97.74199999999999,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1988.9670000000024,
"styleRecalcs": 84,
"styleRecalcDurationMs": 46.458,
"layouts": 16,
"layoutDurationMs": 4.3580000000000005,
"taskDurationMs": 908.2130000000001,
"heapDeltaBytes": 11906292,
"heapUsedBytes": 54972084,
"domNodes": 73,
"jsHeapTotalBytes": 22544384,
"scriptDurationMs": 101.861,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "viewport-pan-sweep",
"durationMs": 8174.937,
"styleRecalcs": 251,
"styleRecalcDurationMs": 41.288000000000004,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3833.5699999999997,
"heapDeltaBytes": 20099908,
"heapUsedBytes": 70965276,
"domNodes": -257,
"jsHeapTotalBytes": 28446720,
"scriptDurationMs": 1455.1070000000002,
"eventListeners": -107,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8183.799000000022,
"styleRecalcs": 252,
"styleRecalcDurationMs": 43.116,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3523.5150000000003,
"heapDeltaBytes": 27587516,
"heapUsedBytes": 78143472,
"domNodes": -256,
"jsHeapTotalBytes": 19795968,
"scriptDurationMs": 1212.834,
"eventListeners": -111,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8164.369000000079,
"styleRecalcs": 252,
"styleRecalcDurationMs": 45.09,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3717.2190000000005,
"heapDeltaBytes": 25078024,
"heapUsedBytes": 75659492,
"domNodes": -256,
"jsHeapTotalBytes": 19533824,
"scriptDurationMs": 1238.872,
"eventListeners": -111,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-idle",
"durationMs": 11374.510999999984,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 11364.1,
"heapDeltaBytes": -34260996,
"heapUsedBytes": 163406600,
"domNodes": -8331,
"jsHeapTotalBytes": 23945216,
"scriptDurationMs": 548.4630000000001,
"eventListeners": -16464,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.223333333333358,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-idle",
"durationMs": 11407.489999999996,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 11396.961,
"heapDeltaBytes": -28864076,
"heapUsedBytes": 165870996,
"domNodes": -8331,
"jsHeapTotalBytes": 26566656,
"scriptDurationMs": 567.542,
"eventListeners": -16464,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-idle",
"durationMs": 12012.553000000025,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 12002.359,
"heapDeltaBytes": -45927212,
"heapUsedBytes": 165878560,
"domNodes": -8330,
"jsHeapTotalBytes": 27353088,
"scriptDurationMs": 597.779,
"eventListeners": -16466,
"totalBlockingTimeMs": 0,
"frameDurationMs": 18.333333333333332,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 13953.480000000014,
"styleRecalcs": 65,
"styleRecalcDurationMs": 12.445999999999986,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 13928.448,
"heapDeltaBytes": -7114048,
"heapUsedBytes": 186491880,
"domNodes": -8333,
"jsHeapTotalBytes": 25956352,
"scriptDurationMs": 848.064,
"eventListeners": -16463,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.223333333333358,
"p95FrameDurationMs": 16.80000000000291
},
{
"name": "vue-large-graph-pan",
"durationMs": 14155.929000000015,
"styleRecalcs": 68,
"styleRecalcDurationMs": 12.934999999999974,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 14131.770999999999,
"heapDeltaBytes": -15903148,
"heapUsedBytes": 180543292,
"domNodes": -8331,
"jsHeapTotalBytes": -520192,
"scriptDurationMs": 859.0740000000001,
"eventListeners": -16492,
"totalBlockingTimeMs": 60,
"frameDurationMs": 17.219999999999953,
"p95FrameDurationMs": 16.80000000000291
},
{
"name": "vue-large-graph-pan",
"durationMs": 13809.871000000043,
"styleRecalcs": 64,
"styleRecalcDurationMs": 13.013999999999971,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 13786.841,
"heapDeltaBytes": -34488496,
"heapUsedBytes": 174312368,
"domNodes": -8331,
"jsHeapTotalBytes": 27004928,
"scriptDurationMs": 845.876,
"eventListeners": -16460,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.776666666666642,
"p95FrameDurationMs": 33.29999999999927
},
{
"name": "workflow-execution",
"durationMs": 450.9819999999536,
"styleRecalcs": 17,
"styleRecalcDurationMs": 26.669,
"layouts": 5,
"layoutDurationMs": 1.437,
"taskDurationMs": 123.88000000000001,
"heapDeltaBytes": 4721844,
"heapUsedBytes": 50584932,
"domNodes": 165,
"jsHeapTotalBytes": 524288,
"scriptDurationMs": 29.137999999999998,
"eventListeners": 71,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.663333333333338,
"p95FrameDurationMs": 16.799999999999727
},
{
"name": "workflow-execution",
"durationMs": 447.89700000001176,
"styleRecalcs": 17,
"styleRecalcDurationMs": 23.415000000000003,
"layouts": 5,
"layoutDurationMs": 1.2889999999999997,
"taskDurationMs": 118.13999999999997,
"heapDeltaBytes": 4505436,
"heapUsedBytes": 50456580,
"domNodes": 156,
"jsHeapTotalBytes": 262144,
"scriptDurationMs": 27.953000000000007,
"eventListeners": 71,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.663333333333338,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "workflow-execution",
"durationMs": 445.5880000000434,
"styleRecalcs": 16,
"styleRecalcDurationMs": 22.09,
"layouts": 5,
"layoutDurationMs": 1.399,
"taskDurationMs": 122.86,
"heapDeltaBytes": 4494412,
"heapUsedBytes": 49101904,
"domNodes": 156,
"jsHeapTotalBytes": 786432,
"scriptDurationMs": 29.360000000000003,
"eventListeners": 71,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.663333333333338,
"p95FrameDurationMs": 16.700000000000273
}
]
} |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (5)
browser_tests/tests/vueNodes/widgets/curve/curveWidget.spec.ts (2)
8-11: Doublesetup()call may cause redundant navigation.The
comfyPageFixturealready callscomfyPage.setup()before yielding to tests. Callingsetup()again inbeforeEachtriggers another full page reload and initialization sequence. If VueNodes setting needs to be enabled before setup, consider usingsetupSettingsAPI before fixture setup or restructuring.If the double setup is intentional (to apply the VueNodes setting), consider documenting why.
Alternative: Use settings in fixture or clarify intent
If the setting must be applied fresh each test, this is acceptable but adds test overhead. If it's intended to be a one-time setup, the setting could potentially be added to the fixture's
setupSettingscall.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_tests/tests/vueNodes/widgets/curve/curveWidget.spec.ts` around lines 8 - 11, The test calls comfyPage.setup() in beforeEach even though the comfyPage fixture already runs setup; remove the redundant call or move the setting earlier: either delete the comfyPage.setup() call in test.beforeEach and rely on the fixture, or ensure the VueNodes flag is applied before fixture setup by using the fixture's setupSettings or calling comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) inside the fixture initialization (instead of in beforeEach); update or document the intent where comfyPage.setup() and comfyPage.settings.setSetting are used (or keep both only if you add a comment explaining why a second setup is required).
112-140: Test misplaced under "Dragging control points" section.The "no points when disabled" test (lines 112-140) is nested under the "Dragging control points"
describeblock, but it tests disabled widget behavior, not dragging. There's also a similar test in the dedicated "Disabled state" section (lines 216-223).Consider either:
- Moving this test to the "Disabled state" section, or
- Removing one of the duplicate disabled-state tests if they cover the same behavior
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_tests/tests/vueNodes/widgets/curve/curveWidget.spec.ts` around lines 112 - 140, The test "no points when disabled" in the Curve widget spec is misplaced under the "Dragging control points" describe block and duplicates coverage in the "Disabled state" section; either move the test (the whole test(...) block named 'no points when disabled' that uses curveWidget('Curve' ) and comfyPage.page.evaluate(...) to set widget.options.disabled = true) into the "Disabled state" describe block, or remove the duplicate test in that section so only one test asserts await expect(helper.svgLocator.locator('circle')).toHaveCount(0); keep the test body and helper usage intact when relocating.browser_tests/fixtures/helpers/CurveWidgetHelper.ts (2)
12-16: Magic numbers could benefit from named constants or brief comments.The
viewBoxExtent = 1.08andpadFraction = 0.04values appear in bothclickAtanddragPoint. A brief comment explaining these values (presumably matching the SVG viewBox setup in the curve widget component) would help maintainability.Example: Extract constants with documentation
+// Curve widget SVG viewBox is "0 0 1.08 1.08" with 0.04 unit padding +const VIEW_BOX_EXTENT = 1.08 +const PAD_FRACTION = 0.04 / VIEW_BOX_EXTENT export class CurveWidgetHelper { // ... async clickAt(curveX: number, curveY: number): Promise<void> { const box = await this.svgLocator.boundingBox() if (!box) throw new Error('SVG not found') - const viewBoxExtent = 1.08 - const padFraction = 0.04 / viewBoxExtent - const usableSize = box.width / viewBoxExtent + const usableSize = box.width / VIEW_BOX_EXTENT - const screenX = box.x + box.width * padFraction + curveX * usableSize + const screenX = box.x + box.width * PAD_FRACTION + curveX * usableSize🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_tests/fixtures/helpers/CurveWidgetHelper.ts` around lines 12 - 16, Extract the repeated magic numbers into well-named constants (e.g., VIEW_BOX_EXTENT = 1.08 and PAD = 0.04) and add a brief comment explaining they correspond to the SVG viewBox scaling and inner padding used by the CurveWidget rendering; update both clickAt and dragPoint to use these constants (and compute padFraction = PAD / VIEW_BOX_EXTENT and usableSize = box.width / VIEW_BOX_EXTENT) so the intent is clear and the values are maintained in one place.
53-60: Consider using Playwright's native right-click for more realistic interaction.The current implementation dispatches a low-level
pointerdownevent withbutton: 2. This may not trigger all the event handlers that a real right-click would (e.g.,contextmenuevent,pointerup).Since SVG elements in Vue-rendered widgets are not occluded by the canvas overlay, the standard Playwright pattern should work. As per coding guidelines,
dispatchEvent('contextmenu')is only needed for canvas-level DOM widgets.Suggested: Use native click with right button
async rightClickPoint(pointIndex: number): Promise<void> { const circle = this.svgLocator.locator('circle').nth(pointIndex) - await circle.dispatchEvent('pointerdown', { - bubbles: true, - cancelable: true, - button: 2 - }) + await circle.click({ button: 'right' }) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_tests/fixtures/helpers/CurveWidgetHelper.ts` around lines 53 - 60, The rightClickPoint helper currently fakes a right-click by dispatching a 'pointerdown' on the circle locator which can miss higher-level events; replace the manual dispatch with Playwright's native click on the circle locator (use circle.click({ button: 'right' }) or numeric button: 2) so the full sequence (pointerdown/pointerup/contextmenu/etc.) is emitted; update the rightClickPoint method to await that click and remove the manual dispatchEvent usage against svgLocator.locator('circle').browser_tests/fixtures/ComfyPage.ts (1)
495-503: Type handling inconsistency withnodeTitleOrIdparameter.The fixture signature accepts
string | number, but the implementation casts tostringand passes togetNodeByTitle. If a numeric node ID is passed, this will look up by title string (e.g.,"1"instead of node ID1), which may not find the intended node.Consider either:
- Restricting the parameter type to
stringonly, or- Adding logic to handle numeric IDs via a different lookup method
Option 1: Simplify to string-only
- curveWidget: async ({ comfyPage, page }, use) => { - await use((nodeTitleOrId: string | number) => { - const node = comfyPage.vueNodes.getNodeByTitle(nodeTitleOrId as string) + curveWidget: async ({ comfyPage, page }, use) => { + await use((nodeTitle: string) => { + const node = comfyPage.vueNodes.getNodeByTitle(nodeTitle)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@browser_tests/fixtures/ComfyPage.ts` around lines 495 - 503, The fixture curveWidget accepts nodeTitleOrId: string | number but always casts to string and calls comfyPage.vueNodes.getNodeByTitle, which will mis-handle numeric IDs; update the implementation to branch on typeof nodeTitleOrId (or change the parameter to string-only): if it's a number call the appropriate ID lookup (e.g., comfyPage.vueNodes.getNodeById or equivalent) and if it's a string call comfyPage.vueNodes.getNodeByTitle so the correct node is returned; ensure the exported fixture signature matches the chosen behavior.
🤖 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/helpers/CurveWidgetHelper.ts`:
- Around line 62-73: The getCurveData method fails to find curve widgets because
it compares widget.type to 'CURVE' (uppercase); update both checks inside the
page.evaluate callback in getCurveData to compare to lowercase 'curve' (i.e.,
change n.widgets?.some((w) => w.type === 'CURVE') and the subsequent .find((w)
=> w.type === 'CURVE') to use 'curve') so the widget search matches the actual
widget.type values.
In `@browser_tests/tests/vueNodes/widgets/curve/curveWidget.spec.ts`:
- Around line 142-150: The test creates widgets with type 'curve' (lowercase)
but CurveWidgetHelper.getCurveData() checks for w.type === 'CURVE' (uppercase),
causing it to return undefined; update CurveWidgetHelper.getCurveData() to match
the test by using lowercase comparison (e.g., w.type === 'curve') or normalize
both sides (e.g., w.type?.toLowerCase() === 'curve') so the helper reliably
finds the widget created by the tests.
- Around line 243-271: The test injects widget data after reload instead of
verifying actual save persistence; change the flow in the 'Persistence' test to
(1) use curveWidget('Curve').clickAt(...) to add the point via the UI, (2) call
the workflow save helper (e.g. comfyPage.workflow.saveWorkflow()) to persist the
change, (3) reload the workflow via
comfyPage.workflow.loadWorkflow('vueNodes/widgets/curve_widget') (or perform a
full page reload), and (4) assert the persisted data by checking
comfyPage.vueNodes.getNodeByTitle('Curve').locator('circle') has the expected
count; remove the manual page.evaluate injection of node.addWidget and ensure
you invoke the real save API/state rather than injecting after reload.
---
Nitpick comments:
In `@browser_tests/fixtures/ComfyPage.ts`:
- Around line 495-503: The fixture curveWidget accepts nodeTitleOrId: string |
number but always casts to string and calls comfyPage.vueNodes.getNodeByTitle,
which will mis-handle numeric IDs; update the implementation to branch on typeof
nodeTitleOrId (or change the parameter to string-only): if it's a number call
the appropriate ID lookup (e.g., comfyPage.vueNodes.getNodeById or equivalent)
and if it's a string call comfyPage.vueNodes.getNodeByTitle so the correct node
is returned; ensure the exported fixture signature matches the chosen behavior.
In `@browser_tests/fixtures/helpers/CurveWidgetHelper.ts`:
- Around line 12-16: Extract the repeated magic numbers into well-named
constants (e.g., VIEW_BOX_EXTENT = 1.08 and PAD = 0.04) and add a brief comment
explaining they correspond to the SVG viewBox scaling and inner padding used by
the CurveWidget rendering; update both clickAt and dragPoint to use these
constants (and compute padFraction = PAD / VIEW_BOX_EXTENT and usableSize =
box.width / VIEW_BOX_EXTENT) so the intent is clear and the values are
maintained in one place.
- Around line 53-60: The rightClickPoint helper currently fakes a right-click by
dispatching a 'pointerdown' on the circle locator which can miss higher-level
events; replace the manual dispatch with Playwright's native click on the circle
locator (use circle.click({ button: 'right' }) or numeric button: 2) so the full
sequence (pointerdown/pointerup/contextmenu/etc.) is emitted; update the
rightClickPoint method to await that click and remove the manual dispatchEvent
usage against svgLocator.locator('circle').
In `@browser_tests/tests/vueNodes/widgets/curve/curveWidget.spec.ts`:
- Around line 8-11: The test calls comfyPage.setup() in beforeEach even though
the comfyPage fixture already runs setup; remove the redundant call or move the
setting earlier: either delete the comfyPage.setup() call in test.beforeEach and
rely on the fixture, or ensure the VueNodes flag is applied before fixture setup
by using the fixture's setupSettings or calling
comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) inside the fixture
initialization (instead of in beforeEach); update or document the intent where
comfyPage.setup() and comfyPage.settings.setSetting are used (or keep both only
if you add a comment explaining why a second setup is required).
- Around line 112-140: The test "no points when disabled" in the Curve widget
spec is misplaced under the "Dragging control points" describe block and
duplicates coverage in the "Disabled state" section; either move the test (the
whole test(...) block named 'no points when disabled' that uses
curveWidget('Curve' ) and comfyPage.page.evaluate(...) to set
widget.options.disabled = true) into the "Disabled state" describe block, or
remove the duplicate test in that section so only one test asserts await
expect(helper.svgLocator.locator('circle')).toHaveCount(0); keep the test body
and helper usage intact when relocating.
🪄 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: c5e040da-0490-4c4c-ba74-297a994aefde
📒 Files selected for processing (4)
browser_tests/assets/vueNodes/widgets/curve_widget.jsonbrowser_tests/fixtures/ComfyPage.tsbrowser_tests/fixtures/helpers/CurveWidgetHelper.tsbrowser_tests/tests/vueNodes/widgets/curve/curveWidget.spec.ts
| async getCurveData(): Promise< | ||
| { points: [number, number][]; interpolation: string } | undefined | ||
| > { | ||
| return this.page.evaluate(() => { | ||
| const node = window.app!.graph.nodes.find((n) => | ||
| n.widgets?.some((w) => w.type === 'CURVE') | ||
| ) | ||
| return node?.widgets?.find((w) => w.type === 'CURVE')?.value as | ||
| | { points: [number, number][]; interpolation: string } | ||
| | undefined | ||
| }) | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for how curve widgets define their type in the codebase
rg -n "type.*['\"]curve['\"]" --type=ts --type=vue -i
rg -n "type.*['\"]CURVE['\"]" --type=ts --type=vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 125
🏁 Script executed:
#!/bin/bash
# Search for curve widget type definitions - fix syntax
rg -i "type.*curve" --type ts --type py -A 2 -B 2Repository: Comfy-Org/ComfyUI_frontend
Length of output: 7627
🏁 Script executed:
#!/bin/bash
# Look for CURVE widget definition specifically
rg "CURVE" -A 2 -B 2 --type ts --type pyRepository: Comfy-Org/ComfyUI_frontend
Length of output: 4297
🏁 Script executed:
#!/bin/bash
# Check test file to see what widget type is actually used
fd "\.spec\.ts$" | xargs rg -l "curve\|CURVE" | head -5Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
#!/bin/bash
# Look for CurveWidget implementation
fd "Curve.*Widget" -type fRepository: Comfy-Org/ComfyUI_frontend
Length of output: 240
Change getCurveData widget type search from 'CURVE' to 'curve'
The method searches for w.type === 'CURVE', but widget objects have type set to lowercase 'curve'. The uppercase 'CURVE' is only used as a widget registry alias and in node definition schemas, not in the actual widget type property. This mismatch prevents the method from finding curve widgets. Update both checks to use lowercase 'curve'.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@browser_tests/fixtures/helpers/CurveWidgetHelper.ts` around lines 62 - 73,
The getCurveData method fails to find curve widgets because it compares
widget.type to 'CURVE' (uppercase); update both checks inside the page.evaluate
callback in getCurveData to compare to lowercase 'curve' (i.e., change
n.widgets?.some((w) => w.type === 'CURVE') and the subsequent .find((w) =>
w.type === 'CURVE') to use 'curve') so the widget search matches the actual
widget.type values.
| test('drag clamps to [0, 1]', async ({ curveWidget }) => { | ||
| const helper = curveWidget('Curve') | ||
| await helper.dragPoint(0, -0.5, 1.5) | ||
| const data = await helper.getCurveData() | ||
| expect(data?.points[0][0]).toBeGreaterThanOrEqual(-0.001) | ||
| expect(data?.points[0][0]).toBeLessThanOrEqual(1.001) | ||
| expect(data?.points[0][1]).toBeGreaterThanOrEqual(-0.001) | ||
| expect(data?.points[0][1]).toBeLessThanOrEqual(1.001) | ||
| }) |
There was a problem hiding this comment.
Widget type case mismatch between tests and helper.
The test adds widgets with type: 'curve' (lowercase, line 20-21, 277), but CurveWidgetHelper.getCurveData() searches for w.type === 'CURVE' (uppercase). This mismatch means getCurveData() will return undefined for widgets created by these tests.
Either the helper should use lowercase 'curve', or the test should add widgets with uppercase 'CURVE'.
Fix in CurveWidgetHelper.ts
- n.widgets?.some((w) => w.type === 'CURVE')
+ n.widgets?.some((w) => w.type === 'curve')
)
- return node?.widgets?.find((w) => w.type === 'CURVE')?.value as
+ return node?.widgets?.find((w) => w.type === 'curve')?.value as🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@browser_tests/tests/vueNodes/widgets/curve/curveWidget.spec.ts` around lines
142 - 150, The test creates widgets with type 'curve' (lowercase) but
CurveWidgetHelper.getCurveData() checks for w.type === 'CURVE' (uppercase),
causing it to return undefined; update CurveWidgetHelper.getCurveData() to match
the test by using lowercase comparison (e.g., w.type === 'curve') or normalize
both sides (e.g., w.type?.toLowerCase() === 'curve') so the helper reliably
finds the widget created by the tests.
| test.describe('Persistence', { tag: '@workflow' }, () => { | ||
| test('data persists after save/reload', async ({ | ||
| comfyPage, | ||
| curveWidget | ||
| }) => { | ||
| await curveWidget('Curve').clickAt(0.5, 0.8) | ||
| await comfyPage.workflow.loadWorkflow('vueNodes/widgets/curve_widget') | ||
| await comfyPage.page.evaluate(() => { | ||
| const graph = window.graph as TestGraphAccess | ||
| const node = graph._nodes_by_id['1'] | ||
| node.addWidget( | ||
| 'curve', | ||
| 'tone_curve', | ||
| { | ||
| points: [ | ||
| [0, 0], | ||
| [0.5, 0.8], | ||
| [1, 1] | ||
| ], | ||
| interpolation: 'monotone_cubic' | ||
| }, | ||
| () => {} | ||
| ) | ||
| }) | ||
| await expect( | ||
| comfyPage.vueNodes.getNodeByTitle('Curve').locator('circle') | ||
| ).toHaveCount(3) | ||
| }) | ||
| }) |
There was a problem hiding this comment.
Test doesn't actually verify persistence - it injects data after reload.
The test claims to verify "data persists after save/reload", but:
- Line 248 adds a point via UI
- Line 249 immediately reloads the workflow (discarding the UI change)
- Lines 250-266 manually inject widget data via
page.evaluate - Lines 267-269 assert the injected data renders
This tests rendering of injected data, not actual save/reload persistence. To test persistence, you'd need to:
- Add point via UI
- Save the workflow
- Reload the page/workflow
- Verify the point persists from saved state
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@browser_tests/tests/vueNodes/widgets/curve/curveWidget.spec.ts` around lines
243 - 271, The test injects widget data after reload instead of verifying actual
save persistence; change the flow in the 'Persistence' test to (1) use
curveWidget('Curve').clickAt(...) to add the point via the UI, (2) call the
workflow save helper (e.g. comfyPage.workflow.saveWorkflow()) to persist the
change, (3) reload the workflow via
comfyPage.workflow.loadWorkflow('vueNodes/widgets/curve_widget') (or perform a
full page reload), and (4) assert the persisted data by checking
comfyPage.vueNodes.getNodeByTitle('Curve').locator('circle') has the expected
count; remove the manual page.evaluate injection of node.addWidget and ensure
you invoke the real save API/state rather than injecting after reload.
|
I already have #10730 which included basic tests for curve, can you compare which one we should keep? |
|
also, likely all yours tests failed, maybe it has the same issue I had before |
Summary
test: Curve Widget E2E Test Plan
┆Issue is synchronized with this Notion page by Unito