Skip to content

Commit 8ba4fce

Browse files
committed
add another test case
1 parent 499ec31 commit 8ba4fce

1 file changed

Lines changed: 117 additions & 0 deletions

File tree

packages/devtools_app/test/shared/ui/hover_positioning_test.dart

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:devtools_test/helpers.dart';
77
import 'package:flutter/gestures.dart';
88
import 'package:flutter/material.dart';
99
import 'package:flutter_test/flutter_test.dart';
10+
import 'package:provider/provider.dart';
1011

1112
void main() {
1213
Future<void> pumpHoverCardTooltip(
@@ -108,4 +109,120 @@ void main() {
108109
expect(overlayContainer, findsOneWidget);
109110
},
110111
);
112+
113+
testWidgetsWithWindowSize(
114+
'HoverCard height clamping with title',
115+
const Size(800, 600),
116+
(WidgetTester tester) async {
117+
await pumpHoverCardTooltip(
118+
tester,
119+
alignment: Alignment.bottomCenter,
120+
title: 'An Important Title',
121+
);
122+
123+
final hoverContentFinderWithTitle = find.text('Hover Content');
124+
expect(hoverContentFinderWithTitle, findsOneWidget);
125+
126+
final containerWithTitle = find
127+
.ancestor(of: hoverContentFinderWithTitle, matching: find.byType(Container))
128+
.last;
129+
130+
final renderBoxWithTitle =
131+
tester.renderObject(containerWithTitle) as RenderBox;
132+
final positionWithTitle = renderBoxWithTitle.localToGlobal(Offset.zero);
133+
134+
// Clamps strictly at y = 274.0 because of dynamic height containing title/divider.
135+
expect(positionWithTitle.dy, equals(274.0));
136+
},
137+
);
138+
139+
testWidgetsWithWindowSize(
140+
'HoverCard height clamping without title',
141+
const Size(800, 600),
142+
(WidgetTester tester) async {
143+
await pumpHoverCardTooltip(
144+
tester,
145+
alignment: Alignment.bottomCenter,
146+
);
147+
148+
final hoverContentFinderNoTitle = find.text('Hover Content');
149+
expect(hoverContentFinderNoTitle, findsOneWidget);
150+
151+
final containerNoTitle = find
152+
.ancestor(of: hoverContentFinderNoTitle, matching: find.byType(Container))
153+
.last;
154+
155+
final renderBoxNoTitle =
156+
tester.renderObject(containerNoTitle) as RenderBox;
157+
final positionNoTitle = renderBoxNoTitle.localToGlobal(Offset.zero);
158+
159+
// Clamps lower down at y = 314.0 because max height is smaller without title gaps.
160+
expect(positionNoTitle.dy, equals(314.0));
161+
},
162+
);
163+
164+
testWidgetsWithWindowSize(
165+
'HoverCard translates global coordinates to local coordinates for offset overlays',
166+
const Size(800, 600),
167+
(WidgetTester tester) async {
168+
final overlayKey = GlobalKey();
169+
170+
await tester.pumpWidget(
171+
MaterialApp(
172+
home: Scaffold(
173+
body: Padding(
174+
padding: const EdgeInsets.only(left: 50.0, top: 100.0),
175+
child: Provider<HoverCardController>.value(
176+
value: HoverCardController(),
177+
child: Overlay(
178+
key: overlayKey,
179+
initialEntries: [
180+
OverlayEntry(
181+
builder: (context) => Align(
182+
alignment: Alignment.topLeft,
183+
child: HoverCardTooltip.sync(
184+
enabled: () => true,
185+
generateHoverCardData: (event) => HoverCardData(
186+
contents: const SizedBox(
187+
width: 200,
188+
height: 250,
189+
child: Text('Hover Content'),
190+
),
191+
),
192+
child: const Text('Hover Me Offset'),
193+
),
194+
),
195+
),
196+
],
197+
),
198+
),
199+
),
200+
),
201+
),
202+
);
203+
204+
// Trigger hover
205+
final gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
206+
await gesture.addPointer(location: Offset.zero);
207+
208+
final center = tester.getCenter(find.text('Hover Me Offset'));
209+
await gesture.moveTo(center);
210+
await tester.pump(const Duration(milliseconds: 500));
211+
await tester.pumpAndSettle();
212+
213+
final hoverContentFinder = find.text('Hover Content');
214+
expect(hoverContentFinder, findsOneWidget);
215+
216+
final overlayContainer = find
217+
.ancestor(of: hoverContentFinder, matching: find.byType(Container))
218+
.last;
219+
220+
final renderBox = tester.renderObject(overlayContainer) as RenderBox;
221+
final position = renderBox.localToGlobal(Offset.zero);
222+
223+
// Dynamic margin is 16.0. Since overlay is offset by 50px globally at the left,
224+
// dynamic local X is 16.0, mapped to global X = 50.0 + 16.0 = 66.0.
225+
expect(position.dx, equals(66.0));
226+
},
227+
);
111228
}

0 commit comments

Comments
 (0)