Skip to content

test: add mock data fixtures for backend API responses#10662

Merged
christian-byrne merged 6 commits intomainfrom
mai-15-backend-data-fixtures
Mar 29, 2026
Merged

test: add mock data fixtures for backend API responses#10662
christian-byrne merged 6 commits intomainfrom
mai-15-backend-data-fixtures

Conversation

@christian-byrne
Copy link
Copy Markdown
Contributor

@christian-byrne christian-byrne commented Mar 28, 2026

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 — Mock ComfyNodeDef objects for KSampler, CheckpointLoaderSimple, and CLIPTextEncode
  • browser_tests/fixtures/data/systemStats.ts — Mock SystemStats with realistic RTX 4090 GPU info
  • browser_tests/fixtures/data/README.md — Usage guide for page.route() interception

All fixtures are typed against the Zod schemas in src/schemas/ and pass pnpm typecheck:browser.

┆Issue is synchronized with this Notion page by Unito

@christian-byrne christian-byrne requested a review from a team March 28, 2026 07:53
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Mar 28, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 28, 2026

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fe4eb021-3b3f-49a7-8d7f-894839ca7a7a

📥 Commits

Reviewing files that changed from the base of the PR and between 524c61f and 1454857.

📒 Files selected for processing (1)
  • .github/workflows/ci-oss-assets-validation.yaml
✅ Files skipped from review due to trivial changes (1)
  • .github/workflows/ci-oss-assets-validation.yaml

📝 Walkthrough

Walkthrough

Adds 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

Cohort / File(s) Summary
Fixtures Documentation
browser_tests/fixtures/data/README.md
New README describing deterministic mock fixtures, typing sources (generated types or Zod schemas), using page.route() to intercept API calls, and the requirement to register routes before comfyPageFixture performs navigation; includes TypeScript examples and contribution steps.
Node Definitions Fixture
browser_tests/fixtures/data/nodeDefinitions.ts
Adds baseNodeDefinitions: Record<string, ComfyNodeDef> and exported createMockNodeDefinitions(overrides?: Record<string, ComfyNodeDef>) which returns a structured deep-cloned set of mock node definitions and applies optional overrides.
System Stats Fixture
browser_tests/fixtures/data/systemStats.ts
Adds mockSystemStats: SystemStatsResponse with OS/python/ComfyUI/PyTorch versions, CLI argv, RAM totals/frees, and a single CUDA device entry (name and VRAM totals/frees).
Package manifest
package.json
Adds workspace dependency comfyorg/ingest-types: "workspace:*" to dependencies.
CI config
.github/workflows/ci-oss-assets-validation.yaml
Updates license-checker exclusion list to also exclude comfyorg/ingest-types from checks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I hopped through fixtures, tidy and bright,

Mock nodes and stats to guide each test flight,
Routes set before the page takes wing,
Stable data hums—how my heart will sing!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding mock data fixtures for backend API responses in browser tests.
Description check ✅ Passed The description covers all required template sections with clear changes listed and type-checking validation mentioned, though Screenshots section is absent as a minor non-critical item.
End-To-End Regression Coverage For Fixes ✅ Passed PR title lacks bug-fix language and changes multiple files under browser_tests/ directory, meeting pass criteria.
Adr Compliance For Entity/Litegraph Changes ✅ Passed PR changes only test fixtures, configuration files, and dependencies with no modifications to src/lib/litegraph/, src/ecs/, or graph entity implementations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch mai-15-backend-data-fixtures

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

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 28, 2026

🎨 Storybook: ✅ Built — View Storybook

Details

⏰ Completed at: 03/29/2026, 09:55:52 PM UTC

Links

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 28, 2026

🎭 Playwright: ✅ 770 passed, 0 failed · 2 flaky

