Skip to content

Conversation

@ohah
Copy link
Owner

@ohah ohah commented Feb 1, 2026

Add React DevTools Components and Profiler panels

Purpose

Add React DevTools Components and Profiler panels to the inspector so that React Native clients see the same tab set as the reference react-native-devtools-frontend. Panels are shown only when clientType=react-native (or clientId starts with rn-inspector-) and appear at the end of the tab bar. Rendering and functionality are working after the fixes below.

Description

Frontend (devtools-frontend)

  • panels/react_devtools: Components and Profiler views (from reference), registered with clientType === 'react-native' or clientId.startsWith('rn-inspector-'), order 1010/1011.
  • models/react_native: ReactDevToolsBindingsModel (CDP Runtime addBinding/bindingCalled).
  • third_party/react-devtools: React DevTools UI (bridge, store, initializeComponents, initializeProfiler).
  • React DevTools CSS: Use a content wrapper div so #clearView() never removes the <style> from contentElement; loader/error/DevTools UI render into the wrapper only.
  • CSP: In entrypoint HTML, add 'unsafe-eval' and blob: to script-src, and worker-src 'self' blob: so the React DevTools bundle (which uses new Function() and Worker from Blob) runs without EvalError/SecurityError.
  • devtools/bundled: Build output updated (includes react_devtools, react_native, third_party/react-devtools, CSP, and ReactDevToolsViewBase with wrapper fix).

Inspector

  • devtools-url: Pass clientId (and clientType) in the DevTools iframe URL so the panel condition shows Components/Profiler for RN clients.

react-native-inspector

  • Runtime.evaluate: Return the expression value (e.g. globalThis.x != undefinedtrue/false) so the frontend’s waitForFuseboxDispatcherToBeInitialized succeeds; previously the expression was run without returning its value, so the panel stayed empty.
  • Runtime.addBinding and Runtime.bindingCalled: Handle addBinding, register the binding name, and send Runtime.bindingCalled when the app invokes the binding.
  • Tests: Added tests for Runtime.evaluate returning expression value (e.g. 1+2 → 3, comparison → boolean); Runtime.addBinding and Runtime.bindingCalled (response + calling binding sends event with name, payload, executionContextId; object payload serialized as JSON string).

client

  • runtime.ts: Use indirect eval (0, eval)(...) to satisfy lint for expression evaluation.

Documentation

  • document/docs/en/guide/react-devtools-components-profiler.md: Step-by-step guide plus “Implementation status and fixes” (Runtime.evaluate return value, clientId in URL, CSP, CSS wrapper).
  • document/docs/en/api/domains/runtime.md and ko: Full Runtime protocol for react-native-inspector — Runtime.enable, executionContextCreated, getProperties, releaseObject (methods + wire format); "implemented in RN" full list; note that Runtime.callFunctionOn is not implemented.
  • .cursor/agents/sub-agent-react-native-devtools-frontend.mdc: Updated for Components/Profiler completion and maintenance.

How to test

  • From repo root: bun run build:devtools if devtools-frontend source or submodule changed.
  • Start server and inspector; connect a React Native client (DevTools URL must include clientType=react-native or clientId=rn-inspector-...).
  • Confirm Components and Profiler tabs appear at the end of the tab bar.
  • Open Components or Profiler: the panel should render with correct CSS and connect to the RN app (component tree / profiler UI) when the app has __FUSEBOX_REACT_DEVTOOLS_DISPATCHER__ and the React DevTools backend.

Additional info

  • Pre-commit: mise exec -- bun run format, mise exec -- bun run lint.
  • Test coverage: packages/react-native-inspector Runtime.evaluate, Runtime.addBinding / bindingCalled, and panel-related handler tests (cdp-message-handler.test.ts).

- Update devtools-frontend submodule with react_devtools panel, react_native
  model, third_party/react-devtools from reference
- Register panels in devtools_app; show only when clientType=react-native
- Add visibility for bindings/logs to react_devtools; grd and third_party
  readme paths
- Copy build output to devtools/bundled
- Add guide doc and sub-agent for react-native-devtools-frontend
- Panel order 1010/1011 so Components and Profiler appear at end of tabs
Copilot AI review requested due to automatic review settings February 1, 2026 08:00
@ohah ohah added the enhancement New feature or request label Feb 1, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds React DevTools Components and Profiler panels to the inspector, matching the reference react-native-devtools-frontend. The panels appear only when clientType=react-native and are positioned at the end of the tab bar (order 1010/1011).

