Skip to content

Commit d634548

Browse files
authored
DevTools: merge element fields in TreeStateContext (facebook#31956)
Stacked on facebook#31892, see commit on top. For some reason, there were 2 fields different fields for essentially same thing: `selectedElementID` and `inspectedElementID`. Basically, the change is: ``` selectedElementID -> inspectedElementID selectedElementIndex -> inspectedElementIndex ``` I have a theory that it was due to previously used async approach around element inspection, and the whole `InspectedElementView` was wrapped in `Suspense`.
1 parent 54cfa95 commit d634548

File tree

12 files changed

+265
-278
lines changed

12 files changed

+265
-278
lines changed

packages/react-devtools-inline/__tests__/__e2e__/components.test.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -119,15 +119,15 @@ test.describe('Components', () => {
119119
runOnlyForReactRange('>=16.8');
120120

121121
// Select the first list item in DevTools.
122-
await devToolsUtils.selectElement(page, 'ListItem', 'List\nApp');
122+
await devToolsUtils.selectElement(page, 'ListItem', 'List\nApp', true);
123123

124124
// Then read the inspected values.
125125
const sourceText = await page.evaluate(() => {
126126
const {createTestNameSelector, findAllNodes} = window.REACT_DOM_DEVTOOLS;
127127
const container = document.getElementById('devtools');
128128

129129
const source = findAllNodes(container, [
130-
createTestNameSelector('InspectedElementView-Source'),
130+
createTestNameSelector('InspectedElementView-FormattedSourceString'),
131131
])[0];
132132

133133
return source.innerText;
@@ -237,35 +237,35 @@ test.describe('Components', () => {
237237
}
238238

239239
await focusComponentSearch();
240-
page.keyboard.insertText('List');
240+
await page.keyboard.insertText('List');
241241
let count = await getComponentSearchResultsCount();
242242
expect(count).toBe('1 | 4');
243243

244-
page.keyboard.insertText('Item');
244+
await page.keyboard.insertText('Item');
245245
count = await getComponentSearchResultsCount();
246246
expect(count).toBe('1 | 3');
247247

248-
page.keyboard.press('Enter');
248+
await page.keyboard.press('Enter');
249249
count = await getComponentSearchResultsCount();
250250
expect(count).toBe('2 | 3');
251251

252-
page.keyboard.press('Enter');
252+
await page.keyboard.press('Enter');
253253
count = await getComponentSearchResultsCount();
254254
expect(count).toBe('3 | 3');
255255

256-
page.keyboard.press('Enter');
256+
await page.keyboard.press('Enter');
257257
count = await getComponentSearchResultsCount();
258258
expect(count).toBe('1 | 3');
259259

260-
page.keyboard.press('Shift+Enter');
260+
await page.keyboard.press('Shift+Enter');
261261
count = await getComponentSearchResultsCount();
262262
expect(count).toBe('3 | 3');
263263

264-
page.keyboard.press('Shift+Enter');
264+
await page.keyboard.press('Shift+Enter');
265265
count = await getComponentSearchResultsCount();
266266
expect(count).toBe('2 | 3');
267267

268-
page.keyboard.press('Shift+Enter');
268+
await page.keyboard.press('Shift+Enter');
269269
count = await getComponentSearchResultsCount();
270270
expect(count).toBe('1 | 3');
271271
});

packages/react-devtools-inline/__tests__/__e2e__/devtools-utils.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@ async function getElementCount(page, displayName) {
2727
}, displayName);
2828
}
2929

30-
async function selectElement(page, displayName, waitForOwnersText) {
30+
async function selectElement(
31+
page,
32+
displayName,
33+
waitForOwnersText,
34+
waitForSourceLoaded = false
35+
) {
3136
await page.evaluate(listItemText => {
3237
const {createTestNameSelector, createTextSelector, findAllNodes} =
3338
window.REACT_DOM_DEVTOOLS;
@@ -69,6 +74,20 @@ async function selectElement(page, displayName, waitForOwnersText) {
6974
{titleText: displayName, ownersListText: waitForOwnersText}
7075
);
7176
}
77+
78+
if (waitForSourceLoaded) {
79+
await page.waitForFunction(() => {
80+
const {createTestNameSelector, findAllNodes} = window.REACT_DOM_DEVTOOLS;
81+
const container = document.getElementById('devtools');
82+
83+
const sourceStringBlock = findAllNodes(container, [
84+
createTestNameSelector('InspectedElementView-FormattedSourceString'),
85+
])[0];
86+
87+
// Wait for a new source line to be fetched
88+
return sourceStringBlock != null && sourceStringBlock.innerText != null;
89+
});
90+
}
7291
}
7392

7493
module.exports = {

packages/react-devtools-shared/src/__tests__/inspectedElement-test.js

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,15 @@ describe('InspectedElement', () => {
115115

116116
const Contexts = ({
117117
children,
118-
defaultSelectedElementID = null,
119-
defaultSelectedElementIndex = null,
118+
defaultInspectedElementID = null,
119+
defaultInspectedElementIndex = null,
120120
}) => (
121121
<BridgeContext.Provider value={bridge}>
122122
<StoreContext.Provider value={store}>
123123
<SettingsContextController>
124124
<TreeContextController
125-
defaultSelectedElementID={defaultSelectedElementID}
126-
defaultSelectedElementIndex={defaultSelectedElementIndex}
127-
defaultInspectedElementID={defaultSelectedElementID}>
125+
defaultInspectedElementID={defaultInspectedElementID}
126+
defaultInspectedElementIndex={defaultInspectedElementIndex}>
128127
<InspectedElementContextController>
129128
{children}
130129
</InspectedElementContextController>
@@ -167,8 +166,8 @@ describe('InspectedElement', () => {
167166
testRendererInstance.update(
168167
<ErrorBoundary>
169168
<Contexts
170-
defaultSelectedElementID={id}
171-
defaultSelectedElementIndex={index}>
169+
defaultInspectedElementID={id}
170+
defaultInspectedElementIndex={index}>
172171
<React.Suspense fallback={null}>
173172
<Suspender id={id} index={index} />
174173
</React.Suspense>
@@ -355,7 +354,7 @@ describe('InspectedElement', () => {
355354
const {index, shouldHaveLegacyContext} = cases[i];
356355

357356
// HACK: Recreate TestRenderer instance because we rely on default state values
358-
// from props like defaultSelectedElementID and it's easier to reset here than
357+
// from props like defaultInspectedElementID and it's easier to reset here than
359358
// to read the TreeDispatcherContext and update the selected ID that way.
360359
// We're testing the inspected values here, not the context wiring, so that's ok.
361360
withErrorsOrWarningsIgnored(
@@ -2069,7 +2068,7 @@ describe('InspectedElement', () => {
20692068
}, false);
20702069

20712070
// HACK: Recreate TestRenderer instance because we rely on default state values
2072-
// from props like defaultSelectedElementID and it's easier to reset here than
2071+
// from props like defaultInspectedElementID and it's easier to reset here than
20732072
// to read the TreeDispatcherContext and update the selected ID that way.
20742073
// We're testing the inspected values here, not the context wiring, so that's ok.
20752074
withErrorsOrWarningsIgnored(
@@ -2129,7 +2128,7 @@ describe('InspectedElement', () => {
21292128
}, false);
21302129

21312130
// HACK: Recreate TestRenderer instance because we rely on default state values
2132-
// from props like defaultSelectedElementID and it's easier to reset here than
2131+
// from props like defaultInspectedElementID and it's easier to reset here than
21332132
// to read the TreeDispatcherContext and update the selected ID that way.
21342133
// We're testing the inspected values here, not the context wiring, so that's ok.
21352134
withErrorsOrWarningsIgnored(
@@ -2408,8 +2407,8 @@ describe('InspectedElement', () => {
24082407
await utils.actAsync(() => {
24092408
root = TestRenderer.create(
24102409
<Contexts
2411-
defaultSelectedElementID={id}
2412-
defaultSelectedElementIndex={index}>
2410+
defaultInspectedElementID={id}
2411+
defaultInspectedElementIndex={index}>
24132412
<React.Suspense fallback={null}>
24142413
<Suspender target={id} />
24152414
</React.Suspense>
@@ -3101,6 +3100,7 @@ describe('InspectedElement', () => {
31013100

31023101
await utils.actAsync(() => {
31033102
store.componentFilters = [utils.createDisplayNameFilter('Wrapper')];
3103+
jest.runOnlyPendingTimers();
31043104
}, false);
31053105

31063106
expect(state).toMatchInlineSnapshot(`
@@ -3120,6 +3120,7 @@ describe('InspectedElement', () => {
31203120

31213121
await utils.actAsync(() => {
31223122
store.componentFilters = [];
3123+
jest.runOnlyPendingTimers();
31233124
}, false);
31243125
expect(state).toMatchInlineSnapshot(`
31253126
✕ 0, ⚠ 2

packages/react-devtools-shared/src/__tests__/profilerContext-test.js

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ describe('ProfilerContext', () => {
6969

7070
const Contexts = ({
7171
children = null,
72-
defaultSelectedElementID = null,
73-
defaultSelectedElementIndex = null,
72+
defaultInspectedElementID = null,
73+
defaultInspectedElementIndex = null,
7474
}: any) => (
7575
<BridgeContext.Provider value={bridge}>
7676
<StoreContext.Provider value={store}>
7777
<TreeContextController
78-
defaultSelectedElementID={defaultSelectedElementID}
79-
defaultSelectedElementIndex={defaultSelectedElementIndex}>
78+
defaultInspectedElementID={defaultInspectedElementID}
79+
defaultInspectedElementIndex={defaultInspectedElementIndex}>
8080
<ProfilerContextController>{children}</ProfilerContextController>
8181
</TreeContextController>
8282
</StoreContext.Provider>
@@ -225,8 +225,8 @@ describe('ProfilerContext', () => {
225225
await utils.actAsync(() =>
226226
TestRenderer.create(
227227
<Contexts
228-
defaultSelectedElementID={store.getElementIDAtIndex(3)}
229-
defaultSelectedElementIndex={3}>
228+
defaultInspectedElementID={store.getElementIDAtIndex(3)}
229+
defaultInspectedElementIndex={3}>
230230
<ContextReader />
231231
</Contexts>,
232232
),
@@ -276,8 +276,8 @@ describe('ProfilerContext', () => {
276276
await utils.actAsync(() =>
277277
TestRenderer.create(
278278
<Contexts
279-
defaultSelectedElementID={store.getElementIDAtIndex(3)}
280-
defaultSelectedElementIndex={3}>
279+
defaultInspectedElementID={store.getElementIDAtIndex(3)}
280+
defaultInspectedElementIndex={3}>
281281
<ContextReader />
282282
</Contexts>,
283283
),
@@ -323,8 +323,8 @@ describe('ProfilerContext', () => {
323323
await utils.actAsync(() =>
324324
TestRenderer.create(
325325
<Contexts
326-
defaultSelectedElementID={store.getElementIDAtIndex(3)}
327-
defaultSelectedElementIndex={3}>
326+
defaultInspectedElementID={store.getElementIDAtIndex(3)}
327+
defaultInspectedElementIndex={3}>
328328
<ContextReader />
329329
</Contexts>,
330330
),
@@ -374,8 +374,8 @@ describe('ProfilerContext', () => {
374374
await utils.actAsync(() =>
375375
TestRenderer.create(
376376
<Contexts
377-
defaultSelectedElementID={store.getElementIDAtIndex(3)}
378-
defaultSelectedElementIndex={3}>
377+
defaultInspectedElementID={store.getElementIDAtIndex(3)}
378+
defaultInspectedElementIndex={3}>
379379
<ContextReader />
380380
</Contexts>,
381381
),
@@ -415,11 +415,12 @@ describe('ProfilerContext', () => {
415415

416416
let context: Context = ((null: any): Context);
417417
let dispatch: DispatcherContext = ((null: any): DispatcherContext);
418-
let selectedElementID = null;
418+
let inspectedElementID = null;
419419
function ContextReader() {
420420
context = React.useContext(ProfilerContext);
421421
dispatch = React.useContext(TreeDispatcherContext);
422-
selectedElementID = React.useContext(TreeStateContext).selectedElementID;
422+
inspectedElementID =
423+
React.useContext(TreeStateContext).inspectedElementID;
423424
return null;
424425
}
425426

@@ -428,13 +429,15 @@ describe('ProfilerContext', () => {
428429
// Select an element within the second root.
429430
await utils.actAsync(() =>
430431
TestRenderer.create(
431-
<Contexts defaultSelectedElementID={id} defaultSelectedElementIndex={3}>
432+
<Contexts
433+
defaultInspectedElementID={id}
434+
defaultInspectedElementIndex={3}>
432435
<ContextReader />
433436
</Contexts>,
434437
),
435438
);
436439

437-
expect(selectedElementID).toBe(id);
440+
expect(inspectedElementID).toBe(id);
438441

439442
// Profile and record more updates to both roots
440443
await utils.actAsync(() => store.profilerStore.startProfiling());
@@ -448,7 +451,7 @@ describe('ProfilerContext', () => {
448451
utils.act(() => dispatch({type: 'SELECT_ELEMENT_AT_INDEX', payload: 0}));
449452

450453
// Verify that the initial Profiler root selection is maintained.
451-
expect(selectedElementID).toBe(otherID);
454+
expect(inspectedElementID).toBe(otherID);
452455
expect(context).not.toBeNull();
453456
expect(context.rootID).toBe(store.getRootIDForElement(id));
454457
});
@@ -484,11 +487,12 @@ describe('ProfilerContext', () => {
484487

485488
let context: Context = ((null: any): Context);
486489
let dispatch: DispatcherContext = ((null: any): DispatcherContext);
487-
let selectedElementID = null;
490+
let inspectedElementID = null;
488491
function ContextReader() {
489492
context = React.useContext(ProfilerContext);
490493
dispatch = React.useContext(TreeDispatcherContext);
491-
selectedElementID = React.useContext(TreeStateContext).selectedElementID;
494+
inspectedElementID =
495+
React.useContext(TreeStateContext).inspectedElementID;
492496
return null;
493497
}
494498

@@ -497,13 +501,15 @@ describe('ProfilerContext', () => {
497501
// Select an element within the second root.
498502
await utils.actAsync(() =>
499503
TestRenderer.create(
500-
<Contexts defaultSelectedElementID={id} defaultSelectedElementIndex={3}>
504+
<Contexts
505+
defaultInspectedElementID={id}
506+
defaultInspectedElementIndex={3}>
501507
<ContextReader />
502508
</Contexts>,
503509
),
504510
);
505511

506-
expect(selectedElementID).toBe(id);
512+
expect(inspectedElementID).toBe(id);
507513

508514
// Profile and record more updates to both roots
509515
await utils.actAsync(() => store.profilerStore.startProfiling());
@@ -517,7 +523,7 @@ describe('ProfilerContext', () => {
517523
utils.act(() => dispatch({type: 'SELECT_ELEMENT_AT_INDEX', payload: 0}));
518524

519525
// Verify that the initial Profiler root selection is maintained.
520-
expect(selectedElementID).toBe(otherID);
526+
expect(inspectedElementID).toBe(otherID);
521527
expect(context).not.toBeNull();
522528
expect(context.rootID).toBe(store.getRootIDForElement(id));
523529
});
@@ -553,10 +559,11 @@ describe('ProfilerContext', () => {
553559
`);
554560

555561
let context: Context = ((null: any): Context);
556-
let selectedElementID = null;
562+
let inspectedElementID = null;
557563
function ContextReader() {
558564
context = React.useContext(ProfilerContext);
559-
selectedElementID = React.useContext(TreeStateContext).selectedElementID;
565+
inspectedElementID =
566+
React.useContext(TreeStateContext).inspectedElementID;
560567
return null;
561568
}
562569

@@ -567,14 +574,14 @@ describe('ProfilerContext', () => {
567574
</Contexts>,
568575
),
569576
);
570-
expect(selectedElementID).toBeNull();
577+
expect(inspectedElementID).toBeNull();
571578

572579
// Select an element in the Profiler tab and verify that the selection is synced to the Components tab.
573580
await utils.actAsync(() => context.selectFiber(parentID, 'Parent'));
574-
expect(selectedElementID).toBe(parentID);
581+
expect(inspectedElementID).toBe(parentID);
575582

576583
// Select an unmounted element and verify no Components tab selection doesn't change.
577584
await utils.actAsync(() => context.selectFiber(childID, 'Child'));
578-
expect(selectedElementID).toBe(parentID);
585+
expect(inspectedElementID).toBe(parentID);
579586
});
580587
});

packages/react-devtools-shared/src/devtools/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export function printStore(
6767
if (state === null) {
6868
return '';
6969
}
70-
return state.selectedElementIndex === index ? `→` : ' ';
70+
return state.inspectedElementIndex === index ? `→` : ' ';
7171
}
7272

7373
function printErrorsAndWarnings(element: Element): string {

packages/react-devtools-shared/src/devtools/views/Components/Element.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type Props = {
3333

3434
export default function Element({data, index, style}: Props): React.Node {
3535
const store = useContext(StoreContext);
36-
const {ownerFlatTree, ownerID, selectedElementID} =
36+
const {ownerFlatTree, ownerID, inspectedElementID} =
3737
useContext(TreeStateContext);
3838
const dispatch = useContext(TreeDispatcherContext);
3939

@@ -46,7 +46,7 @@ export default function Element({data, index, style}: Props): React.Node {
4646

4747
const {isNavigatingWithKeyboard, onElementMouseEnter, treeFocused} = data;
4848
const id = element === null ? null : element.id;
49-
const isSelected = selectedElementID === id;
49+
const isSelected = inspectedElementID === id;
5050

5151
const errorsAndWarningsSubscription = useMemo(
5252
() => ({

0 commit comments

Comments
 (0)