📊 Browser Reports
  • chromium: View Report (✅ 756 / ❌ 0 / ⚠️ 2 / ⏭️ 1)
  • chromium-2x: View Report (✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • chromium-0.5x: View Report (✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • mobile-chrome: View Report (✅ 11 / ❌ 0 / ⚠️ 0 / ⏭️ 0)

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 28, 2026

📦 Bundle: 5.09 MB gzip 🔴 +81 B

Details

Summary

  • Raw size: 23.5 MB baseline 23.5 MB — ⚪ 0 B
  • Gzip: 5.09 MB baseline 5.09 MB — 🔴 +81 B
  • Brotli: 3.94 MB baseline 3.94 MB — 🔴 +422 B
  • Bundles: 249 current • 249 baseline • 114 added / 114 removed

Category Glance
Vendor & Third-Party ⚪ 0 B (9.8 MB) · Other ⚪ 0 B (8.45 MB) · Data & Services ⚪ 0 B (2.96 MB) · Graph Workspace ⚪ 0 B (1.14 MB) · Panels & Settings ⚪ 0 B (484 kB) · Utilities & Hooks ⚪ 0 B (334 kB) · + 5 more

App Entry Points — 22.3 kB (baseline 22.3 kB) • ⚪ 0 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-D1rqDQQV.js (new) 22.3 kB 🔴 +22.3 kB 🔴 +7.93 kB 🔴 +6.79 kB
assets/index-FVaTAYJW.js (removed) 22.3 kB 🟢 -22.3 kB 🟢 -7.93 kB 🟢 -6.81 kB

Status: 1 added / 1 removed

Graph Workspace — 1.14 MB (baseline 1.14 MB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-CmhqI9QL.js (new) 1.14 MB 🔴 +1.14 MB 🔴 +244 kB 🔴 +184 kB
assets/GraphView-DWYj7wmj.js (removed) 1.14 MB 🟢 -1.14 MB 🟢 -244 kB 🟢 -184 kB

Status: 1 added / 1 removed

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

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CloudSurveyView-bxLSq9jj.js (removed) 15.7 kB 🟢 -15.7 kB 🟢 -3.4 kB 🟢 -2.9 kB
assets/CloudSurveyView-DFd93fEG.js (new) 15.7 kB 🔴 +15.7 kB 🔴 +3.4 kB 🔴 +2.9 kB
assets/CloudLoginView-C-wX-TMB.js (removed) 12 kB 🟢 -12 kB 🟢 -3.36 kB 🟢 -2.96 kB
assets/CloudLoginView-Cc3G671p.js (new) 12 kB 🔴 +12 kB 🔴 +3.36 kB 🔴 +2.97 kB
assets/CloudSignupView-BjAIHrYR.js (new) 9.78 kB 🔴 +9.78 kB 🔴 +2.85 kB 🔴 +2.5 kB
assets/CloudSignupView-BWeHl8b8.js (removed) 9.78 kB 🟢 -9.78 kB 🟢 -2.85 kB 🟢 -2.5 kB
assets/UserCheckView-DbDyVDRm.js (removed) 9.04 kB 🟢 -9.04 kB 🟢 -2.33 kB 🟢 -2.03 kB
assets/UserCheckView-R79l9LNX.js (new) 9.04 kB 🔴 +9.04 kB 🔴 +2.33 kB 🔴 +2.03 kB
assets/CloudLayoutView-C1l_FATb.js (removed) 7.54 kB 🟢 -7.54 kB 🟢 -2.36 kB 🟢 -2.05 kB
assets/CloudLayoutView-DwgKyhMq.js (new) 7.54 kB 🔴 +7.54 kB 🔴 +2.36 kB 🔴 +2.05 kB
assets/CloudForgotPasswordView-CgoXOqjn.js (new) 5.94 kB 🔴 +5.94 kB 🔴 +2.09 kB 🔴 +1.86 kB
assets/CloudForgotPasswordView-DUehfO50.js (removed) 5.94 kB 🟢 -5.94 kB 🟢 -2.09 kB 🟢 -1.85 kB
assets/CloudAuthTimeoutView-BZPMYki5.js (new) 5.31 kB 🔴 +5.31 kB 🔴 +1.93 kB 🔴 +1.69 kB
assets/CloudAuthTimeoutView-D68to8BX.js (removed) 5.31 kB 🟢 -5.31 kB 🟢 -1.93 kB 🟢 -1.69 kB
assets/CloudSubscriptionRedirectView-D8ZhtYrS.js (removed) 5.08 kB 🟢 -5.08 kB 🟢 -1.91 kB 🟢 -1.69 kB
assets/CloudSubscriptionRedirectView-Kx6gcjk_.js (new) 5.08 kB 🔴 +5.08 kB 🔴 +1.91 kB 🔴 +1.69 kB
assets/UserSelectView-BzrsgqSL.js (removed) 4.71 kB 🟢 -4.71 kB 🟢 -1.74 kB 🟢 -1.54 kB
assets/UserSelectView-D71Cfd7j.js (new) 4.71 kB 🔴 +4.71 kB 🔴 +1.74 kB 🔴 +1.54 kB

Status: 9 added / 9 removed / 2 unchanged

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

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/KeybindingPanel-BTNqhQcS.js (removed) 46.6 kB 🟢 -46.6 kB 🟢 -9.52 kB 🟢 -8.46 kB
assets/KeybindingPanel-CK3QwFZw.js (new) 46.6 kB 🔴 +46.6 kB 🔴 +9.52 kB 🔴 +8.46 kB
assets/SecretsPanel-BHKZOkP-.js (new) 22.4 kB 🔴 +22.4 kB 🔴 +5.42 kB 🔴 +4.76 kB
assets/SecretsPanel-SG15xnp2.js (removed) 22.4 kB 🟢 -22.4 kB 🟢 -5.42 kB 🟢 -4.76 kB
assets/LegacyCreditsPanel-ChbQv5wQ.js (removed) 21.5 kB 🟢 -21.5 kB 🟢 -5.81 kB 🟢 -5.14 kB
assets/LegacyCreditsPanel-pI3yUlBf.js (new) 21.5 kB 🔴 +21.5 kB 🔴 +5.81 kB 🔴 +5.13 kB
assets/SubscriptionPanel-Cj_8RMkt.js (removed) 19.7 kB 🟢 -19.7 kB 🟢 -5.01 kB 🟢 -4.4 kB
assets/SubscriptionPanel-JaLDRsbH.js (new) 19.7 kB 🔴 +19.7 kB 🔴 +5.01 kB 🔴 +4.41 kB
assets/AboutPanel-BODcBcgB.js (new) 12 kB 🔴 +12 kB 🔴 +3.32 kB 🔴 +2.98 kB
assets/AboutPanel-C6iANM0a.js (removed) 12 kB 🟢 -12 kB 🟢 -3.32 kB 🟢 -2.98 kB
assets/ExtensionPanel-B-HWV1hJ.js (new) 9.78 kB 🔴 +9.78 kB 🔴 +2.82 kB 🔴 +2.51 kB
assets/ExtensionPanel-BExRPIn1.js (removed) 9.78 kB 🟢 -9.78 kB 🟢 -2.82 kB 🟢 -2.49 kB
assets/ServerConfigPanel-DNJinx-l.js (removed) 6.85 kB 🟢 -6.85 kB 🟢 -2.27 kB 🟢 -2.03 kB
assets/ServerConfigPanel-DyTTopZu.js (new) 6.85 kB 🔴 +6.85 kB 🔴 +2.27 kB 🔴 +2.03 kB
assets/UserPanel-DobOoTTj.js (new) 6.56 kB 🔴 +6.56 kB 🔴 +2.15 kB 🔴 +1.9 kB
assets/UserPanel-v5X0cU7q.js (removed) 6.56 kB 🟢 -6.56 kB 🟢 -2.16 kB 🟢 -1.89 kB
assets/cloudRemoteConfig--gjWRYLm.js (new) 1.85 kB 🔴 +1.85 kB 🔴 +904 B 🔴 +793 B
assets/cloudRemoteConfig-BjTd6bzO.js (removed) 1.85 kB 🟢 -1.85 kB 🟢 -902 B 🟢 -793 B
assets/refreshRemoteConfig-DcVh34JW.js (new) 1.45 kB 🔴 +1.45 kB 🔴 +648 B 🔴 +555 B
assets/refreshRemoteConfig-DhImIzSr.js (removed) 1.45 kB 🟢 -1.45 kB 🟢 -648 B 🟢 -551 B

Status: 10 added / 10 removed / 12 unchanged

User & Accounts — 17.1 kB (baseline 17.1 kB) • ⚪ 0 B

Authentication, profile, and account management bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/auth-BiWEoJdk.js (new) 3.57 kB 🔴 +3.57 kB 🔴 +1.26 kB 🔴 +1.07 kB
assets/auth-Dz98tlgE.js (removed) 3.57 kB 🟢 -3.57 kB 🟢 -1.26 kB 🟢 -1.07 kB
assets/SignUpForm-CXHB7TgS.js (new) 3.16 kB 🔴 +3.16 kB 🔴 +1.29 kB 🔴 +1.15 kB
assets/SignUpForm-DQ5gjKmC.js (removed) 3.16 kB 🟢 -3.16 kB 🟢 -1.29 kB 🟢 -1.14 kB
assets/UpdatePasswordContent-BAsLp58T.js (new) 2.66 kB 🔴 +2.66 kB 🔴 +1.19 kB 🔴 +1.06 kB
assets/UpdatePasswordContent-BCA0ASm1.js (removed) 2.66 kB 🟢 -2.66 kB 🟢 -1.2 kB 🟢 -1.06 kB
assets/authStore-BK_PDJsE.js (new) 989 B 🔴 +989 B 🔴 +482 B 🔴 +430 B
assets/authStore-BQ8bAoDa.js (removed) 989 B 🟢 -989 B 🟢 -481 B 🟢 -423 B
assets/auth-Bc7PC8ms.js (new) 348 B 🔴 +348 B 🔴 +215 B 🔴 +190 B
assets/auth-DBQRXyBb.js (removed) 348 B 🟢 -348 B 🟢 -213 B 🟢 -188 B

Status: 5 added / 5 removed / 2 unchanged

Editors & Dialogs — 109 kB (baseline 109 kB) • ⚪ 0 B

Modals, dialogs, drawers, and in-app editors

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useShareDialog-D5gN52-x.js (new) 108 kB 🔴 +108 kB 🔴 +22.4 kB 🔴 +18.9 kB
assets/useShareDialog-hDEl7lxZ.js (removed) 108 kB 🟢 -108 kB 🟢 -22.4 kB 🟢 -18.9 kB
assets/useSubscriptionDialog-C2kdzZsc.js (removed) 969 B 🟢 -969 B 🟢 -475 B 🟢 -414 B
assets/useSubscriptionDialog-CeZgS5pv.js (new) 969 B 🔴 +969 B 🔴 +476 B 🔴 +418 B

Status: 2 added / 2 removed

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

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyQueueButton-C4mZjppn.js (removed) 13.5 kB 🟢 -13.5 kB 🟢 -3.79 kB 🟢 -3.37 kB
assets/ComfyQueueButton-D_24yHWS.js (new) 13.5 kB 🔴 +13.5 kB 🔴 +3.79 kB 🔴 +3.38 kB
assets/useTerminalTabs-7KDy0ygM.js (removed) 10.7 kB 🟢 -10.7 kB 🟢 -3.6 kB 🟢 -3.16 kB
assets/useTerminalTabs-CWReOP4m.js (new) 10.7 kB 🔴 +10.7 kB 🔴 +3.6 kB 🔴 +3.17 kB
assets/SubscribeButton-CFpZ1GpN.js (new) 2.42 kB 🔴 +2.42 kB 🔴 +1.04 kB 🔴 +915 B
assets/SubscribeButton-ybuMQabk.js (removed) 2.42 kB 🟢 -2.42 kB 🟢 -1.04 kB 🟢 -913 B
assets/cloudFeedbackTopbarButton-CqGiG_ad.js (new) 1.66 kB 🔴 +1.66 kB 🔴 +843 B 🔴 +763 B
assets/cloudFeedbackTopbarButton-EfKNY5da.js (removed) 1.66 kB 🟢 -1.66 kB 🟢 -843 B 🟢 -758 B
assets/ComfyQueueButton-CncSZBm_.js (new) 1.03 kB 🔴 +1.03 kB 🔴 +490 B 🔴 +443 B
assets/ComfyQueueButton-DCbHdfRa.js (removed) 1.03 kB 🟢 -1.03 kB 🟢 -489 B 🟢 -436 B

Status: 5 added / 5 removed / 8 unchanged

Data & Services — 2.96 MB (baseline 2.96 MB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/dialogService-B-YbBy4J.js (new) 1.92 MB 🔴 +1.92 MB 🔴 +443 kB 🔴 +336 kB
assets/dialogService-DuTrMvhR.js (removed) 1.92 MB 🟢 -1.92 MB 🟢 -443 kB 🟢 -336 kB
assets/api-Brfh6vY9.js (removed) 885 kB 🟢 -885 kB 🟢 -211 kB 🟢 -167 kB
assets/api-jDQiC_QJ.js (new) 885 kB 🔴 +885 kB 🔴 +211 kB 🔴 +167 kB
assets/load3dService-D1yDnXcb.js (removed) 92.5 kB 🟢 -92.5 kB 🟢 -19.7 kB 🟢 -16.9 kB
assets/load3dService-yoc4PDTP.js (new) 92.5 kB 🔴 +92.5 kB 🔴 +19.7 kB 🔴 +16.9 kB
assets/workflowShareService-BZUh2yP6.js (new) 16.6 kB 🔴 +16.6 kB 🔴 +4.88 kB 🔴 +4.32 kB
assets/workflowShareService-CYFCG-0x.js (removed) 16.6 kB 🟢 -16.6 kB 🟢 -4.88 kB 🟢 -4.32 kB
assets/keybindingService-CmKOeKAd.js (new) 13.8 kB 🔴 +13.8 kB 🔴 +3.67 kB 🔴 +3.21 kB
assets/keybindingService-yG9LhBRS.js (removed) 13.8 kB 🟢 -13.8 kB 🟢 -3.66 kB 🟢 -3.21 kB
assets/releaseStore-Bw4v9qJS.js (removed) 8.12 kB 🟢 -8.12 kB 🟢 -2.28 kB 🟢 -2 kB
assets/releaseStore-CYBasoEp.js (new) 8.12 kB 🔴 +8.12 kB 🔴 +2.28 kB 🔴 +2 kB
assets/userStore-DAtFjaqd.js (new) 2.24 kB 🔴 +2.24 kB 🔴 +869 B 🔴 +762 B
assets/userStore-DgNeaCLA.js (removed) 2.24 kB 🟢 -2.24 kB 🟢 -869 B 🟢 -766 B
assets/audioService-7OB7hCZ9.js (new) 1.8 kB 🔴 +1.8 kB 🔴 +880 B 🔴 +759 B
assets/audioService-CtXY2iYR.js (removed) 1.8 kB 🟢 -1.8 kB 🟢 -877 B 🟢 -765 B
assets/releaseStore-C3KimY2c.js (removed) 993 B 🟢 -993 B 🟢 -480 B 🟢 -421 B
assets/releaseStore-ZYFIKHgC.js (new) 993 B 🔴 +993 B 🔴 +480 B 🔴 +428 B
assets/workflowDraftStore-C0yezESb.js (removed) 969 B 🟢 -969 B 🟢 -474 B 🟢 -417 B
assets/workflowDraftStore-lD7uLtEd.js (new) 969 B 🔴 +969 B 🔴 +475 B 🔴 +425 B
assets/dialogService-DeOt45Nb.js (removed) 958 B 🟢 -958 B 🟢 -464 B 🟢 -412 B
assets/dialogService-DQ6aj_Cj.js (new) 958 B 🔴 +958 B 🔴 +467 B 🔴 +415 B
assets/settingStore-BXmXKW2b.js (removed) 956 B 🟢 -956 B 🟢 -469 B 🟢 -411 B
assets/settingStore-CP7tqekJ.js (new) 956 B 🔴 +956 B 🔴 +470 B 🔴 +414 B
assets/assetsStore-DTacjJw_.js (new) 955 B 🔴 +955 B 🔴 +470 B 🔴 +416 B
assets/assetsStore-Dz4bx8-L.js (removed) 955 B 🟢 -955 B 🟢 -470 B 🟢 -414 B

Status: 13 added / 13 removed / 4 unchanged

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

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useConflictDetection-BlDsbq0O.js (removed) 232 kB 🟢 -232 kB 🟢 -51.3 kB 🟢 -41.8 kB
assets/useConflictDetection-Hzbi-3P8.js (new) 232 kB 🔴 +232 kB 🔴 +51.3 kB 🔴 +41.8 kB
assets/useLoad3dViewer-BVMAcxQA.js (new) 18.7 kB 🔴 +18.7 kB 🔴 +4.43 kB 🔴 +3.87 kB
assets/useLoad3dViewer-z8CIB865.js (removed) 18.7 kB 🟢 -18.7 kB 🟢 -4.43 kB 🟢 -3.88 kB
assets/useLoad3d-_3ikm7wQ.js (new) 15 kB 🔴 +15 kB 🔴 +3.79 kB 🔴 +3.36 kB
assets/useLoad3d-OYAvNqFa.js (removed) 15 kB 🟢 -15 kB 🟢 -3.79 kB 🟢 -3.35 kB
assets/useFeatureFlags-B1YJnwdd.js (removed) 5.78 kB 🟢 -5.78 kB 🟢 -1.75 kB 🟢 -1.48 kB
assets/useFeatureFlags-sH_j_IeK.js (new) 5.78 kB 🔴 +5.78 kB 🔴 +1.75 kB 🔴 +1.48 kB
assets/useCopyToClipboard-D2b4QF2i.js (removed) 5.29 kB 🟢 -5.29 kB 🟢 -1.86 kB 🟢 -1.57 kB
assets/useCopyToClipboard-ToPBU_Lc.js (new) 5.29 kB 🔴 +5.29 kB 🔴 +1.86 kB 🔴 +1.57 kB
assets/useWorkspaceUI-BW8P4gD5.js (new) 3.34 kB 🔴 +3.34 kB 🔴 +981 B 🔴 +811 B
assets/useWorkspaceUI-Df54cry3.js (removed) 3.34 kB 🟢 -3.34 kB 🟢 -979 B 🟢 -812 B
assets/subscriptionCheckoutUtil-DS946SeH.js (removed) 2.97 kB 🟢 -2.97 kB 🟢 -1.3 kB 🟢 -1.14 kB
assets/subscriptionCheckoutUtil-vx8KaEBI.js (new) 2.97 kB 🔴 +2.97 kB 🔴 +1.31 kB 🔴 +1.14 kB
assets/assetPreviewUtil-CBLqshEX.js (new) 2.27 kB 🔴 +2.27 kB 🔴 +957 B 🔴 +830 B
assets/assetPreviewUtil-CPkWxSCW.js (removed) 2.27 kB 🟢 -2.27 kB 🟢 -958 B 🟢 -837 B
assets/useUpstreamValue-7NRHMR3-.js (removed) 2.08 kB 🟢 -2.08 kB 🟢 -807 B 🟢 -721 B
assets/useUpstreamValue-HgIT0c2_.js (new) 2.08 kB 🔴 +2.08 kB 🔴 +804 B 🔴 +709 B
assets/useLoad3d-D-8McCuN.js (new) 1.13 kB 🔴 +1.13 kB 🔴 +539 B 🔴 +484 B
assets/useLoad3d-WDkmuIX4.js (removed) 1.13 kB 🟢 -1.13 kB 🟢 -539 B 🟢 -476 B
assets/useLoad3dViewer-BqMo7g-l.js (removed) 1.07 kB 🟢 -1.07 kB 🟢 -506 B 🟢 -448 B
assets/useLoad3dViewer-bzN9J2bh.js (new) 1.07 kB 🔴 +1.07 kB 🔴 +506 B 🔴 +459 B
assets/useCurrentUser-BSr9sXsq.js (new) 955 B 🔴 +955 B 🔴 +471 B 🔴 +415 B
assets/useCurrentUser-CqN2gi48.js (removed) 955 B 🟢 -955 B 🟢 -470 B 🟢 -411 B
assets/useWorkspaceSwitch-BeXem9pk.js (removed) 747 B 🟢 -747 B 🟢 -384 B 🟢 -334 B
assets/useWorkspaceSwitch-Ccy0DxG1.js (new) 747 B 🔴 +747 B 🔴 +386 B 🔴 +332 B

Status: 13 added / 13 removed / 12 unchanged

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

External libraries and shared vendor chunks

Status: 16 unchanged

Other — 8.45 MB (baseline 8.45 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/core-De_dOFpp.js (removed) 76.8 kB 🟢 -76.8 kB 🟢 -19.9 kB 🟢 -16.9 kB
assets/core-MepBhNgN.js (new) 76.8 kB 🔴 +76.8 kB 🔴 +19.9 kB 🔴 +17 kB
assets/groupNode-DE-vaN-2.js (removed) 74 kB 🟢 -74 kB 🟢 -18.5 kB 🟢 -16.3 kB
assets/groupNode-yPFvA1DE.js (new) 74 kB 🔴 +74 kB 🔴 +18.5 kB 🔴 +16.3 kB
assets/WidgetSelect-B6lXaZT2.js (removed) 64.6 kB 🟢 -64.6 kB 🟢 -14.1 kB 🟢 -12.2 kB
assets/WidgetSelect-DNVnWmNm.js (new) 64.6 kB 🔴 +64.6 kB 🔴 +14.1 kB 🔴 +12.2 kB
assets/SubscriptionRequiredDialogContentWorkspace-D-2JGd6i.js (new) 48.9 kB 🔴 +48.9 kB 🔴 +9.29 kB 🔴 +7.94 kB
assets/SubscriptionRequiredDialogContentWorkspace-RNUQaQ5o.js (removed) 48.9 kB 🟢 -48.9 kB 🟢 -9.29 kB 🟢 -7.95 kB
assets/WidgetPainter-BnEQVC-7.js (new) 33.3 kB 🔴 +33.3 kB 🔴 +8.12 kB 🔴 +7.2 kB
assets/WidgetPainter-BUmVlOQ8.js (removed) 33.3 kB 🟢 -33.3 kB 🟢 -8.11 kB 🟢 -7.17 kB
assets/Load3DControls-C6r00Ghf.js (new) 32.1 kB 🔴 +32.1 kB 🔴 +5.47 kB 🔴 +4.76 kB
assets/Load3DControls-tZTk_euP.js (removed) 32.1 kB 🟢 -32.1 kB 🟢 -5.47 kB 🟢 -4.75 kB
assets/WorkspacePanelContent-BstBas7k.js (new) 29.9 kB 🔴 +29.9 kB 🔴 +6.33 kB 🔴 +5.55 kB
assets/WorkspacePanelContent-DQuCkQyr.js (removed) 29.9 kB 🟢 -29.9 kB 🟢 -6.33 kB 🟢 -5.55 kB
assets/SubscriptionRequiredDialogContent-B9aXo8a6.js (removed) 28.2 kB 🟢 -28.2 kB 🟢 -7.16 kB 🟢 -6.3 kB
assets/SubscriptionRequiredDialogContent-Cw4rQnDq.js (new) 28.2 kB 🔴 +28.2 kB 🔴 +7.17 kB 🔴 +6.3 kB
assets/Load3dViewerContent-Bs_rsC8H.js (new) 24.3 kB 🔴 +24.3 kB 🔴 +5.32 kB 🔴 +4.63 kB
assets/Load3dViewerContent-DW9XKiXL.js (removed) 24.3 kB 🟢 -24.3 kB 🟢 -5.32 kB 🟢 -4.63 kB
assets/WidgetImageCrop-B0v6liuY.js (new) 23.3 kB 🔴 +23.3 kB 🔴 +5.83 kB 🔴 +5.14 kB
assets/WidgetImageCrop-BV9RVr0Z.js (removed) 23.3 kB 🟢 -23.3 kB 🟢 -5.82 kB 🟢 -5.14 kB
assets/SubscriptionPanelContentWorkspace-L3nRA1K6.js (removed) 22.2 kB 🟢 -22.2 kB 🟢 -5.18 kB 🟢 -4.56 kB
assets/SubscriptionPanelContentWorkspace-wCmc1BbP.js (new) 22.2 kB 🔴 +22.2 kB 🔴 +5.18 kB 🔴 +4.56 kB
assets/SignInContent-BFe9inbc.js (removed) 20.4 kB 🟢 -20.4 kB 🟢 -5.29 kB 🟢 -4.61 kB
assets/SignInContent-CzgSiWaU.js (new) 20.4 kB 🔴 +20.4 kB 🔴 +5.29 kB 🔴 +4.63 kB
assets/CurrentUserPopoverWorkspace-Cr1mSna2.js (removed) 20.4 kB 🟢 -20.4 kB 🟢 -4.83 kB 🟢 -4.33 kB
assets/CurrentUserPopoverWorkspace-TD9YaP9C.js (new) 20.4 kB 🔴 +20.4 kB 🔴 +4.83 kB 🔴 +4.33 kB
assets/WidgetInputNumber-BoaeuWF0.js (new) 19.1 kB 🔴 +19.1 kB 🔴 +4.84 kB 🔴 +4.29 kB
assets/WidgetInputNumber-BWbZgzDr.js (removed) 19.1 kB 🟢 -19.1 kB 🟢 -4.84 kB 🟢 -4.29 kB
assets/WidgetRecordAudio-CwkIeIx7.js (new) 18.1 kB 🔴 +18.1 kB 🔴 +5.18 kB 🔴 +4.64 kB
assets/WidgetRecordAudio-rfkJ3Jy3.js (removed) 18.1 kB 🟢 -18.1 kB 🟢 -5.18 kB 🟢 -4.64 kB
assets/Load3D-DwoQvGC8.js (new) 16.9 kB 🔴 +16.9 kB 🔴 +4.11 kB 🔴 +3.59 kB
assets/Load3D-DXeaiziR.js (removed) 16.9 kB 🟢 -16.9 kB 🟢 -4.12 kB 🟢 -3.59 kB
assets/WidgetCurve-CKaIKVYh.js (new) 16.1 kB 🔴 +16.1 kB 🔴 +4.96 kB 🔴 +4.45 kB
assets/WidgetCurve-DmQH3T4a.js (removed) 16.1 kB 🟢 -16.1 kB 🟢 -4.97 kB 🟢 -4.45 kB
assets/load3d-CBcmW1-d.js (removed) 15 kB 🟢 -15 kB 🟢 -4.32 kB 🟢 -3.74 kB
assets/load3d-Sn0-2XUp.js (new) 15 kB 🔴 +15 kB 🔴 +4.32 kB 🔴 +3.74 kB
assets/WaveAudioPlayer-Cb3La42a.js (removed) 13.4 kB 🟢 -13.4 kB 🟢 -3.68 kB 🟢 -3.22 kB
assets/WaveAudioPlayer-xj_z4Ygi.js (new) 13.4 kB 🔴 +13.4 kB 🔴 +3.68 kB 🔴 +3.22 kB
assets/TeamWorkspacesDialogContent-BoZGxgw6.js (new) 11.1 kB 🔴 +11.1 kB 🔴 +3.33 kB 🔴 +2.98 kB
assets/TeamWorkspacesDialogContent-g1Wp9EVw.js (removed) 11.1 kB 🟢 -11.1 kB 🟢 -3.33 kB 🟢 -2.98 kB
assets/nodeTemplates-BKrIRmO3.js (removed) 9.58 kB 🟢 -9.58 kB 🟢 -3.37 kB 🟢 -2.97 kB
assets/nodeTemplates-DPZd-Adx.js (new) 9.58 kB 🔴 +9.58 kB 🔴 +3.37 kB 🔴 +2.97 kB
assets/InviteMemberDialogContent-DqwIs82H.js (removed) 7.77 kB 🟢 -7.77 kB 🟢 -2.45 kB 🟢 -2.13 kB
assets/InviteMemberDialogContent-tz4o18Wo.js (new) 7.77 kB 🔴 +7.77 kB 🔴 +2.45 kB 🔴 +2.14 kB
assets/Load3DConfiguration-BPcnX_ie.js (new) 6.6 kB 🔴 +6.6 kB 🔴 +2.04 kB 🔴 +1.78 kB
assets/Load3DConfiguration-kanwps0b.js (removed) 6.6 kB 🟢 -6.6 kB 🟢 -2.04 kB 🟢 -1.78 kB
assets/onboardingCloudRoutes-BbNAfQ5s.js (new) 6.53 kB 🔴 +6.53 kB 🔴 +2.04 kB 🔴 +1.77 kB
assets/onboardingCloudRoutes-Bh-qBDDc.js (removed) 6.53 kB 🟢 -6.53 kB 🟢 -2.04 kB 🟢 -1.75 kB
assets/WidgetWithControl-BsaOQf0a.js (removed) 5.99 kB 🟢 -5.99 kB 🟢 -2.38 kB 🟢 -2.13 kB
assets/WidgetWithControl-DFqF6FLq.js (new) 5.99 kB 🔴 +5.99 kB 🔴 +2.38 kB 🔴 +2.14 kB
assets/CreateWorkspaceDialogContent-6GC3TbG9.js (removed) 5.95 kB 🟢 -5.95 kB 🟢 -2.15 kB 🟢 -1.88 kB
assets/CreateWorkspaceDialogContent-CnGqTG53.js (new) 5.95 kB 🔴 +5.95 kB 🔴 +2.15 kB 🔴 +1.87 kB
assets/FreeTierDialogContent-CTezgamP.js (removed) 5.82 kB 🟢 -5.82 kB 🟢 -2.05 kB 🟢 -1.8 kB
assets/FreeTierDialogContent-DWJECGAR.js (new) 5.82 kB 🔴 +5.82 kB 🔴 +2.04 kB 🔴 +1.81 kB
assets/EditWorkspaceDialogContent-BBkum3xm.js (removed) 5.75 kB 🟢 -5.75 kB 🟢 -2.11 kB 🟢 -1.84 kB
assets/EditWorkspaceDialogContent-D0zgeLzI.js (new) 5.75 kB 🔴 +5.75 kB 🔴 +2.11 kB 🔴 +1.84 kB
assets/WidgetTextarea-BHBOlOdk.js (removed) 5.53 kB 🟢 -5.53 kB 🟢 -2.17 kB 🟢 -1.93 kB
assets/WidgetTextarea-DsM9u-WO.js (new) 5.53 kB 🔴 +5.53 kB 🔴 +2.17 kB 🔴 +1.92 kB
assets/Preview3d-C-TCP5pN.js (removed) 5.36 kB 🟢 -5.36 kB 🟢 -1.79 kB 🟢 -1.56 kB
assets/Preview3d-TTrstGR4.js (new) 5.36 kB 🔴 +5.36 kB 🔴 +1.79 kB 🔴 +1.57 kB
assets/ValueControlPopover-B0cXgejC.js (removed) 5.33 kB 🟢 -5.33 kB 🟢 -1.93 kB 🟢 -1.72 kB
assets/ValueControlPopover-CF7T2EbT.js (new) 5.33 kB 🔴 +5.33 kB 🔴 +1.93 kB 🔴 +1.72 kB
assets/CancelSubscriptionDialogContent-BV5s9Ozs.js (new) 5.22 kB 🔴 +5.22 kB 🔴 +1.95 kB 🔴 +1.7 kB
assets/CancelSubscriptionDialogContent-DeMqyUXn.js (removed) 5.22 kB 🟢 -5.22 kB 🟢 -1.95 kB 🟢 -1.7 kB
assets/DeleteWorkspaceDialogContent-BXVHVJQp.js (removed) 4.65 kB 🟢 -4.65 kB 🟢 -1.79 kB 🟢 -1.54 kB
assets/DeleteWorkspaceDialogContent-DL_81ziW.js (new) 4.65 kB 🔴 +4.65 kB 🔴 +1.79 kB 🔴 +1.55 kB
assets/LeaveWorkspaceDialogContent-BV_yejBA.js (removed) 4.48 kB 🟢 -4.48 kB 🟢 -1.73 kB 🟢 -1.51 kB
assets/LeaveWorkspaceDialogContent-DZUW2AU9.js (new) 4.48 kB 🔴 +4.48 kB 🔴 +1.74 kB 🔴 +1.5 kB
assets/RemoveMemberDialogContent-BbiSjQZr.js (removed) 4.46 kB 🟢 -4.46 kB 🟢 -1.69 kB 🟢 -1.47 kB
assets/RemoveMemberDialogContent-CGH4Dyzm.js (new) 4.46 kB 🔴 +4.46 kB 🔴 +1.69 kB 🔴 +1.47 kB
assets/tierBenefits-BRxDUa1d.js (removed) 4.45 kB 🟢 -4.45 kB 🟢 -1.57 kB 🟢 -1.36 kB
assets/tierBenefits-DNu5A0uH.js (new) 4.45 kB 🔴 +4.45 kB 🔴 +1.58 kB 🔴 +1.37 kB
assets/RevokeInviteDialogContent-jlWb9iMD.js (removed) 4.37 kB 🟢 -4.37 kB 🟢 -1.7 kB 🟢 -1.48 kB
assets/RevokeInviteDialogContent-YPZNr3Pd.js (new) 4.37 kB 🔴 +4.37 kB 🔴 +1.7 kB 🔴 +1.48 kB
assets/InviteMemberUpsellDialogContent-gsmdK26P.js (removed) 4.27 kB 🟢 -4.27 kB 🟢 -1.56 kB 🟢 -1.36 kB
assets/InviteMemberUpsellDialogContent-Q6ukMLb8.js (new) 4.27 kB 🔴 +4.27 kB 🔴 +1.56 kB 🔴 +1.37 kB
assets/cloudSessionCookie-D567Nihf.js (removed) 4.12 kB 🟢 -4.12 kB 🟢 -1.49 kB 🟢 -1.29 kB
assets/cloudSessionCookie-DJthrVzx.js (new) 4.12 kB 🔴 +4.12 kB 🔴 +1.49 kB 🔴 +1.3 kB
assets/saveMesh-Baj1GJB2.js (new) 3.92 kB 🔴 +3.92 kB 🔴 +1.68 kB 🔴 +1.48 kB
assets/saveMesh-CELKmUps.js (removed) 3.92 kB 🟢 -3.92 kB 🟢 -1.68 kB 🟢 -1.48 kB
assets/Media3DTop-B407brqa.js (removed) 3.85 kB 🟢 -3.85 kB 🟢 -1.62 kB 🟢 -1.43 kB
assets/Media3DTop-i5LuLPqe.js (new) 3.85 kB 🔴 +3.85 kB 🔴 +1.62 kB 🔴 +1.43 kB
assets/GlobalToast-CC4O9Csi.js (new) 3.05 kB 🔴 +3.05 kB 🔴 +1.26 kB 🔴 +1.11 kB
assets/GlobalToast-CqACQfCp.js (removed) 3.05 kB 🟢 -3.05 kB 🟢 -1.26 kB 🟢 -1.07 kB
assets/SubscribeToRun-d-2KUSH2.js (removed) 2.13 kB 🟢 -2.13 kB 🟢 -982 B 🟢 -873 B
assets/SubscribeToRun-Ttm5Klac.js (new) 2.13 kB 🔴 +2.13 kB 🔴 +983 B 🔴 +868 B
assets/MediaAudioTop-BMvudm-4.js (removed) 2.02 kB 🟢 -2.02 kB 🟢 -979 B 🟢 -831 B
assets/MediaAudioTop-FicdMILp.js (new) 2.02 kB 🔴 +2.02 kB 🔴 +980 B 🔴 +828 B
assets/CloudRunButtonWrapper-BL12Eo0o.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -913 B 🟢 -800 B
assets/CloudRunButtonWrapper-CQP-bJdT.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +911 B 🔴 +808 B
assets/graphHasMissingNodes-CtK5e52I.js (new) 1.83 kB 🔴 +1.83 kB 🔴 +861 B 🔴 +752 B
assets/graphHasMissingNodes-DR9f3XSg.js (removed) 1.83 kB 🟢 -1.83 kB 🟢 -861 B 🟢 -750 B
assets/cloudBadges-C34t5s5i.js (new) 1.77 kB 🔴 +1.77 kB 🔴 +892 B 🔴 +775 B
assets/cloudBadges-CWhWiRB6.js (removed) 1.77 kB 🟢 -1.77 kB 🟢 -892 B 🟢 -773 B
assets/cloudSubscription-aKNiOX7o.js (removed) 1.68 kB 🟢 -1.68 kB 🟢 -813 B 🟢 -709 B
assets/cloudSubscription-D-80NweI.js (new) 1.68 kB 🔴 +1.68 kB 🔴 +814 B 🔴 +716 B
assets/previousFullPath-ClLgfaVc.js (removed) 1.53 kB 🟢 -1.53 kB 🟢 -692 B 🟢 -598 B
assets/previousFullPath-if60mFYR.js (new) 1.53 kB 🔴 +1.53 kB 🔴 +694 B 🔴 +601 B
assets/Load3D-BaRsztra.js (removed) 1.34 kB 🟢 -1.34 kB 🟢 -614 B 🟢 -544 B
assets/Load3D-DEjogUJU.js (new) 1.34 kB 🔴 +1.34 kB 🔴 +613 B 🔴 +550 B
assets/nightlyBadges-CVBMt7KI.js (new) 1.29 kB 🔴 +1.29 kB 🔴 +658 B 🔴 +580 B
assets/nightlyBadges-Dps8kBfc.js (removed) 1.29 kB 🟢 -1.29 kB 🟢 -655 B 🟢 -580 B
assets/Load3dViewerContent-d_Rgwq2V.js (removed) 1.23 kB 🟢 -1.23 kB 🟢 -568 B 🟢 -496 B
assets/Load3dViewerContent-ywZsZAAN.js (new) 1.23 kB 🔴 +1.23 kB 🔴 +567 B 🔴 +502 B
assets/SubscriptionPanelContentWorkspace-Crz0PcVh.js (removed) 1.15 kB 🟢 -1.15 kB 🟢 -537 B 🟢 -465 B
assets/SubscriptionPanelContentWorkspace-CVBiucos.js (new) 1.15 kB 🔴 +1.15 kB 🔴 +535 B 🔴 +470 B
assets/WidgetLegacy-BpIj0shR.js (new) 978 B 🔴 +978 B 🔴 +482 B 🔴 +425 B
assets/WidgetLegacy-BQvkrFzZ.js (removed) 978 B 🟢 -978 B 🟢 -482 B 🟢 -423 B
assets/changeTracker-CSQHcwzR.js (new) 952 B 🔴 +952 B 🔴 +470 B 🔴 +414 B
assets/changeTracker-DgJH3nWZ.js (removed) 952 B 🟢 -952 B 🟢 -469 B 🟢 -409 B

Status: 55 added / 55 removed / 79 unchanged

⚡ Performance Report

canvas-idle: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 60.6 MB heap
canvas-mouse-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 56.0 MB heap
canvas-zoom-sweep: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 64.1 MB heap
dom-widget-clipping: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 47.0 MB heap
large-graph-idle: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 52.9 MB heap
large-graph-pan: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 65.2 MB heap
large-graph-zoom: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 61.3 MB heap
minimap-idle: · 60.0 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 68.2 MB heap
subgraph-dom-widget-clipping: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 47.0 MB heap
subgraph-idle: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 60.0 MB heap
subgraph-mouse-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 52.4 MB heap
viewport-pan-sweep: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 70.1 MB heap
vue-large-graph-idle: · 58.1 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 158.1 MB heap
vue-large-graph-pan: · 58.1 avg FPS · 59.5 P5 FPS ✅ (target: ≥52) · 0ms TBT · 164.2 MB heap
workflow-execution: · 60.0 avg FPS · 59.9 P5 FPS ✅ (target: ≥52) · 0ms TBT · 46.2 MB heap

⚠️ 1 regression detected

Metric Baseline PR (median) Δ Sig
subgraph-mouse-sweep: task duration 917ms 941ms +3% ⚠️ z=2.5
All metrics
Metric Baseline PR (median) Δ Sig
canvas-idle: avg frame time 17ms 17ms -0% z=-0.9
canvas-idle: p95 frame time 17ms 17ms +1%
canvas-idle: layout duration 0ms 0ms +0%
canvas-idle: style recalc duration 11ms 11ms -2% z=0.4
canvas-idle: layout count 0 0 +0%
canvas-idle: style recalc count 11 11 +0% z=-0.3
canvas-idle: task duration 372ms 358ms -4% z=-1.2
canvas-idle: script duration 25ms 23ms -10% z=-1.1
canvas-idle: TBT 0ms 0ms +0%
canvas-idle: heap used 60.4 MB 60.6 MB +0%
canvas-idle: DOM nodes 22 22 +0% z=-0.5
canvas-idle: event listeners 6 6 +0% z=-1.2
canvas-mouse-sweep: avg frame time 17ms 17ms +0% z=0.7
canvas-mouse-sweep: p95 frame time 17ms 17ms -1%
canvas-mouse-sweep: layout duration 3ms 4ms +5% z=0.1
canvas-mouse-sweep: style recalc duration 42ms 36ms -14% z=-2.0
canvas-mouse-sweep: layout count 12 12 +0%
canvas-mouse-sweep: style recalc count 76 73 -4% z=-2.4
canvas-mouse-sweep: task duration 778ms 748ms -4% z=-2.0
canvas-mouse-sweep: script duration 139ms 134ms -4% z=-0.3
canvas-mouse-sweep: TBT 0ms 0ms +0%
canvas-mouse-sweep: heap used 56.1 MB 56.0 MB -0%
canvas-mouse-sweep: DOM nodes 60 56 -7% z=-2.4
canvas-mouse-sweep: event listeners 6 4 -33% z=-1.1
canvas-zoom-sweep: avg frame time 17ms 17ms +0% z=0.5
canvas-zoom-sweep: p95 frame time 17ms 17ms +1%
canvas-zoom-sweep: layout duration 1ms 1ms +1% z=0.4
canvas-zoom-sweep: style recalc duration 19ms 20ms +4% z=0.4
canvas-zoom-sweep: layout count 6 6 +0%
canvas-zoom-sweep: style recalc count 31 32 +3% z=1.6
canvas-zoom-sweep: task duration 305ms 320ms +5% z=-0.3
canvas-zoom-sweep: script duration 25ms 29ms +16% z=0.8
canvas-zoom-sweep: TBT 0ms 0ms +0%
canvas-zoom-sweep: heap used 64.0 MB 64.1 MB +0%
canvas-zoom-sweep: DOM nodes 79 80 +1% z=1.0
canvas-zoom-sweep: event listeners 19 19 +0% z=-0.9
dom-widget-clipping: avg frame time 17ms 17ms +0% z=0.1
dom-widget-clipping: p95 frame time 17ms 17ms +0%
dom-widget-clipping: layout duration 0ms 0ms +0%
dom-widget-clipping: style recalc duration 8ms 10ms +17% z=-0.4
dom-widget-clipping: layout count 0 0 +0%
dom-widget-clipping: style recalc count 12 13 +8% z=-0.2
dom-widget-clipping: task duration 353ms 350ms -1% z=-0.9
dom-widget-clipping: script duration 66ms 70ms +5% z=0.5
dom-widget-clipping: TBT 0ms 0ms +0%
dom-widget-clipping: heap used 46.8 MB 47.0 MB +0%
dom-widget-clipping: DOM nodes 20 22 +10% z=-0.1
dom-widget-clipping: event listeners 2 2 +0% variance too high
large-graph-idle: avg frame time 17ms 17ms +0% z=-0.2
large-graph-idle: p95 frame time 17ms 17ms +0%
large-graph-idle: layout duration 0ms 0ms +0%
large-graph-idle: style recalc duration 10ms 11ms +13% z=-1.2
large-graph-idle: layout count 0 0 +0%
large-graph-idle: style recalc count 9 11 +22% z=-1.9
large-graph-idle: task duration 556ms 562ms +1% z=0.4
large-graph-idle: script duration 102ms 103ms +1% z=0.1
large-graph-idle: TBT 0ms 0ms +0%
large-graph-idle: heap used 53.2 MB 52.9 MB -1%
large-graph-idle: DOM nodes -259 -256 -1% z=-310.6
large-graph-idle: event listeners -127 -125 -2% z=-24.8
large-graph-pan: avg frame time 17ms 17ms +0% z=0.3
large-graph-pan: p95 frame time 17ms 17ms -1%
large-graph-pan: layout duration 0ms 0ms +0%
large-graph-pan: style recalc duration 18ms 16ms -10% z=-1.9
large-graph-pan: layout count 0 0 +0%
large-graph-pan: style recalc count 70 69 -1% z=-0.9
large-graph-pan: task duration 1131ms 1126ms -0% z=1.0
large-graph-pan: script duration 411ms 405ms -2% z=-0.2
large-graph-pan: TBT 0ms 0ms +0%
large-graph-pan: heap used 53.9 MB 65.2 MB +21%
large-graph-pan: DOM nodes -259 -262 +1% z=-170.3
large-graph-pan: event listeners -127 -127 +0% z=-159.3
large-graph-zoom: avg frame time 17ms 17ms +0%
large-graph-zoom: p95 frame time 17ms 17ms +0%
large-graph-zoom: layout duration 7ms 8ms +3%
large-graph-zoom: style recalc duration 18ms 18ms +2%
large-graph-zoom: layout count 60 60 +0%
large-graph-zoom: style recalc count 66 67 +2%
large-graph-zoom: task duration 1339ms 1339ms -0%
large-graph-zoom: script duration 496ms 497ms +0%
large-graph-zoom: TBT 0ms 0ms +0%
large-graph-zoom: heap used 58.7 MB 61.3 MB +4%
large-graph-zoom: DOM nodes -263 -262 -0%
large-graph-zoom: event listeners -123 -123 +0%
minimap-idle: avg frame time 17ms 17ms +0% z=1.2
minimap-idle: p95 frame time 17ms 17ms +1%
minimap-idle: layout duration 0ms 0ms +0%
minimap-idle: style recalc duration 10ms 9ms -7% z=-0.1
minimap-idle: layout count 0 0 +0%
minimap-idle: style recalc count 10 9 -10% z=-0.8
minimap-idle: task duration 546ms 567ms +4% z=0.8
minimap-idle: script duration 99ms 102ms +3% z=0.4
minimap-idle: TBT 0ms 0ms +0%
minimap-idle: heap used 54.1 MB 68.2 MB +26%
minimap-idle: DOM nodes -260 -261 +0% z=-204.8
minimap-idle: event listeners -127 -127 +0% z=-199.3
subgraph-dom-widget-clipping: avg frame time 17ms 17ms +0% z=0.1
subgraph-dom-widget-clipping: p95 frame time 17ms 17ms +0%
subgraph-dom-widget-clipping: layout duration 0ms 0ms +0%
subgraph-dom-widget-clipping: style recalc duration 13ms 12ms -8% z=-1.0
subgraph-dom-widget-clipping: layout count 0 0 +0%
subgraph-dom-widget-clipping: style recalc count 48 47 -2% z=-1.6
subgraph-dom-widget-clipping: task duration 362ms 366ms +1% z=-0.7
subgraph-dom-widget-clipping: script duration 125ms 126ms +1% z=-0.4
subgraph-dom-widget-clipping: TBT 0ms 0ms +0%
subgraph-dom-widget-clipping: heap used 47.2 MB 47.0 MB -1%
subgraph-dom-widget-clipping: DOM nodes 22 20 -9% z=-1.9
subgraph-dom-widget-clipping: event listeners 8 8 +0% z=-1.4
subgraph-idle: avg frame time 17ms 17ms +0% z=0.4
subgraph-idle: p95 frame time 17ms 17ms -1%
subgraph-idle: layout duration 0ms 0ms +0%
subgraph-idle: style recalc duration 10ms 11ms +2% z=0.3
subgraph-idle: layout count 0 0 +0%
subgraph-idle: style recalc count 11 11 +0% z=0.2
subgraph-idle: task duration 346ms 367ms +6% z=-0.1
subgraph-idle: script duration 18ms 21ms +17% z=0.4
subgraph-idle: TBT 0ms 0ms +0%
subgraph-idle: heap used 60.1 MB 60.0 MB -0%
subgraph-idle: DOM nodes 22 21 -5% z=-0.5
subgraph-idle: event listeners 6 6 +0% variance too high
subgraph-mouse-sweep: avg frame time 17ms 17ms +0% z=0.4
subgraph-mouse-sweep: p95 frame time 17ms 17ms +0%
subgraph-mouse-sweep: layout duration 5ms 5ms -6% z=0.2
subgraph-mouse-sweep: style recalc duration 47ms 47ms +0% z=1.3
subgraph-mouse-sweep: layout count 16 16 +0%
subgraph-mouse-sweep: style recalc count 84 83 -1% z=1.5
subgraph-mouse-sweep: task duration 917ms 941ms +3% ⚠️ z=2.5
subgraph-mouse-sweep: script duration 105ms 104ms -0% z=0.5
subgraph-mouse-sweep: TBT 0ms 0ms +0%
subgraph-mouse-sweep: heap used 52.5 MB 52.4 MB -0%
subgraph-mouse-sweep: DOM nodes 72 71 -1% z=1.8
subgraph-mouse-sweep: event listeners 6 6 +0% variance too high
viewport-pan-sweep: avg frame time 17ms 17ms +0%
viewport-pan-sweep: p95 frame time 17ms 17ms -1%
viewport-pan-sweep: layout duration 0ms 0ms +0%
viewport-pan-sweep: style recalc duration 44ms 46ms +5%
viewport-pan-sweep: layout count 0 0 +0%
viewport-pan-sweep: style recalc count 252 251 -0%
viewport-pan-sweep: task duration 3769ms 3825ms +1%
viewport-pan-sweep: script duration 1281ms 1298ms +1%
viewport-pan-sweep: TBT 0ms 0ms +0%
viewport-pan-sweep: heap used 73.2 MB 70.1 MB -4%
viewport-pan-sweep: DOM nodes -258 -259 +0%
viewport-pan-sweep: event listeners -111 -111 +0%
vue-large-graph-idle: avg frame time 17ms 17ms +0%
vue-large-graph-idle: p95 frame time 17ms 17ms +0%
vue-large-graph-idle: layout duration 0ms 0ms +0%
vue-large-graph-idle: style recalc duration 0ms 0ms +0%
vue-large-graph-idle: layout count 0 0 +0%
vue-large-graph-idle: style recalc count 0 0 +0%
vue-large-graph-idle: task duration 11992ms 12437ms +4%
vue-large-graph-idle: script duration 613ms 601ms -2%
vue-large-graph-idle: TBT 0ms 0ms +0%
vue-large-graph-idle: heap used 157.8 MB 158.1 MB +0%
vue-large-graph-idle: DOM nodes -8333 -8331 -0%
vue-large-graph-idle: event listeners -16462 -16462 +0%
vue-large-graph-pan: avg frame time 18ms 17ms -3%
vue-large-graph-pan: p95 frame time 17ms 17ms +0%
vue-large-graph-pan: layout duration 0ms 0ms +0%
vue-large-graph-pan: style recalc duration 14ms 15ms +6%
vue-large-graph-pan: layout count 0 0 +0%
vue-large-graph-pan: style recalc count 67 68 +1%
vue-large-graph-pan: task duration 14372ms 14540ms +1%
vue-large-graph-pan: script duration 895ms 880ms -2%
vue-large-graph-pan: TBT 0ms 0ms +0%
vue-large-graph-pan: heap used 165.9 MB 164.2 MB -1%
vue-large-graph-pan: DOM nodes -8331 -8331 +0%
vue-large-graph-pan: event listeners -16464 -16462 -0%
workflow-execution: avg frame time 17ms 17ms -0% z=-0.4
workflow-execution: p95 frame time 17ms 17ms +0%
workflow-execution: layout duration 1ms 1ms -3% z=-1.2
workflow-execution: style recalc duration 27ms 23ms -14% z=-0.4
workflow-execution: layout count 5 5 +0% z=0.1
workflow-execution: style recalc count 18 19 +6% z=0.6
workflow-execution: task duration 131ms 123ms -7% z=-0.0
workflow-execution: script duration 30ms 30ms -1% z=0.2
workflow-execution: TBT 0ms 0ms +0%
workflow-execution: heap used 47.0 MB 46.2 MB -2%
workflow-execution: DOM nodes 156 159 +2% z=-0.3
workflow-execution: event listeners 71 71 +0% z=4.4
Historical variance (last 15 runs)
Metric μ σ CV
canvas-idle: avg frame time 17ms 0ms 0.0%
canvas-idle: layout duration 0ms 0ms 0.0%
canvas-idle: style recalc duration 11ms 1ms 8.2%
canvas-idle: layout count 0 0 0.0%
canvas-idle: style recalc count 11 1 5.0%
canvas-idle: task duration 395ms 31ms 7.9%
canvas-idle: script duration 25ms 2ms 8.8%
canvas-idle: TBT 0ms 0ms 0.0%
canvas-idle: DOM nodes 23 1 5.6%
canvas-idle: event listeners 12 5 40.9%
canvas-mouse-sweep: avg frame time 17ms 0ms 0.0%
canvas-mouse-sweep: layout duration 4ms 0ms 5.4%
canvas-mouse-sweep: style recalc duration 43ms 3ms 7.4%
canvas-mouse-sweep: layout count 12 0 0.0%
canvas-mouse-sweep: style recalc count 79 2 3.0%
canvas-mouse-sweep: task duration 865ms 58ms 6.7%
canvas-mouse-sweep: script duration 136ms 6ms 4.8%
canvas-mouse-sweep: TBT 0ms 0ms 0.0%
canvas-mouse-sweep: DOM nodes 62 3 4.2%
canvas-mouse-sweep: event listeners 8 4 49.4%
canvas-zoom-sweep: avg frame time 17ms 0ms 0.0%
canvas-zoom-sweep: layout duration 1ms 0ms 7.0%
canvas-zoom-sweep: style recalc duration 19ms 2ms 8.0%
canvas-zoom-sweep: layout count 6 0 0.0%
canvas-zoom-sweep: style recalc count 31 0 1.5%
canvas-zoom-sweep: task duration 327ms 23ms 7.1%
canvas-zoom-sweep: script duration 27ms 3ms 11.1%
canvas-zoom-sweep: TBT 0ms 0ms 0.0%
canvas-zoom-sweep: DOM nodes 79 1 1.0%
canvas-zoom-sweep: event listeners 24 5 21.8%
dom-widget-clipping: avg frame time 17ms 0ms 0.0%
dom-widget-clipping: layout duration 0ms 0ms 0.0%
dom-widget-clipping: style recalc duration 10ms 1ms 8.0%
dom-widget-clipping: layout count 0 0 0.0%
dom-widget-clipping: style recalc count 13 0 3.8%
dom-widget-clipping: task duration 365ms 16ms 4.5%
dom-widget-clipping: script duration 68ms 3ms 4.8%
dom-widget-clipping: TBT 0ms 0ms 0.0%
dom-widget-clipping: DOM nodes 22 1 6.4%
dom-widget-clipping: event listeners 8 6 81.2%
large-graph-idle: avg frame time 17ms 0ms 0.0%
large-graph-idle: layout duration 0ms 0ms 0.0%
large-graph-idle: style recalc duration 12ms 1ms 8.6%
large-graph-idle: layout count 0 0 0.0%
large-graph-idle: style recalc count 12 0 2.7%
large-graph-idle: task duration 542ms 54ms 10.0%
large-graph-idle: script duration 102ms 11ms 10.3%
large-graph-idle: TBT 0ms 0ms 0.0%
large-graph-idle: DOM nodes 25 1 3.7%
large-graph-idle: event listeners 26 6 23.2%
large-graph-pan: avg frame time 17ms 0ms 0.0%
large-graph-pan: layout duration 0ms 0ms 0.0%
large-graph-pan: style recalc duration 17ms 1ms 4.6%
large-graph-pan: layout count 0 0 0.0%
large-graph-pan: style recalc count 70 1 0.9%
large-graph-pan: task duration 1082ms 43ms 4.0%
large-graph-pan: script duration 408ms 20ms 4.8%
large-graph-pan: TBT 0ms 0ms 0.0%
large-graph-pan: DOM nodes 19 2 8.7%
large-graph-pan: event listeners 5 1 16.8%
minimap-idle: avg frame time 17ms 0ms 0.0%
minimap-idle: layout duration 0ms 0ms 0.0%
minimap-idle: style recalc duration 10ms 1ms 8.6%
minimap-idle: layout count 0 0 0.0%
minimap-idle: style recalc count 10 1 7.1%
minimap-idle: task duration 527ms 47ms 9.0%
minimap-idle: script duration 98ms 10ms 10.1%
minimap-idle: TBT 0ms 0ms 0.0%
minimap-idle: DOM nodes 19 1 7.1%
minimap-idle: event listeners 5 1 14.4%
subgraph-dom-widget-clipping: avg frame time 17ms 0ms 0.0%
subgraph-dom-widget-clipping: layout duration 0ms 0ms 0.0%
subgraph-dom-widget-clipping: style recalc duration 13ms 1ms 7.4%
subgraph-dom-widget-clipping: layout count 0 0 0.0%
subgraph-dom-widget-clipping: style recalc count 48 1 1.2%
subgraph-dom-widget-clipping: task duration 378ms 18ms 4.9%
subgraph-dom-widget-clipping: script duration 128ms 6ms 4.9%
subgraph-dom-widget-clipping: TBT 0ms 0ms 0.0%
subgraph-dom-widget-clipping: DOM nodes 22 1 5.0%
subgraph-dom-widget-clipping: event listeners 16 6 36.0%
subgraph-idle: avg frame time 17ms 0ms 0.0%
subgraph-idle: layout duration 0ms 0ms 0.0%
subgraph-idle: style recalc duration 10ms 1ms 7.5%
subgraph-idle: layout count 0 0 0.0%
subgraph-idle: style recalc count 11 1 6.0%
subgraph-idle: task duration 370ms 31ms 8.5%
subgraph-idle: script duration 20ms 3ms 13.2%
subgraph-idle: TBT 0ms 0ms 0.0%
subgraph-idle: DOM nodes 22 1 6.9%
subgraph-idle: event listeners 10 7 64.5%
subgraph-mouse-sweep: avg frame time 17ms 0ms 0.0%
subgraph-mouse-sweep: layout duration 5ms 0ms 6.8%
subgraph-mouse-sweep: style recalc duration 42ms 3ms 7.8%
subgraph-mouse-sweep: layout count 16 0 0.0%
subgraph-mouse-sweep: style recalc count 80 2 2.4%
subgraph-mouse-sweep: task duration 766ms 69ms 9.0%
subgraph-mouse-sweep: script duration 101ms 7ms 6.5%
subgraph-mouse-sweep: TBT 0ms 0ms 0.0%
subgraph-mouse-sweep: DOM nodes 67 2 3.3%
subgraph-mouse-sweep: event listeners 8 4 52.6%
workflow-execution: avg frame time 17ms 0ms 0.0%
workflow-execution: layout duration 2ms 0ms 9.4%
workflow-execution: style recalc duration 24ms 2ms 9.1%
workflow-execution: layout count 5 1 11.0%
workflow-execution: style recalc count 18 2 11.5%
workflow-execution: task duration 123ms 11ms 8.8%
workflow-execution: script duration 29ms 3ms 10.2%
workflow-execution: TBT 0ms 0ms 0.0%
workflow-execution: DOM nodes 161 7 4.4%
workflow-execution: event listeners 52 4 8.4%
Trend (last 15 commits on main)
Metric Trend Dir Latest
canvas-idle: avg frame time ▆▃▆▁▆▃▆█▆▆▄▃▃▄▃ ➡️ 17ms
canvas-idle: p95 frame time ➡️ NaNms
canvas-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-idle: style recalc duration ▇▇▆▆▃█▄▃▄▃▇▄▁▆▇ ➡️ 11ms
canvas-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
canvas-idle: style recalc count █▃▅▂▅▆▃▁▂▁▂▅▆▅▆ ➡️ 12
canvas-idle: task duration ▃▃▃▆▂▃▃▅▆▂█▃▁▃▃ ➡️ 391ms
canvas-idle: script duration ▄▃▅▇▂▅▃▆▇▅█▄▁▅▆ ➡️ 27ms
canvas-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-idle: heap used ➡️ NaN MB
canvas-idle: DOM nodes █▇▆▅▃▇▃▁▂▂▅▆▆▆▇ ➡️ 24
canvas-idle: event listeners ▅█▅▄▁▅▁▁▁▄▅▅▁▅▄ 📉 11
canvas-mouse-sweep: avg frame time ▆█▆▃▁▃▁▆▆▁▃▆▆▃▃ ➡️ 17ms
canvas-mouse-sweep: p95 frame time ➡️ NaNms
canvas-mouse-sweep: layout duration ▁▃▂▄▁▂▁▃▆▂█▇▆▄▃ ➡️ 4ms
canvas-mouse-sweep: style recalc duration ▄▄▂▄▁▂▃▃▅▄█▆▂▄▄ ➡️ 43ms
canvas-mouse-sweep: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 12
canvas-mouse-sweep: style recalc count █▅▄▃▂▂▁▄▄▅▆▅▂▇▄ ➡️ 79
canvas-mouse-sweep: task duration █▆▄▂▂▃▂▄▄▅█▆▁▆▄ ➡️ 868ms
canvas-mouse-sweep: script duration ▄▅▄▆▄▆▆▆▅▅█▆▁▅▆ ➡️ 139ms
canvas-mouse-sweep: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-mouse-sweep: heap used ➡️ NaN MB
canvas-mouse-sweep: DOM nodes █▅▃▃▁▂▂▃▂▄▆▅▃▅▅ ➡️ 64
canvas-mouse-sweep: event listeners █▁▁▁▁▁▇▁▁▁██▇▁█ 📈 13
canvas-zoom-sweep: avg frame time ▅▅█▄▅▁▁▁▅▁▁▅▄▅▁ ➡️ 17ms
canvas-zoom-sweep: p95 frame time ➡️ NaNms
canvas-zoom-sweep: layout duration ▆▅▅▄▁▁█▅▃▅▇▆▁▂▆ ➡️ 1ms
canvas-zoom-sweep: style recalc duration ▆▅▄▆▅▃█▆▇▅▇▄▁▃▅ ➡️ 20ms
canvas-zoom-sweep: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 6
canvas-zoom-sweep: style recalc count ▁▁▃▄▆▃▆█▄▄▆▁▆▁▆ ➡️ 32
canvas-zoom-sweep: task duration ▄▂▁▇▂▂▄▅▆▃█▄▁▁▅ ➡️ 338ms
canvas-zoom-sweep: script duration ▃▃▂▇▂▂▅▇▆▅█▄▁▂▆ ➡️ 30ms
canvas-zoom-sweep: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
canvas-zoom-sweep: heap used ➡️ NaN MB
canvas-zoom-sweep: DOM nodes ▄▃▁▅█▁▃▆▄▅▅▃▃▄▃ ➡️ 79
canvas-zoom-sweep: event listeners ▁▁▂▅█▂▁▅▁▅▅▄▁▅▁ ➡️ 19
dom-widget-clipping: avg frame time ▂▄▅▅▂▄█▇▅▇▇▅▅▁▇ ➡️ 17ms
dom-widget-clipping: p95 frame time ➡️ NaNms
dom-widget-clipping: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
dom-widget-clipping: style recalc duration ▆▆▂▆▄▃██▄▁▆▇▆▃▅ ➡️ 10ms
dom-widget-clipping: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
dom-widget-clipping: style recalc count ▇█▅█▅▄█▇▇▁▇▄▇▂▅ ➡️ 13
dom-widget-clipping: task duration ▃▃▁▅▄▃▅▆▅▂▇█▁▅▅ ➡️ 371ms
dom-widget-clipping: script duration ▅▄▄▆▆▅▇▇▆▃█▇▁▇▇ ➡️ 71ms
dom-widget-clipping: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
dom-widget-clipping: heap used ➡️ NaN MB
dom-widget-clipping: DOM nodes ▇▇▄▇▅▄█▇▅▁▅▄▇▃▄ ➡️ 21
dom-widget-clipping: event listeners ▅▅▅▅▁▅██▁▁▁▁█▁▁ 📉 2
large-graph-idle: avg frame time ▅▅▅▅▅▂▁▂▄▅▄▂▂▅█ ➡️ 17ms
large-graph-idle: p95 frame time ➡️ NaNms
large-graph-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-idle: style recalc duration ▅▅▅▆▄▅▃▄▅▅▆█▁▄▆ ➡️ 13ms
large-graph-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
large-graph-idle: style recalc count █▆█▃▃▁▃▆▃▆▆▃▆██ ➡️ 12
large-graph-idle: task duration ▂▃▂▆▂▃▃▇▅▃██▁▂▅ ➡️ 569ms
large-graph-idle: script duration ▄▅▄▆▄▅▅▇▆▅█▆▁▃▆ ➡️ 110ms
large-graph-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-idle: heap used ➡️ NaN MB
large-graph-idle: DOM nodes ▆█▅▂▅▃▁▂▃▅▅▆▂▆▅ ➡️ 25
large-graph-idle: event listeners ███▇██▄▁▄▇▇█▂█▇ ➡️ 29
large-graph-pan: avg frame time ▆▃▃▆█▃▁█▆▆▆▆█▁▆ ➡️ 17ms
large-graph-pan: p95 frame time ➡️ NaNms
large-graph-pan: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-pan: style recalc duration ▃▂▄▄▁▅▂▂▁▄▄█▃▁▂ ➡️ 17ms
large-graph-pan: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
large-graph-pan: style recalc count ▆▃█▂▃▂▂▂▁▇▅▃█▆▃ ➡️ 69
large-graph-pan: task duration ▄▃▄▆▄▄▄▆▄▄█▆▁▂▅ ➡️ 1100ms
large-graph-pan: script duration ▅▄▅▆▆▅▄▆▄▅█▄▁▄▅ ➡️ 413ms
large-graph-pan: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
large-graph-pan: heap used ➡️ NaN MB
large-graph-pan: DOM nodes ▅▃▆▂▄▁▃▁▁▅▁▂█▅▂ ➡️ 18
large-graph-pan: event listeners █▆█▁▁▆▁▁▃▆▁▃██▃ ➡️ 5
minimap-idle: avg frame time ▃▆▆▃█▁█▆▆▃▃▆█▆█ ➡️ 17ms
minimap-idle: p95 frame time ➡️ NaNms
minimap-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
minimap-idle: style recalc duration ▄█▁█▅▅█▅▅▃▅▁▁▄▆ ➡️ 10ms
minimap-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
minimap-idle: style recalc count ▃▅▂▄█▃▆▁▂▅▂▁▅▆▃ ➡️ 9
minimap-idle: task duration ▃▄▁▅▁▃▄▅▇▃█▅▁▁▅ ➡️ 547ms
minimap-idle: script duration ▄▆▃▇▃▅▆▆▇▅█▅▁▃▆ ➡️ 106ms
minimap-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
minimap-idle: heap used ➡️ NaN MB
minimap-idle: DOM nodes ▃▅▂▄█▃▆▁▂▅▂▁▅▆▃ ➡️ 19
minimap-idle: event listeners ▃▃▆▁▁▁▃▁▁▆▁▃█▆▁ ➡️ 4
subgraph-dom-widget-clipping: avg frame time ▅▄▄▄▄▄█▄▄▄▃▁▆▃▃ ➡️ 17ms
subgraph-dom-widget-clipping: p95 frame time ➡️ NaNms
subgraph-dom-widget-clipping: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-dom-widget-clipping: style recalc duration ▂▄▃▅▅▃▂▅▇▃▄█▁▄▆ ➡️ 14ms
subgraph-dom-widget-clipping: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
subgraph-dom-widget-clipping: style recalc count ▇█▆▃▆▃▁▆█▇▃▆▇█▅ ➡️ 48
subgraph-dom-widget-clipping: task duration ▂▃▃▆▅▅▂▅█▂▆█▁▂▇ ➡️ 398ms
subgraph-dom-widget-clipping: script duration ▃▃▃▄▅▅▂▄█▂▅▇▁▂▅ ➡️ 131ms
subgraph-dom-widget-clipping: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-dom-widget-clipping: heap used ➡️ NaN MB
subgraph-dom-widget-clipping: DOM nodes ▅▇▅▂▅▂▁▅▅▅▁▇▅█▄ ➡️ 22
subgraph-dom-widget-clipping: event listeners ▅▅▅▂▅▁▅██▁▁█▅█▅ 📈 16
subgraph-idle: avg frame time ▆▆█▁▆▃▆▆▆▃▆▁▃▆█ ➡️ 17ms
subgraph-idle: p95 frame time ➡️ NaNms
subgraph-idle: layout duration ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-idle: style recalc duration ▁▇▃▆▂▄▂▃▃▆▆▄▃▇█ ➡️ 12ms
subgraph-idle: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0
subgraph-idle: style recalc count ▃▆▃▃▂▅▁▂▁▆▃▃██▇ ➡️ 12
subgraph-idle: task duration ▁▃▁▇▁▁▃▆▅▂█▅▁▁▄ ➡️ 378ms
subgraph-idle: script duration ▁▃▂▇▁▂▃▇▆▂█▅▂▁▅ ➡️ 22ms
subgraph-idle: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-idle: heap used ➡️ NaN MB
subgraph-idle: DOM nodes ▃▅▃▂▁▄▁▂▁▅▃▂▇█▇ ➡️ 24
subgraph-idle: event listeners ▁▅▁▁▁▁▁▁▁▅▄▁███ 📈 21
subgraph-mouse-sweep: avg frame time ▅▄▁▃▃▄▆▄▆▃▃█▁▃▃ ➡️ 17ms
subgraph-mouse-sweep: p95 frame time ➡️ NaNms
subgraph-mouse-sweep: layout duration ▁▄▄▄▃▃▅▅▅▂█▇▂▃▆ ➡️ 5ms
subgraph-mouse-sweep: style recalc duration ▃▂▄▅▂▃▄▅█▃█▆▁▂▅ ➡️ 43ms
subgraph-mouse-sweep: layout count ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 16
subgraph-mouse-sweep: style recalc count ▅▂▅▅▁▄▃▅█▅▆▄▂▄▅ ➡️ 81
subgraph-mouse-sweep: task duration ▃▂▄▅▂▄▄▅▇▄█▆▁▃▅ ➡️ 785ms
subgraph-mouse-sweep: script duration ▄▅▄▇▅▅▆▇▆▅██▁▄▆ ➡️ 105ms
subgraph-mouse-sweep: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
subgraph-mouse-sweep: heap used ➡️ NaN MB
subgraph-mouse-sweep: DOM nodes ▅▁▄▅▁▄▃▃█▅▅▄▂▅▃ ➡️ 66
subgraph-mouse-sweep: event listeners ▇▁▂▇▁▂▂▂█▇▂▂▇▇▂ 📈 5
workflow-execution: avg frame time ▆▆▆▄▆▆▃▄▁▄█▆▅▄▆ ➡️ 17ms
workflow-execution: p95 frame time ➡️ NaNms
workflow-execution: layout duration ▁▆▁▃▂▄▃▂▃▃▅█▄▂▅ ➡️ 2ms
workflow-execution: style recalc duration ▃▇▅▇▁▅▆▇█▁██▂▄▆ ➡️ 25ms
workflow-execution: layout count ▁█▂▃▂▃▃▁▃▃▄▃▂▃▂ ➡️ 5
workflow-execution: style recalc count ▃█▅▇▁▄▅▆▅▅▅▅▄▄▂ ➡️ 15
workflow-execution: task duration ▂▅▄▅▁▄▆▆▆▁▇█▁▃▃ ➡️ 120ms
workflow-execution: script duration ▄▃▄▄▃▅▄▅▆▂▇█▁▃▄ ➡️ 29ms
workflow-execution: TBT ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ➡️ 0ms
workflow-execution: heap used ➡️ NaN MB
workflow-execution: DOM nodes ▂█▃▆▁▄▃▅▃█▃▃▄▃▁ ➡️ 152
workflow-execution: event listeners ▅███▁▅███▁██▅█▅ ➡️ 49
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
    }
  ]
}

Copy link
Copy Markdown
Contributor Author

@christian-byrne christian-byrne left a comment

Choose a reason for hiding this comment

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

Is there no types in ingest-types that we can use instead of the outdated/deprecated apiSchema.ts?

@christian-byrne
Copy link
Copy Markdown
Contributor Author

Re: the review comment about using ingest-types instead of apiSchema.ts

The @comfyorg/ingest-types codegen was explicitly filtering out all backend-mirrored endpoints (system_stats, object_info, etc.) with this comment:

// Exclude endpoints that overlap with ComfyUI Python backend.
// These are shared between local and cloud, with separate Zod
// schemas already maintained in src/schemas/apiSchema.ts.

Since the cloud ingest API is supposed to mirror the ComfyUI backend, #10697 removes those exclusion filters so the types get generated.

Plan:

  1. Merge refactor: include backend-mirrored endpoints in ingest-types codegen #10697 (adds backend types to ingest-types codegen)
  2. Update this PR to import SystemStats from @comfyorg/ingest-types instead of @/schemas/apiSchema

benceruleanlu
benceruleanlu previously approved these changes Mar 29, 2026
Comment on lines +13 to +22
// 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 })
)
```
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

note: comfyPageFixture navigates before test body, so this might need some updating

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

addressed in 09326d8 and 524c61f - added all 9 default workflow node definitions and consolidated to a single createMockNodeDefinitions factory with structuredClone for deep copy. tests can extend via overrides param.

@dante01yoon
Copy link
Copy Markdown
Collaborator

Checked ingest-types — it doesn't have equivalents for SystemStats or ComfyNodeDef. Those are frontend-specific Zod schemas not covered by the OpenAPI-generated package. The current imports from @/schemas/apiSchema and @/schemas/nodeDefSchema are the right ones to use here.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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

📥 Commits

Reviewing files that changed from the base of the PR and between f213c80 and 5efcd94.

📒 Files selected for processing (3)
  • browser_tests/fixtures/data/README.md
  • browser_tests/fixtures/data/nodeDefinitions.ts
  • browser_tests/fixtures/data/systemStats.ts
✅ Files skipped from review due to trivial changes (1)
  • browser_tests/fixtures/data/README.md

Copy link
Copy Markdown
Collaborator

@dante01yoon dante01yoon left a comment

Choose a reason for hiding this comment

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

left comments

}
}

export function createMockNodeDefinitions(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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'
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fixed in e205ae3 - switched to SystemStatsResponse from @comfyorg/ingest-types now that #10697 has landed.

experimental: false
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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()                  
  )                                                           
})     

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧩 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).

christian-byrne added a commit that referenced this pull request Mar 29, 2026
…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>
christian-byrne and others added 5 commits March 29, 2026 00:22
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>
Consolidates to single createMockNodeDefinitions factory function
with deep clone to prevent cross-test state leakage.

Addresses review feedback:
#10662 (comment)
#10662 (comment)
dante01yoon
dante01yoon previously approved these changes Mar 29, 2026
Copy link
Copy Markdown
Collaborator

@dante01yoon dante01yoon left a comment

Choose a reason for hiding this comment

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

Comment addressed.

@dante01yoon dante01yoon removed their assignment Mar 29, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
browser_tests/fixtures/data/nodeDefinitions.ts (1)

150-155: 🛠️ Refactor suggestion | 🟠 Major

Move factory logic out of fixtures/data (data-only directory).

createMockNodeDefinitions is executable helper logic in a folder reserved for static fixture data. Please move this factory to browser_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) in fixtures/data/ with no code or Playwright imports”. Based on learnings, pure utility functions with no Page dependency should live in browser_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

📥 Commits

Reviewing files that changed from the base of the PR and between 87119ab and 524c61f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • browser_tests/fixtures/data/README.md
  • browser_tests/fixtures/data/nodeDefinitions.ts
  • browser_tests/fixtures/data/systemStats.ts
  • package.json
✅ Files skipped from review due to trivial changes (2)
  • package.json
  • browser_tests/fixtures/data/README.md

@christian-byrne christian-byrne merged commit 04f90b7 into main Mar 29, 2026
37 checks passed
@christian-byrne christian-byrne deleted the mai-15-backend-data-fixtures branch March 29, 2026 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants