Skip to content

Commit cf2a0b9

Browse files
angelosilvestrematthew-carroll
authored andcommitted
[Infrastructure] Fix widget tester tapping on block component (Resolves #2197) (#2207)
1 parent fd5d4e1 commit cf2a0b9

File tree

1 file changed

+53
-3
lines changed

1 file changed

+53
-3
lines changed

super_editor/lib/src/test/super_editor_test/supereditor_robot.dart

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ extension SuperEditorRobot on WidgetTester {
164164
/// {@macro supereditor_finder}
165165
Future<void> tapAtDocumentPosition(DocumentPosition position, [Finder? superEditorFinder]) async {
166166
final documentLayout = _findDocumentLayout(superEditorFinder);
167-
final positionRectInDoc = documentLayout.getRectForPosition(position)!;
167+
final positionRectInDoc = _getRectForDocumentPosition(position, documentLayout, superEditorFinder);
168168
final globalTapOffset = documentLayout.getAncestorOffsetFromDocumentOffset(positionRectInDoc.center);
169169

170170
await tapAt(globalTapOffset);
@@ -436,17 +436,67 @@ extension SuperEditorRobot on WidgetTester {
436436
return textLayout.getOffsetForCaret(position) + Offset(affinity == TextAffinity.upstream ? -1 : 1, 5);
437437
}
438438

439+
/// Returns the bounding box around the given [position], within the associated component.
440+
///
441+
/// If the component is a block component, the returned [Rect] will be half of its width.
442+
Rect _getRectForDocumentPosition(DocumentPosition position, DocumentLayout documentLayout,
443+
[Finder? superEditorFinder]) {
444+
final component = documentLayout.getComponentByNodeId(position.nodeId);
445+
if (component == null) {
446+
throw Exception('No component found for node ID: ${position.nodeId}');
447+
}
448+
449+
if (component.getBeginningPosition() is UpstreamDownstreamNodePosition) {
450+
// The component is a block component. Compute the rect manually, because
451+
// `getRectForPosition` returns always the rect of the whole block.
452+
// The returned rect will be half of the width of the component.
453+
final componentBox = component.context.findRenderObject() as RenderBox;
454+
final edge = component.getEdgeForPosition(position.nodePosition);
455+
456+
final positionRect = position.nodePosition == UpstreamDownstreamNodePosition.upstream()
457+
// For upstream position, the edge is a zero width rect starting from the left.
458+
? Rect.fromLTWH(
459+
edge.left,
460+
edge.top,
461+
componentBox.size.width / 2,
462+
componentBox.size.height,
463+
)
464+
// For downstream position, the edge is a zero width rect starting at the right.
465+
// Subtract half of the width to make it start from the center.
466+
: Rect.fromLTWH(
467+
edge.left - componentBox.size.width / 2,
468+
edge.top,
469+
componentBox.size.width / 2,
470+
componentBox.size.height,
471+
);
472+
473+
// Translate the rect to global coordinates.
474+
final documentLayoutElement = _findDocumentLayoutElement(superEditorFinder);
475+
final docOffset = componentBox.localToGlobal(Offset.zero, ancestor: documentLayoutElement.findRenderObject());
476+
return positionRect.translate(docOffset.dx, docOffset.dy);
477+
}
478+
479+
// The component isn't a block node. Use the default implementation for getRectForPosition.
480+
return documentLayout.getRectForPosition(position)!;
481+
}
482+
439483
/// Finds and returns the [DocumentLayout] within the only [SuperEditor] in the
440484
/// widget tree, or within the [SuperEditor] found via the optional [superEditorFinder].
441485
DocumentLayout _findDocumentLayout([Finder? superEditorFinder]) {
486+
final documentLayoutElement = _findDocumentLayoutElement(superEditorFinder);
487+
return documentLayoutElement.state as DocumentLayout;
488+
}
489+
490+
/// Finds and returns the document layout element within the only [SuperEditor] in the
491+
/// widget tree, or within the [SuperEditor] found via the optional [superEditorFinder].
492+
StatefulElement _findDocumentLayoutElement([Finder? superEditorFinder]) {
442493
late final Finder layoutFinder;
443494
if (superEditorFinder != null) {
444495
layoutFinder = find.descendant(of: superEditorFinder, matching: find.byType(SingleColumnDocumentLayout));
445496
} else {
446497
layoutFinder = find.byType(SingleColumnDocumentLayout);
447498
}
448-
final documentLayoutElement = layoutFinder.evaluate().single as StatefulElement;
449-
return documentLayoutElement.state as DocumentLayout;
499+
return layoutFinder.evaluate().single as StatefulElement;
450500
}
451501

452502
/// Finds the [GlobalKey] that's attached to the [TextComponent], which presents the

0 commit comments

Comments
 (0)