Changes:

  • Updated devtools-frontend submodule to include react_devtools panels, models/react_native (ReactDevToolsBindingsModel), and third_party/react-devtools UI
  • Copied build output to devtools/bundled with all necessary TypeScript configs and resource files
  • Added comprehensive documentation guide for implementing React DevTools panels

Reviewed changes

Copilot reviewed 46 out of 91 changed files in this pull request and generated no comments.

Show a summary per file
File Description
devtools/devtools-frontend Submodule updated to commit with react_devtools panels and models
devtools/bundled/front_end/panels/react_devtools/* Built panel files for Components and Profiler views
devtools/bundled/front_end/models/react_native/* ReactDevToolsBindingsModel for CDP Runtime messaging
devtools/bundled/front_end/third_party/react-devtools/* React DevTools UI bundle (bridge, store, initializers)
devtools/bundled/front_end/entrypoints/devtools_app/* Updated to import new panel meta files
devtools/bundled/front_end/ui/visual_logging/* Added "sendFeedback" context value
devtools/bundled/front_end/devtools_resources.grd Resource file entries for new modules
document/docs/en/guide/react-devtools-components-profiler.md Implementation guide for React DevTools panels
document/docs/en/guide/_meta.json Navigation entry for new guide
.cursor/agents/sub-agent-react-native-devtools-frontend.mdc Agent ruleset for RN DevTools reference comparison

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…ing and docs

- react-native-inspector: Runtime.evaluate returns expression value so
  waitForFuseboxDispatcher succeeds; Runtime.addBinding/bindingCalled;
  tests for evaluate return value.
- inspector: pass clientId in DevTools URL for panel condition.
- client: use indirect eval in runtime.
- devtools bundled: CSP (unsafe-eval, blob, worker-src) and
  ReactDevToolsViewBase content wrapper so CSS is never cleared.
- docs: guide updated with implementation status and fixes.
@github-actions
Copy link

github-actions bot commented Feb 1, 2026

📊 Test Coverage Report - Client

Summary

Metric Coverage
Functions 72.55%
Lines 73.23%

File Coverage

Click to expand
File Functions Lines Uncovered Lines
happydom.ts 100.00% 100.00% N/A
packages/client/src/cdp/domain/common/node-manager.ts 100.00% 100.00% N/A
packages/client/src/cdp/domain/index.ts 100.00% 100.00% N/A
packages/client/src/cdp/domain/protocol.ts 100.00% 100.00% N/A
packages/client/src/cdp/domain/storage/index.ts 100.00% 100.00% N/A
packages/client/src/core/cdp-client.ts 90.91% 100.00% N/A
packages/client/src/utils/debug-id.ts 100.00% 100.00% N/A
packages/client/src/utils/page-info.ts 100.00% 100.00% N/A
packages/client/src/cdp/domain/css/utils.ts 93.33% 97.87% 68,246,282
packages/client/src/cdp/domain/page.ts 77.78% 97.10% 1-2
packages/client/src/cdp/common/remoteObject.ts 100.00% 93.19% 105-118,240
packages/client/src/connection/postmessage-handler.ts 90.00% 92.71% 155-161
packages/client/src/cdp/domain/runtime.ts 92.86% 91.53% 172-181
packages/client/src/cdp/index.ts 70.00% 90.28% 63-68
packages/client/src/cdp/domain/css/index.ts 80.77% 88.30% 58-82,95,113-118
packages/client/src/cdp/domain/base.ts 72.22% 88.10% 101-103,132-137,161-166
packages/client/src/connection/websocket-client.ts 87.50% 78.92% 159-195,250
packages/client-rrweb/src/buffer.ts 60.00% 78.57% 24-25
packages/client/src/cdp/common/utils.ts 90.91% 75.68% 28,30-37
packages/client/src/persistence/event-storage.ts 79.49% 74.23% 60-61,162,186,189-223,255,356-370,481,580,625,657,688,720,768,804,807-901
packages/client/src/persistence/compression.ts 87.50% 72.09% 16,31-32,44,60-61,71-76
packages/client/src/cdp/domain/css/stylesheet.ts 85.00% 71.30% 26-32,56-58,117,148,151-157,160,162-165,204,206,254,271-309
packages/client/src/initialization/rrweb-init.ts 40.00% 70.59% 31,40-47,80,89,91,95-97
packages/client/src/cdp/domain/console.ts 66.67% 70.00% 1-4
packages/client/src/cdp/domain/session-replay.ts 41.67% 65.71% 19-22,36-38,41-46,56,62-78,91-95
packages/client-rrweb/src/index.ts 56.25% 65.38% 20,47-57,71,81-85,105-114,118-119,129,132,141-144
packages/client-rrweb/src/transport/cdp.ts 50.00% 45.45% 11-16
packages/client/src/cdp/domain/storage/dom-storage.ts 54.17% 42.64% 25,69-83,88-103,108-119,125-131,136-146,186-189,267-277,282-292,300-363
packages/client/src/cdp/domain/network.ts 73.91% 33.62% 67-75,152-157,204-249,274-454,462-521,566-577
packages/client/src/cdp/domain/dom.ts 50.00% 32.05% 8-12,123-129,175-206,211-224,229-240,245-269,275-279,284-290,336-340,345-350,355-415,420-427,432-441,447-554,579-591
packages/client/src/initialization/client-init.ts 33.33% 30.77% 19,21,23,25-29
packages/client/src/index.ts 0.00% 18.33% 27-38,46-70,77-88
packages/client/src/cdp/domain/storage/storage.ts 33.33% 10.67% 1-3,12-76
packages/client-rrweb/src/transport/ws.ts 0.00% 0.00% 6-22

Generated by test coverage script

@github-actions
Copy link

github-actions bot commented Feb 1, 2026

📊 Test Coverage Report - React Native Inspector

Summary

Metric Coverage
Functions 95.27%
Lines 83.62%

File Coverage

Click to expand
File Functions Lines Uncovered Lines
happydom.ts 100.00% 100.00% N/A
packages/react-native-inspector/src/cdp-message-handler.ts 100.00% 100.00% N/A
packages/react-native-inspector/src/cdp/common/object-store.ts 100.00% 100.00% N/A
packages/react-native-inspector/src/cdp/domain/protocol.ts 100.00% 100.00% N/A
packages/react-native-inspector/src/cdp/domain/runtime.ts 100.00% 96.08% 137,139-142
packages/react-native-inspector/src/metro-config.cjs 100.00% 92.86% 33,35-36
packages/react-native-inspector/src/server-info.ts 100.00% 92.31% N/A
packages/react-native-inspector/src/cdp/common/get-object-properties.ts 100.00% 91.43% 31,39
packages/react-native-inspector/src/utils.ts 100.00% 90.91% 14-15
packages/react-native-inspector/src/cdp/common/value-to-remote-object.ts 100.00% 90.23% 53,56,66,69,73,76,81-82,84-85,102,196-197
packages/react-native-inspector/src/redux-devtools-extension.ts 82.35% 87.89% 109-110,120-121,123-124,126,131,146-147,158-165,168-179,189,191,196-200,498-501,554,558,560-562
packages/react-native-inspector/src/cdp/domain/base.ts 100.00% 80.43% 45,58-62,69-71
packages/react-native-inspector/src/device-id.ts 83.33% 73.08% 20,61,72-76,78-80,82-85
packages/react-native-inspector/src/cdp/domain/network.ts 76.92% 68.50% 21-22,37,67,100-114,125,236-239,254-258,261-264,267-292,296-305,308-317,326-327,331-333,336-337,360,370-373,388,390-391,420-421,423-429,435,470,475-485,513-519,523-529,536,554,581-591
packages/react-native-inspector/src/cdp/domain/runtime-evaluate.ts 100.00% 62.50% 20,23,26,33-44,61-71,85-88,101,105-106,121,125-126
packages/react-native-inspector/src/cdp-message.ts 100.00% 56.25% 28-33
packages/react-native-inspector/src/websocket-client.ts 76.92% 39.05% 37-93,96-100,140-141

Generated by test coverage script

@github-actions
Copy link

github-actions bot commented Feb 1, 2026

📊 Test Coverage Report - Inspector

Summary

Metric Coverage
Functions 62.08%
Lines 67.52%

File Coverage

Click to expand
File Functions Lines Uncovered Lines
happydom.ts 100.00% 100.00% N/A
packages/inspector/src/app/providers/index.tsx 100.00% 100.00% N/A
packages/inspector/src/app/router.ts 100.00% 100.00% N/A
packages/inspector/src/entities/client/api/client.queries.ts 75.00% 100.00% N/A
packages/inspector/src/entities/client/api/get-clients.ts 100.00% 100.00% N/A
packages/inspector/src/entities/client/index.ts 100.00% 100.00% N/A
packages/inspector/src/features/client-list/index.ts 100.00% 100.00% N/A
packages/inspector/src/features/client-list/lib/filter-clients.ts 100.00% 100.00% N/A
packages/inspector/src/features/replay/lib/constants.ts 100.00% 100.00% N/A
packages/inspector/src/features/replay/lib/message-sender.ts 100.00% 100.00% N/A
packages/inspector/src/features/replay/lib/response-body-store.ts 100.00% 100.00% N/A
packages/inspector/src/features/settings/index.ts 100.00% 100.00% N/A
packages/inspector/src/routeTree.gen.ts 100.00% 100.00% N/A
packages/inspector/src/routes/devtools/$clientId.tsx 100.00% 100.00% N/A
packages/inspector/src/shared/api/query-client.ts 100.00% 100.00% N/A
packages/inspector/src/shared/lib/constants.ts 100.00% 100.00% N/A
packages/inspector/src/shared/lib/file-to-cdp.ts 100.00% 100.00% N/A
packages/inspector/src/shared/lib/index.ts 100.00% 100.00% N/A
packages/inspector/src/shared/lib/url-validation.ts 100.00% 100.00% N/A
packages/inspector/src/shared/ui/index.ts 100.00% 100.00% N/A
packages/inspector/src/shared/lib/devtools-url.ts 100.00% 96.97% N/A
packages/inspector/src/components/ui/button.tsx 0.00% 91.67% 40-42
packages/inspector/src/features/replay/lib/message-handlers.ts 92.86% 87.18% 44,209-227
packages/inspector/src/features/replay/lib/cdp-message-utils.ts 77.78% 85.45% 23,33-36,55,90
packages/inspector/src/features/replay/lib/message-sender-extended.ts 94.12% 85.21% 132-134,136-140,161-162,171-174,202,240,245-249
packages/inspector/src/features/replay/lib/extractors.ts 91.67% 83.54% 70,87-91,101,127-128,131-133,181,184-189,191-196
packages/inspector/src/shared/lib/server-url.ts 93.75% 76.39% 83,147-162
packages/inspector/src/lib/utils.ts 0.00% 66.67% N/A
packages/inspector/src/components/ui/tooltip.tsx 0.00% 47.62% 15-25
packages/inspector/src/routes/mode/$mode.tsx 0.00% 7.22% 15-21,27-199
packages/inspector/src/shared/ui/empty-states.tsx 0.00% 6.90% 7-12,29-49
packages/inspector/src/routes/index.tsx 0.00% 6.28% 18-226
packages/inspector/src/routes/__root.tsx 20.00% 5.46% 10-158,164-202,208-346,371-372
packages/inspector/src/routes/replay.tsx 0.00% 5.22% 21-238
packages/inspector/src/pages/devtools/index.tsx 0.00% 4.44% 15-18,25-278
packages/inspector/src/features/client-list/ui/client-filter.tsx 0.00% 3.45% 13-40
packages/inspector/src/components/tabs.tsx 0.00% 3.13% 20-81
packages/inspector/src/features/client-list/ui/client-table.tsx 0.00% 1.90% 11-113
packages/inspector/src/features/settings/ui/server-settings.tsx 0.00% 1.87% 10-114
packages/inspector/src/features/settings/ui/settings-modal.tsx 0.00% 1.79% 11-65
packages/inspector/src/features/client-list/ui/client-select.tsx 0.00% 0.00% 10-27

Generated by test coverage script

@github-actions
Copy link

github-actions bot commented Feb 1, 2026

Integration Tests

1 tests   1 ✅  18s ⏱️
1 suites  0 💤
1 files    0 ❌

Results for commit 03a18a7.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Feb 1, 2026

📊 Test Results

✅ Test Status: PASSED

📸 Screenshots

Screenshots are available as artifacts. Download them here.

Artifact name: playwright-screenshots

Screenshot files
  1. test-client-rn-2.png (test-client-rn-2)
  2. test-client-web-1.png (test-client-web-1)
  3. test-client-web-2.png (test-client-web-2)
  4. test-client-rn-1.png (test-client-rn-1)

…nt doc

- Document Runtime.enable, executionContextCreated, getProperties, releaseObject (methods + wire format) in en/ko runtime.md
- Note Runtime.callFunctionOn as not implemented in react-native-inspector
- Add implemented-in-RN full list (commands + events) to runtime.md
- Update sub-agent-react-native-devtools-frontend.mdc for Components/Profiler completion
@ohah ohah self-assigned this Feb 1, 2026
…d tests

- Add test: addBinding sends result and calling binding sends Runtime.bindingCalled with name, payload, executionContextId
- Add test: binding called with object sends JSON string payload (React DevTools wire format)
- Clean up installed bindings in afterEach
@ohah
Copy link
Owner Author

ohah commented Feb 1, 2026

AI review

Purpose and description

The PR purpose (adding React DevTools Components and Profiler panels for React Native clients) matches the changes. The description accurately covers frontend (devtools-frontend panels, models, CSP, CSS wrapper), Inspector (clientId in URL), react-native-inspector (Runtime.evaluate return value, addBinding/bindingCalled), client (indirect eval), and documentation. The latest commit adds tests for Runtime.addBinding and Runtime.bindingCalled, which is reflected in the PR body.

What's done well

  • Clear layering: Frontend (DevTools UI), Inspector (URL params), and react-native-inspector (CDP Runtime) are separated; Runtime protocol is documented in en/ko runtime.md with wire format and "implemented in RN" list.
  • React DevTools integration: Panel visibility gated by clientType === 'react-native' or clientId.startsWith('rn-inspector-'); Runtime.evaluate returns expression value so Fusebox init succeeds; addBinding/bindingCalled relay app ↔ frontend messages.
  • Fixes: CSS wrapper so #clearView() does not remove <style>; CSP updates for unsafe-eval and blob workers; indirect eval in client for lint.
  • Tests: cdp-message-handler tests cover Runtime.enable → executionContextCreated, getProperties, releaseObject, evaluate (value and boolean), and addBinding/bindingCalled (response + event with name/payload/executionContextId; object payload as JSON string). AfterEach cleans up installed bindings.
  • Docs: Guide (react-devtools-components-profiler), API runtime domain (full protocol), and sub-agent mdc are updated.

Improvement suggestions

  • Submodule: devtools-frontend is included in the PR; if the team usually merges submodule updates separately, consider documenting that or splitting. No code change required.
  • Edge case: Runtime.addBinding with empty/invalid name still sends empty result (no error); this is consistent with the current implementation and is acceptable.
  • Optional: Adding a short note in the guide or runtime.md that React DevTools Fusebox message format ({ domain, message }) is defined upstream could help future maintainers; already linked in runtime.md.

Testing

  • Run mise exec -- bun test packages/react-native-inspector/src/__tests__/cdp-message-handler.test.ts — 17 tests pass, including the two new addBinding/bindingCalled tests.
  • Manual: build devtools, start server and inspector, connect RN client with clientType=react-native or clientId=rn-inspector-..., confirm Components and Profiler tabs render and connect when the app has the Fusebox dispatcher.

Overall the PR is in good shape for merge; purpose, implementation, docs, and tests are aligned.

@github-actions
Copy link

github-actions bot commented Feb 1, 2026

📱 Maestro Android Test Results

PASSED

Maestro Android tests have completed. Check the workflow run for details.

@ohah ohah merged commit 75dd34e into main Feb 1, 2026
20 checks passed
@ohah ohah deleted the feat/react-devtools-components-profiler branch February 1, 2026 09:38
@github-actions
Copy link

github-actions bot commented Feb 1, 2026

📱 Maestro iOS Test Results

PASSED

Maestro iOS tests have completed. Check the workflow run for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants