Commit Graph

38 Commits

Author SHA1 Message Date
Ruslan Lesiutin 2eed132847 refactor[devtools/extension]: more stable element updates polling to avoid timed out errors (#27357)
Some context:
- When user selects an element in tree inspector, we display current
state of the component. In order to display really current state, we
start polling the backend to get available updates for the element.

Previously:
- Straight-forward sending an event to get element updates each second.
Potential race condition is not handled in any form.
- If user navigates from the page, timeout wouldn't be cleared and we
would potentially throw "Timed out ..." error.
- Bridge disconnection is not handled in any form, if it was shut down,
we could spam with "Timed out ..." errors.

With these changes:
- Requests are now chained, so there can be a single request at a time.
- Handling both navigation and shut down events.

This should reduce the number of "Timed out ..." errors that we see in
our logs for the extension. Other surfaces will also benefit from it,
but not to the full extent, as long as they utilize
"resumeElementPolling" and "pauseElementPolling" events.

Tested this on Chrome, running React DevTools on multiple tabs,
explicitly checked the case when service worker is in idle state and we
return back to the tab.
2023-09-12 15:05:39 +01:00
Ruslan Lesiutin 21021fb0f0 refactor[devtools]: copy to clipboard only on frontend side (#26604)
Fixes https://github.com/facebook/react/issues/26500

## Summary
- No more using `clipboard-js` from the backend side, now emitting
custom `saveToClipboard` event, also adding corresponding listener in
`store.js`
- Not migrating to `navigator.clipboard` api yet, there were some issues
with using it on Chrome, will add more details to
https://github.com/facebook/react/pull/26539

## How did you test this change?
- Tested on Chrome, Firefox, Edge
- Tested on standalone electron app: seems like context menu is not
expected to work there (cannot right-click on value, the menu is not
appearing), other logic (pressing on copy icon) was not changed
2023-04-12 16:12:03 +01:00
Jan Kassens afea1d0c53 [flow] make Flow suppressions explicit on the error (#26487)
Added an explicit type to all $FlowFixMe suppressions to reduce
over-suppressions of new errors that might be caused on the same lines.

Also removes suppressions that aren't used (e.g. in a `@noflow` file as
they're purely misleading)

Test Plan:
yarn flow-ci
2023-03-27 13:43:04 +02:00
Andrew Clark 44d3807945 Move internalAct to internal-test-utils package (#26344)
This is not a public API. We only use it for our internal tests, the
ones in this repo. Let's move it to this private package. Practically
speaking this will also let us use async/await in the implementation.
2023-03-08 12:58:31 -05:00
Andrew Clark 702fc984e6 Codemod act -> await act (4/?) (#26338)
Similar to the rationale for `waitFor` (see #26285), we should always
await the result of an `act` call so that microtasks have a chance to
fire.

This only affects the internal `act` that we use in our repo, for now.
In the public `act` API, we don't yet require this; however, we
effectively will for any update that triggers suspense once `use` lands.
So we likely will start warning in an upcoming minor.
2023-03-08 11:36:05 -05:00
Ming Ye 71cace4d32 Migrate testRunner from jasmine2 to jest-circus (#26144)
## Summary

In jest v27, jest-circus as default test runner
(https://github.com/facebook/jest/pull/10686)

## How did you test this change?

ci green
2023-02-10 13:39:14 -05:00
Ming Ye 55542bc73d Update jest printBasicPrototype config (#26142) 2023-02-10 09:58:57 +01:00
Ming Ye 35698311de Update jest escapeString config (#26140)
## Summary

In jest v29, snapshotFormat default to escapeString:
false(https://github.com/facebook/jest/pull/13036)

## How did you test this change?

ci green
2023-02-10 00:08:37 +01:00
Jan Kassens 6b30832666 Upgrade prettier (#26081)
The old version of prettier we were using didn't support the Flow syntax
to access properties in a type using `SomeType['prop']`. This updates
`prettier` and `rollup-plugin-prettier` to the latest versions.

I added the prettier config `arrowParens: "avoid"` to reduce the diff
size as the default has changed in Prettier 2.0. The largest amount of
changes comes from function expressions now having a space. This doesn't
have an option to preserve the old behavior, so we have to update this.
2023-01-31 08:25:05 -05:00
Andrew Clark 9cdf8a99ed [Codemod] Update copyright header to Meta (#25315)
* Facebook -> Meta in copyright

rg --files | xargs sed -i 's#Copyright (c) Facebook, Inc. and its affiliates.#Copyright (c) Meta Platforms, Inc. and affiliates.#g'

* Manual tweaks
2022-10-18 11:19:24 -04:00
Vic Graf 5b59dd6400 Fix duplicate words tests (#25333)
* refactor: removed duplicated words in comments
* refactor: removed duplicate words in tests
2022-09-27 10:07:06 -04:00
Mengdi "Monday" Chen e531a4a62d [React DevTools] Improve DevTools UI when Inspecting a user Component that Throws an Error (#24248)
* [ReactDevTools] custom view for errors occur in user's code

* [ReactDevTools] show message for unsupported feature

* fix bad import

* fix typo

* fix issues from rebasing

* prettier

* sync error names

* sync error name with upstream

* fix lint & better comment

* fix error message for test

* better error message per review

* add missing file

* remove dead enum & provide component name in error message

* better error message

* better user facing error message
2022-05-05 20:17:23 -04:00
Mengdi "Monday" Chen c89a15c716 [ReactDebugTools] wrap uncaught error from rendering user's component (#24216)
* [ReactDebugTools] wrap uncaught error from rendering user's component

* fix lint

* make error names more package specific

* update per review comments

* fix tests

* fix lint

* fix tests

* fix lint

* fix error name & nits

* try catch instead of mocking error

* fix test for older node.js version

* avoid false positive from try-catch in tests
2022-04-01 14:38:11 -04:00
Luna Ruan 645ec5d6fc fix inspecting an element in a nested renderer bug (#24116)
Fixes this issue, where inspecting components in nested renderers results in an error. The reason for this is because we have different fiberToIDMap instances for each renderer, and owners of a component could be in different renderers.

This fix moves the fiberToIDMap and idToArbitraryFiberMap out of the attach method so there's only one instance of each for all renderers.
2022-03-17 15:40:03 -04:00
Sebastian Silbermann 2bf7c02f0e Don't hide console error|warn in inspectedElement-test (#24086) 2022-03-14 09:17:37 -04:00
Andrew Clark 061ac27bc9 Fix use of hydrateRoot in DevTools test (#24084)
I noticed while working on a different PR that this test was not
using hydrateRoot correctly. You're meant to pass the initial children
as the second argument.
2022-03-12 19:21:58 -05:00
Sebastian Markbåge 17806594cc Move createRoot/hydrateRoot to react-dom/client (#23385)
* Move createRoot/hydrateRoot to /client

We want these APIs ideally to be imported separately from things you
might use in arbitrary components (like flushSync). Those other methods
are "isomorphic" to how the ReactDOM tree is rendered. Similar to hooks.

E.g. importing flushSync into a component that only uses it on the client
should ideally not also pull in the entry client implementation on the
server.

This also creates a nicer parity with /server where the roots are in a
separate entry point.

Unfortunately, I can't quite do this yet because we have some legacy APIs
that we plan on removing (like findDOMNode) and we also haven't implemented
flushSync using a flag like startTransition does yet.

Another problem is that we currently encourage these APIs to be aliased by
/profiling (or unstable_testing). In the future you don't have to alias
them because you can just change your roots to just import those APIs and
they'll still work with the isomorphic forms. Although we might also just
use export conditions for them.

For that all to work, I went with a different strategy for now where the
real API is in / but it comes with a warning if you use it. If you instead
import /client it disables the warning in a wrapper. That means that if you
alias / then import /client that will inturn import the alias and it'll
just work.

In a future breaking changes (likely when we switch to ESM) we can just
remove createRoot/hydrateRoot from / and move away from the aliasing
strategy.

* Update tests to import from react-dom/client

* Fix fixtures

* Update warnings

* Add test for the warning

* Update devtools

* Change order of react-dom, react-dom/client alias

I think the order matters here. The first one takes precedence.

* Require react-dom through client so it can be aliased

Co-authored-by: Andrew Clark <git@andrewclark.io>
2022-03-01 00:13:28 -05:00
Brian Vaughn 3d1e7e7278 Suppress act() warnings in DevTools tests (#23192)
These warnings are not useful for DevTools tests– and sometimes may mask other, important warnings. This commit disables them.
2022-01-26 15:18:21 -05:00
Andrew Clark 996da67b29 Replace global jest heuristic with IS_REACT_ACT_ENVIRONMENT (#22562)
* Remove `jest` global check in concurrent roots

In concurrent mode, instead of checking `jest`, we check the new
`IS_REACT_ACT_ENVIRONMENT` global. The default behavior is `false`.

Legacy mode behavior is unchanged.

React's own internal test suite use a custom version of `act` that works
by mocking the Scheduler — rather than the "real" act used publicly. So
we don't enable the flag in our repo.

* Warn if `act` is called in wrong environment

Adds a warning if `act` is called but `IS_REACT_ACT_ENVIRONMENT` is not
enabled. The goal is to prompt users to correctly configure their
testing environment, so that if they forget to use `act` in a different
test, we can detect and warn about.

It's expected that the environment flag will be configured by the
testing framework. For example, a Jest plugin. We will link to the
relevant documentation page, once it exists.

The warning only fires in concurrent mode. Legacy roots will keep the
existing behavior.
2021-10-18 08:59:18 -07:00
Brian Vaughn 8ee4ff8836 Surface backend errors during inspection in the frontend UI (#22546) 2021-10-13 10:35:21 -04:00
Brian Vaughn 47177247f8 DevTools: Fixed potential cache miss when insepcting elements (#22472) 2021-09-30 12:48:53 -04:00
Sebastian Silbermann 3ee7a004e5 devtools: Display actual ReactDOM API name in root type (#22363) 2021-09-20 11:44:21 -04:00
Brian Vaughn edfe50510b DevTools: Replaced WeakMap with LRU for inspected element cache (#22160)
We use an LRU for this rather than a WeakMap because of how the "no-change" optimization works.

When the frontend polls the backend for an update on the element that's currently inspected, the backend will send a "no-change" message if the element hasn't updated (rendered) since the last time it was asked. In thid case, the frontend cache should reuse the previous (cached) value. Using a WeakMap keyed on Element generally works well for this, since Elements are mutable and stable in the Store. This doens't work properly though when component filters are changed, because this will cause the Store to dump all roots and re-initialize the tree (recreating the Element objects).

So instead we key on Element ID (which is stable in this case) and use an LRU for eviction.
2021-08-23 19:22:31 -04:00
Brian Vaughn 6840c98c32 Remove named hooks feature flag (#21894) 2021-07-16 00:14:20 -04:00
Andrew Clark a4ecd85e86 act: Batch updates, even in legacy roots (#21797)
In legacy roots, if an update originates outside of `batchedUpdates`,
check if it's inside an `act` scope; if so, treat it as if it were
batched. This is only necessary in legacy roots because in concurrent
roots, updates are batched by default.

With this change, the Test Utils and Test Renderer versions of `act` are
nothing more than aliases of the isomorphic API (still not exposed, but
will likely be the recommended API that replaces the others).
2021-07-12 17:15:20 -07:00
Brian Vaughn c5cfa71948 DevTools: Show hook names based on variable usage (#21641)
Co-authored-by: Brian Vaughn <brian.david.vaughn@gmail.com>
Co-authored-by: Saphal Patro <saphal1998@gmail.com>
Co-authored-by: VibhorCodecianGupta <vibhordelgupta@gmail.com>
2021-07-01 14:39:18 -04:00
Brian Vaughn 73ffce1b6f DevTools: Update tests to fix warnings/errors (#21748)
Some new ones had slipped in (e.g. deprecated ReactDOM.render message from 18)
2021-06-24 22:42:44 -04:00
Andrew Clark d7dce572c7 Remove internal act builds from public modules (#21721)
* Move internal version of act to shared module

No reason to have three different copies of this anymore.

I've left the the renderer-specific `act` entry points because legacy
mode tests need to also be wrapped in `batchedUpdates`. Next, I'll update
the tests to use `batchedUpdates` manually when needed.

* Migrates tests to use internal module directly

Instead of the `unstable_concurrentAct` exports. Now we can drop those
from the public builds.

I put it in the jest-react package since that's where we put our other
testing utilities (like `toFlushAndYield`). Not so much so it can be
consumed publicly (nobody uses that package except us), but so it works
with our build tests.

* Remove unused internal fields

These were used by the old act implementation. No longer needed.
2021-06-22 14:29:35 -07:00
Brian Vaughn 01be61c12f DevTools can inspect Proxies that return broken iterator functions (#21660) 2021-06-11 10:15:48 -04:00
Andrew Clark aecb3b6d11 Deprecate ReactDOM.render and ReactDOM.hydrate (#21652)
* Use existing test warning filter for server tests

We have a warning filter for our internal tests to ignore warnings
that are too noisy or that we haven't removed from our test suite yet:
shouldIgnoreConsoleError.

Many of our server rendering tests don't use this filter, though,
because it has its own special of asserting warnings.

So I added the warning filter to the server tests, too.

* Deprecate ReactDOM.render and ReactDOM.hydrate

These are no longer supported in React 18. They are replaced by the
`createRoot` API.

The warning includes a link to documentation of the new API. Currently
it redirects to the corresponding working group post. Here's the PR to
set up the redirect: https://github.com/reactjs/reactjs.org/pull/3730

Many of our tests still use ReactDOM.render. We will need to gradually
migrate them over to createRoot.

In the meantime, I added the warnings to our internal warning filter.
2021-06-09 13:46:55 -07:00
Bao Pham 8b4201535c Devtools: add feature to trigger an error boundary (#21583)
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2021-06-03 11:21:44 -04:00
Brian Vaughn b8bbb6a13d Fix edge-case Fast Refresh bug that caused Fibers with warnings/errors to be untracked prematurely (#21536)
Refactor error/warning count tracking to avoid pre-allocating an ID for Fibers that aren't yet mounted. Instead, we store a temporary reference to the Fiber itself and later check to see if it successfully mounted before merging pending error/warning counts.

This avoids a problematic edge case where a force-remounted Fiber (from Fast Refresh) caused us to untrack a Fiber that was still mounted, resulting in a DevTools error if that Fiber was inspected in the Components tab.
2021-05-20 11:24:08 -04:00
Sebastian Silbermann 84b9162cbe Use toMatchInlineSnapshot for dehydrated values (#20618) 2021-04-26 12:30:34 -04:00
Sebastian Silbermann 1214b302e1 test: Fix "couldn't locate all inline snapshots" (#21205) 2021-04-08 11:18:13 -04:00
Brian Vaughn cfd8c1bd43 DevTools: Restore inspect-element bridge optimizations (#20789)
* Restore inspect-element bridge optimizations

When the new Suspense cache was integrated (so that startTransition could be used) I removed a couple of optimizations between the backend and frontend that reduced bridge traffic when e.g. dehydrated paths were inspected for elements that had not rendered since previously inspected. This commit re-adds those optimizations as well as an additional test with a bug fix that I noticed while reading the backend code.

There are two remaining TODO items as of this commit:
- Make inspected element edits and deletes also use transition API
- Don't over-eagerly refresh the cache in our ping-for-updates handler

I will addres both in subsequent commits.

* Poll for update only refreshes cache when there's an update

* Added inline comment
2021-02-22 14:04:20 -05:00
Brian Vaughn 6d94017c42 DevTools: Make it easier to write tests for inspected elements (#20655)
And also add a few tests for  which also cover a recent bugfix that just landed
2021-01-25 14:58:19 -05:00
ChenLei ba9582da27 [devtools] Fix can't expand prop value in some scenario (#20534)
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2021-01-19 10:26:52 -05:00
Brian Vaughn af16f755dc Update DevTools to use getCacheForType API (#20548)
DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs.

### Messaging changes

I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it.

The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.)

_Initial inspection..._
```
front |                                                      | back
      | -- "inspect" (id:1, paths:[], force:true) ---------> |
      | <------------------------ "inspected" (full-data) -- |
```
_1 second passes with no updates..._
```
      | -- "inspect" (id:1, paths:[], force:false) --------> |
      | <------------------------ "inspected" (no-change) -- |
```
_User clicks to expand a path, aka hydrate..._
```
      | -- "inspect" (id:1, paths:['foo'], force:true) ----> |
      | <------------------------ "inspected" (full-data) -- |
```
_1 second passes during which there is an update..._
```
      | -- "inspect" (id:1, paths:['foo'], force:false) ---> |
      | <----------------- "inspectedElement" (full-data) -- |
```

### Clear errors/warnings transition
Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved.

### Hydrating paths transition
I also added a transition to hydration (expanding "dehyrated" paths).

### Better error boundaries
I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element.

### Improved snapshot tests
I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 09:51:32 -05:00