Skip to content

Commit 063a9e9

Browse files
committed
Add inspector tree left/right keyboard navigation coverage
Updates inspector tree tests to cover left and right arrow navigation, including expand, next-row selection, and parent selection behavior. Also ensures left navigation to a parent notifies Flutter Inspector consistently with other keyboard selection changes.
1 parent 015e2ba commit 063a9e9

2 files changed

Lines changed: 124 additions & 1 deletion

File tree

packages/devtools_app/lib/src/screens/inspector/inspector_tree_controller.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,10 @@ class InspectorTreeController extends DisposableController
357357
return true;
358358
}
359359
if (selectionLocal.parent != null) {
360-
return setSelectedNode(selectionLocal.parent);
360+
return setSelectedNode(
361+
selectionLocal.parent,
362+
notifyFlutterInspector: true,
363+
);
361364
}
362365
return false;
363366
},

packages/devtools_app/test/screens/inspector/inspector_tree_test.dart

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,66 @@ void main() {
196196
expect(capturedNotify, isTrue);
197197
},
198198
);
199+
200+
testWidgets(
201+
'navigateRight triggers onSelectionChange with notifyFlutterInspector true',
202+
(WidgetTester tester) async {
203+
bool? capturedNotify;
204+
final treeController = buildTreeController(
205+
onSelectionChange: ({bool notifyFlutterInspector = false}) {
206+
capturedNotify = notifyFlutterInspector;
207+
},
208+
);
209+
210+
await pumpInspectorTree(tester, treeController: treeController);
211+
212+
final root = treeController.root!;
213+
final firstChild = root.children.first;
214+
root.isExpanded = false;
215+
treeController.setSelectedNode(root);
216+
217+
// First right-arrow navigation expands the selected node.
218+
capturedNotify = null;
219+
treeController.navigateRight();
220+
await tester.pump();
221+
222+
expect(root.isExpanded, isTrue);
223+
expect(treeController.selection, root);
224+
expect(capturedNotify, isNull);
225+
226+
// Once expanded, right-arrow navigation selects the next visible row.
227+
treeController.navigateRight();
228+
await tester.pump();
229+
230+
expect(treeController.selection, firstChild);
231+
expect(capturedNotify, isTrue);
232+
},
233+
);
234+
235+
testWidgets(
236+
'navigateLeft triggers onSelectionChange with notifyFlutterInspector true',
237+
(WidgetTester tester) async {
238+
bool? capturedNotify;
239+
final treeController = buildTreeController(
240+
onSelectionChange: ({bool notifyFlutterInspector = false}) {
241+
capturedNotify = notifyFlutterInspector;
242+
},
243+
);
244+
245+
await pumpInspectorTree(tester, treeController: treeController);
246+
247+
final root = treeController.root!;
248+
final firstChild = root.children.first..isExpanded = false;
249+
treeController.setSelectedNode(firstChild);
250+
251+
capturedNotify = null;
252+
treeController.navigateLeft();
253+
await tester.pump();
254+
255+
expect(treeController.selection, root);
256+
expect(capturedNotify, isTrue);
257+
},
258+
);
199259
});
200260

201261
group('InspectorTree keyboard events', () {
@@ -243,5 +303,65 @@ void main() {
243303
expect(capturedNotify, isTrue);
244304
},
245305
);
306+
307+
testWidgets(
308+
'arrowRight key triggers onSelectionChange with notifyFlutterInspector true',
309+
(WidgetTester tester) async {
310+
bool? capturedNotify;
311+
final treeController = buildTreeController(
312+
onSelectionChange: ({bool notifyFlutterInspector = false}) {
313+
capturedNotify = notifyFlutterInspector;
314+
},
315+
);
316+
317+
await pumpInspectorTree(tester, treeController: treeController);
318+
319+
final root = treeController.root!;
320+
final firstChild = root.children.first;
321+
root.isExpanded = false;
322+
treeController.setSelectedNode(root);
323+
324+
// First arrowRight expands the selected node.
325+
capturedNotify = null;
326+
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
327+
await tester.pump();
328+
329+
expect(root.isExpanded, isTrue);
330+
expect(treeController.selection, root);
331+
expect(capturedNotify, isNull);
332+
333+
// Once expanded, arrowRight selects the next visible row.
334+
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
335+
await tester.pump();
336+
337+
expect(treeController.selection, firstChild);
338+
expect(capturedNotify, isTrue);
339+
},
340+
);
341+
342+
testWidgets(
343+
'arrowLeft key triggers onSelectionChange with notifyFlutterInspector true',
344+
(WidgetTester tester) async {
345+
bool? capturedNotify;
346+
final treeController = buildTreeController(
347+
onSelectionChange: ({bool notifyFlutterInspector = false}) {
348+
capturedNotify = notifyFlutterInspector;
349+
},
350+
);
351+
352+
await pumpInspectorTree(tester, treeController: treeController);
353+
354+
final root = treeController.root!;
355+
final firstChild = root.children.first..isExpanded = false;
356+
treeController.setSelectedNode(firstChild);
357+
358+
capturedNotify = null;
359+
await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
360+
await tester.pump();
361+
362+
expect(treeController.selection, root);
363+
expect(capturedNotify, isTrue);
364+
},
365+
);
246366
});
247367
}

0 commit comments

Comments
 (0)