1 | // Copyright 2014 The Flutter Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | import 'package:flutter/foundation.dart'; |
6 | import 'package:flutter/gestures.dart'; |
7 | import 'package:flutter/material.dart'; |
8 | import 'package:flutter/rendering.dart'; |
9 | import 'package:flutter/src/services/keyboard_key.g.dart'; |
10 | import 'package:flutter_test/flutter_test.dart'; |
11 | import '../widgets/semantics_tester.dart'; |
12 | |
13 | void main() { |
14 | testWidgets('RawMaterialButton responds when tapped' , (WidgetTester tester) async { |
15 | bool pressed = false; |
16 | const Color splashColor = Color(0xff00ff00); |
17 | await tester.pumpWidget( |
18 | Theme( |
19 | data: ThemeData(useMaterial3: false), |
20 | child: Directionality( |
21 | textDirection: TextDirection.ltr, |
22 | child: Center( |
23 | child: RawMaterialButton( |
24 | splashColor: splashColor, |
25 | onPressed: () { |
26 | pressed = true; |
27 | }, |
28 | child: const Text('BUTTON' ), |
29 | ), |
30 | ), |
31 | ), |
32 | ), |
33 | ); |
34 | |
35 | await tester.tap(find.text('BUTTON' )); |
36 | await tester.pump(const Duration(milliseconds: 10)); |
37 | |
38 | final RenderBox splash = Material.of(tester.element(find.byType(InkWell))) as RenderBox; |
39 | expect(splash, paints..circle(color: splashColor)); |
40 | |
41 | await tester.pumpAndSettle(); |
42 | |
43 | expect(pressed, isTrue); |
44 | }); |
45 | |
46 | testWidgets('RawMaterialButton responds to shortcut when activated' , (WidgetTester tester) async { |
47 | bool pressed = false; |
48 | final FocusNode focusNode = FocusNode(debugLabel: 'Test Button' ); |
49 | const Color splashColor = Color(0xff00ff00); |
50 | await tester.pumpWidget( |
51 | Theme( |
52 | data: ThemeData(useMaterial3: false), |
53 | child: Shortcuts( |
54 | shortcuts: const <ShortcutActivator, Intent>{ |
55 | SingleActivator(LogicalKeyboardKey.enter): ActivateIntent(), |
56 | SingleActivator(LogicalKeyboardKey.space): ActivateIntent(), |
57 | }, |
58 | child: Directionality( |
59 | textDirection: TextDirection.ltr, |
60 | child: Center( |
61 | child: RawMaterialButton( |
62 | splashColor: splashColor, |
63 | focusNode: focusNode, |
64 | onPressed: () { |
65 | pressed = true; |
66 | }, |
67 | child: const Text('BUTTON' ), |
68 | ), |
69 | ), |
70 | ), |
71 | ), |
72 | ), |
73 | ); |
74 | |
75 | focusNode.requestFocus(); |
76 | await tester.pump(); |
77 | |
78 | // Web doesn't react to enter, just space. |
79 | await tester.sendKeyEvent(LogicalKeyboardKey.enter); |
80 | await tester.pump(const Duration(milliseconds: 10)); |
81 | |
82 | if (!kIsWeb) { |
83 | final RenderBox splash = Material.of(tester.element(find.byType(InkWell))) as RenderBox; |
84 | expect(splash, paints..circle(color: splashColor)); |
85 | } |
86 | |
87 | await tester.pumpAndSettle(); |
88 | |
89 | expect(pressed, isTrue); |
90 | |
91 | pressed = false; |
92 | await tester.sendKeyEvent(LogicalKeyboardKey.space); |
93 | await tester.pumpAndSettle(); |
94 | |
95 | expect(pressed, isTrue); |
96 | |
97 | pressed = false; |
98 | await tester.sendKeyEvent(LogicalKeyboardKey.space); |
99 | await tester.pump(const Duration(milliseconds: 10)); |
100 | |
101 | final RenderBox splash = Material.of(tester.element(find.byType(InkWell))) as RenderBox; |
102 | expect(splash, paints..circle(color: splashColor)); |
103 | |
104 | await tester.pumpAndSettle(); |
105 | |
106 | expect(pressed, isTrue); |
107 | |
108 | pressed = false; |
109 | await tester.sendKeyEvent(LogicalKeyboardKey.space); |
110 | await tester.pumpAndSettle(); |
111 | |
112 | expect(pressed, isTrue); |
113 | focusNode.dispose(); |
114 | }); |
115 | |
116 | testWidgets('materialTapTargetSize.padded expands hit test area' , (WidgetTester tester) async { |
117 | int pressed = 0; |
118 | |
119 | await tester.pumpWidget( |
120 | Directionality( |
121 | textDirection: TextDirection.ltr, |
122 | child: RawMaterialButton( |
123 | onPressed: () { |
124 | pressed++; |
125 | }, |
126 | constraints: BoxConstraints.tight(const Size(10.0, 10.0)), |
127 | materialTapTargetSize: MaterialTapTargetSize.padded, |
128 | child: const Text('+' ), |
129 | ), |
130 | ), |
131 | ); |
132 | |
133 | await tester.tapAt(const Offset(40.0, 400.0)); |
134 | |
135 | expect(pressed, 1); |
136 | }); |
137 | |
138 | testWidgets('materialTapTargetSize.padded expands semantics area' , (WidgetTester tester) async { |
139 | final SemanticsTester semantics = SemanticsTester(tester); |
140 | await tester.pumpWidget( |
141 | Directionality( |
142 | textDirection: TextDirection.ltr, |
143 | child: Center( |
144 | child: RawMaterialButton( |
145 | onPressed: () {}, |
146 | constraints: BoxConstraints.tight(const Size(10.0, 10.0)), |
147 | materialTapTargetSize: MaterialTapTargetSize.padded, |
148 | child: const Text('+' ), |
149 | ), |
150 | ), |
151 | ), |
152 | ); |
153 | |
154 | expect( |
155 | semantics, |
156 | hasSemantics( |
157 | TestSemantics.root( |
158 | children: <TestSemantics>[ |
159 | TestSemantics( |
160 | id: 1, |
161 | flags: <SemanticsFlag>[ |
162 | SemanticsFlag.hasEnabledState, |
163 | SemanticsFlag.isButton, |
164 | SemanticsFlag.isEnabled, |
165 | SemanticsFlag.isFocusable, |
166 | ], |
167 | actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus], |
168 | label: '+' , |
169 | textDirection: TextDirection.ltr, |
170 | rect: const Rect.fromLTRB(0.0, 0.0, 48.0, 48.0), |
171 | children: <TestSemantics>[], |
172 | ), |
173 | ], |
174 | ), |
175 | ignoreTransform: true, |
176 | ), |
177 | ); |
178 | |
179 | semantics.dispose(); |
180 | }); |
181 | |
182 | testWidgets('Ink splash from center tap originates in correct location' , ( |
183 | WidgetTester tester, |
184 | ) async { |
185 | const Color highlightColor = Color(0xAAFF0000); |
186 | const Color splashColor = Color(0xAA0000FF); |
187 | const Color fillColor = Color(0xFFEF5350); |
188 | |
189 | await tester.pumpWidget( |
190 | Theme( |
191 | data: ThemeData(useMaterial3: false), |
192 | child: Directionality( |
193 | textDirection: TextDirection.ltr, |
194 | child: Center( |
195 | child: RawMaterialButton( |
196 | materialTapTargetSize: MaterialTapTargetSize.padded, |
197 | onPressed: () {}, |
198 | fillColor: fillColor, |
199 | highlightColor: highlightColor, |
200 | splashColor: splashColor, |
201 | child: const SizedBox(), |
202 | ), |
203 | ), |
204 | ), |
205 | ), |
206 | ); |
207 | |
208 | final Offset center = tester.getCenter(find.byType(InkWell)); |
209 | final TestGesture gesture = await tester.startGesture(center); |
210 | await tester.pump(); // start gesture |
211 | await tester.pump(const Duration(milliseconds: 200)); // wait for splash to be well under way |
212 | |
213 | final RenderBox box = Material.of(tester.element(find.byType(InkWell))) as RenderBox; |
214 | // centered in material button. |
215 | expect(box, paints..circle(x: 44.0, y: 18.0, color: splashColor)); |
216 | await gesture.up(); |
217 | }); |
218 | |
219 | testWidgets('Ink splash from tap above material originates in correct location' , ( |
220 | WidgetTester tester, |
221 | ) async { |
222 | const Color highlightColor = Color(0xAAFF0000); |
223 | const Color splashColor = Color(0xAA0000FF); |
224 | const Color fillColor = Color(0xFFEF5350); |
225 | |
226 | await tester.pumpWidget( |
227 | Theme( |
228 | data: ThemeData(useMaterial3: false), |
229 | child: Directionality( |
230 | textDirection: TextDirection.ltr, |
231 | child: Center( |
232 | child: RawMaterialButton( |
233 | materialTapTargetSize: MaterialTapTargetSize.padded, |
234 | onPressed: () {}, |
235 | fillColor: fillColor, |
236 | highlightColor: highlightColor, |
237 | splashColor: splashColor, |
238 | child: const SizedBox(), |
239 | ), |
240 | ), |
241 | ), |
242 | ), |
243 | ); |
244 | |
245 | final Offset top = tester.getRect(find.byType(InkWell)).topCenter; |
246 | final TestGesture gesture = await tester.startGesture(top); |
247 | await tester.pump(); // start gesture |
248 | await tester.pump(const Duration(milliseconds: 200)); // wait for splash to be well under way |
249 | final RenderBox box = Material.of(tester.element(find.byType(InkWell))) as RenderBox; |
250 | // paints above material |
251 | expect(box, paints..circle(x: 44.0, y: 0.0, color: splashColor)); |
252 | await gesture.up(); |
253 | }); |
254 | |
255 | testWidgets('off-center child is hit testable' , (WidgetTester tester) async { |
256 | await tester.pumpWidget( |
257 | MaterialApp( |
258 | home: Column( |
259 | children: <Widget>[ |
260 | RawMaterialButton( |
261 | materialTapTargetSize: MaterialTapTargetSize.padded, |
262 | onPressed: () {}, |
263 | child: const SizedBox( |
264 | width: 400.0, |
265 | height: 400.0, |
266 | child: Column( |
267 | mainAxisAlignment: MainAxisAlignment.end, |
268 | children: <Widget>[SizedBox(height: 50.0, width: 400.0, child: Text('Material' ))], |
269 | ), |
270 | ), |
271 | ), |
272 | ], |
273 | ), |
274 | ), |
275 | ); |
276 | expect(find.text('Material' ).hitTestable(), findsOneWidget); |
277 | }); |
278 | |
279 | testWidgets('smaller child is hit testable' , (WidgetTester tester) async { |
280 | const Key key = Key('test' ); |
281 | await tester.pumpWidget( |
282 | MaterialApp( |
283 | home: Column( |
284 | children: <Widget>[ |
285 | RawMaterialButton( |
286 | materialTapTargetSize: MaterialTapTargetSize.padded, |
287 | onPressed: () {}, |
288 | child: SizedBox( |
289 | key: key, |
290 | width: 8.0, |
291 | height: 8.0, |
292 | child: Container(color: const Color(0xFFAABBCC)), |
293 | ), |
294 | ), |
295 | ], |
296 | ), |
297 | ), |
298 | ); |
299 | expect(find.byKey(key).hitTestable(), findsOneWidget); |
300 | }); |
301 | |
302 | testWidgets('RawMaterialButton can be expanded by parent constraints' , ( |
303 | WidgetTester tester, |
304 | ) async { |
305 | const Key key = Key('test' ); |
306 | await tester.pumpWidget( |
307 | MaterialApp( |
308 | home: Column( |
309 | crossAxisAlignment: CrossAxisAlignment.stretch, |
310 | children: <Widget>[ |
311 | RawMaterialButton(key: key, onPressed: () {}, child: const SizedBox()), |
312 | ], |
313 | ), |
314 | ), |
315 | ); |
316 | |
317 | expect(tester.getSize(find.byKey(key)), const Size(800.0, 48.0)); |
318 | }); |
319 | |
320 | testWidgets('RawMaterialButton handles focus' , (WidgetTester tester) async { |
321 | final FocusNode focusNode = FocusNode(debugLabel: 'Button Focus' ); |
322 | const Key key = Key('test' ); |
323 | const Color focusColor = Color(0xff00ff00); |
324 | |
325 | FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; |
326 | await tester.pumpWidget( |
327 | MaterialApp( |
328 | home: Center( |
329 | child: RawMaterialButton( |
330 | key: key, |
331 | focusNode: focusNode, |
332 | focusColor: focusColor, |
333 | onPressed: () {}, |
334 | child: Container(width: 100, height: 100, color: const Color(0xffff0000)), |
335 | ), |
336 | ), |
337 | ), |
338 | ); |
339 | final RenderBox box = Material.of(tester.element(find.byType(InkWell))) as RenderBox; |
340 | expect(box, isNot(paints..rect(color: focusColor))); |
341 | |
342 | focusNode.requestFocus(); |
343 | await tester.pumpAndSettle(const Duration(seconds: 1)); |
344 | |
345 | expect(box, paints..rect(color: focusColor)); |
346 | focusNode.dispose(); |
347 | }); |
348 | |
349 | testWidgets('RawMaterialButton loses focus when disabled.' , (WidgetTester tester) async { |
350 | final FocusNode focusNode = FocusNode(debugLabel: 'RawMaterialButton' ); |
351 | await tester.pumpWidget( |
352 | MaterialApp( |
353 | home: Center( |
354 | child: RawMaterialButton( |
355 | autofocus: true, |
356 | focusNode: focusNode, |
357 | onPressed: () {}, |
358 | child: Container(width: 100, height: 100, color: const Color(0xffff0000)), |
359 | ), |
360 | ), |
361 | ), |
362 | ); |
363 | |
364 | await tester.pump(); |
365 | expect(focusNode.hasPrimaryFocus, isTrue); |
366 | |
367 | await tester.pumpWidget( |
368 | MaterialApp( |
369 | home: Center( |
370 | child: RawMaterialButton( |
371 | focusNode: focusNode, |
372 | onPressed: null, |
373 | child: Container(width: 100, height: 100, color: const Color(0xffff0000)), |
374 | ), |
375 | ), |
376 | ), |
377 | ); |
378 | |
379 | await tester.pump(); |
380 | expect(focusNode.hasPrimaryFocus, isFalse); |
381 | focusNode.dispose(); |
382 | }); |
383 | |
384 | testWidgets("Disabled RawMaterialButton can't be traversed to." , (WidgetTester tester) async { |
385 | final FocusNode focusNode1 = FocusNode(debugLabel: ' $RawMaterialButton 1' ); |
386 | final FocusNode focusNode2 = FocusNode(debugLabel: ' $RawMaterialButton 2' ); |
387 | |
388 | await tester.pumpWidget( |
389 | MaterialApp( |
390 | home: FocusScope( |
391 | child: Center( |
392 | child: Column( |
393 | children: <Widget>[ |
394 | RawMaterialButton( |
395 | autofocus: true, |
396 | focusNode: focusNode1, |
397 | onPressed: () {}, |
398 | child: Container(width: 100, height: 100, color: const Color(0xffff0000)), |
399 | ), |
400 | RawMaterialButton( |
401 | autofocus: true, |
402 | focusNode: focusNode2, |
403 | onPressed: null, |
404 | child: Container(width: 100, height: 100, color: const Color(0xffff0000)), |
405 | ), |
406 | ], |
407 | ), |
408 | ), |
409 | ), |
410 | ), |
411 | ); |
412 | await tester.pump(); |
413 | |
414 | expect(focusNode1.hasPrimaryFocus, isTrue); |
415 | expect(focusNode2.hasPrimaryFocus, isFalse); |
416 | |
417 | expect(focusNode1.nextFocus(), isFalse); |
418 | await tester.pump(); |
419 | |
420 | expect(focusNode1.hasPrimaryFocus, isTrue); |
421 | expect(focusNode2.hasPrimaryFocus, isFalse); |
422 | |
423 | focusNode1.dispose(); |
424 | focusNode2.dispose(); |
425 | }); |
426 | |
427 | testWidgets('RawMaterialButton handles hover' , (WidgetTester tester) async { |
428 | const Key key = Key('test' ); |
429 | const Color hoverColor = Color(0xff00ff00); |
430 | |
431 | FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; |
432 | await tester.pumpWidget( |
433 | MaterialApp( |
434 | home: Center( |
435 | child: RawMaterialButton( |
436 | key: key, |
437 | hoverColor: hoverColor, |
438 | hoverElevation: 10.5, |
439 | onPressed: () {}, |
440 | child: Container(width: 100, height: 100, color: const Color(0xffff0000)), |
441 | ), |
442 | ), |
443 | ), |
444 | ); |
445 | final RenderBox box = Material.of(tester.element(find.byType(InkWell))) as RenderBox; |
446 | final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse); |
447 | await gesture.addPointer(); |
448 | expect(box, isNot(paints..rect(color: hoverColor))); |
449 | |
450 | await gesture.moveTo(tester.getCenter(find.byType(RawMaterialButton))); |
451 | await tester.pumpAndSettle(const Duration(seconds: 1)); |
452 | |
453 | expect(box, paints..rect(color: hoverColor)); |
454 | }); |
455 | |
456 | testWidgets( |
457 | 'RawMaterialButton onPressed and onLongPress callbacks are correctly called when non-null' , |
458 | (WidgetTester tester) async { |
459 | bool wasPressed; |
460 | Finder rawMaterialButton; |
461 | |
462 | Widget buildFrame({VoidCallback? onPressed, VoidCallback? onLongPress}) { |
463 | return Directionality( |
464 | textDirection: TextDirection.ltr, |
465 | child: RawMaterialButton( |
466 | onPressed: onPressed, |
467 | onLongPress: onLongPress, |
468 | child: const Text('button' ), |
469 | ), |
470 | ); |
471 | } |
472 | |
473 | // onPressed not null, onLongPress null. |
474 | wasPressed = false; |
475 | await tester.pumpWidget( |
476 | buildFrame( |
477 | onPressed: () { |
478 | wasPressed = true; |
479 | }, |
480 | ), |
481 | ); |
482 | rawMaterialButton = find.byType(RawMaterialButton); |
483 | expect(tester.widget<RawMaterialButton>(rawMaterialButton).enabled, true); |
484 | await tester.tap(rawMaterialButton); |
485 | expect(wasPressed, true); |
486 | |
487 | // onPressed null, onLongPress not null. |
488 | wasPressed = false; |
489 | await tester.pumpWidget( |
490 | buildFrame( |
491 | onLongPress: () { |
492 | wasPressed = true; |
493 | }, |
494 | ), |
495 | ); |
496 | rawMaterialButton = find.byType(RawMaterialButton); |
497 | expect(tester.widget<RawMaterialButton>(rawMaterialButton).enabled, true); |
498 | await tester.longPress(rawMaterialButton); |
499 | expect(wasPressed, true); |
500 | |
501 | // onPressed null, onLongPress null. |
502 | await tester.pumpWidget(buildFrame()); |
503 | rawMaterialButton = find.byType(RawMaterialButton); |
504 | expect(tester.widget<RawMaterialButton>(rawMaterialButton).enabled, false); |
505 | }, |
506 | ); |
507 | |
508 | testWidgets('RawMaterialButton onPressed and onLongPress callbacks are distinctly recognized' , ( |
509 | WidgetTester tester, |
510 | ) async { |
511 | bool didPressButton = false; |
512 | bool didLongPressButton = false; |
513 | |
514 | await tester.pumpWidget( |
515 | Directionality( |
516 | textDirection: TextDirection.ltr, |
517 | child: RawMaterialButton( |
518 | onPressed: () { |
519 | didPressButton = true; |
520 | }, |
521 | onLongPress: () { |
522 | didLongPressButton = true; |
523 | }, |
524 | child: const Text('button' ), |
525 | ), |
526 | ), |
527 | ); |
528 | |
529 | final Finder rawMaterialButton = find.byType(RawMaterialButton); |
530 | expect(tester.widget<RawMaterialButton>(rawMaterialButton).enabled, true); |
531 | |
532 | expect(didPressButton, isFalse); |
533 | await tester.tap(rawMaterialButton); |
534 | expect(didPressButton, isTrue); |
535 | |
536 | expect(didLongPressButton, isFalse); |
537 | await tester.longPress(rawMaterialButton); |
538 | expect(didLongPressButton, isTrue); |
539 | }); |
540 | |
541 | testWidgets('RawMaterialButton responds to density changes.' , (WidgetTester tester) async { |
542 | const Key key = Key('test' ); |
543 | const Key childKey = Key('test child' ); |
544 | |
545 | Future<void> buildTest(VisualDensity visualDensity, {bool useText = false}) async { |
546 | return tester.pumpWidget( |
547 | MaterialApp( |
548 | theme: ThemeData(useMaterial3: false), |
549 | home: Directionality( |
550 | textDirection: TextDirection.rtl, |
551 | child: Center( |
552 | child: RawMaterialButton( |
553 | visualDensity: visualDensity, |
554 | key: key, |
555 | onPressed: () {}, |
556 | child: |
557 | useText |
558 | ? const Text('Text' , key: childKey) |
559 | : Container( |
560 | key: childKey, |
561 | width: 100, |
562 | height: 100, |
563 | color: const Color(0xffff0000), |
564 | ), |
565 | ), |
566 | ), |
567 | ), |
568 | ), |
569 | ); |
570 | } |
571 | |
572 | await buildTest(VisualDensity.standard); |
573 | final RenderBox box = tester.renderObject(find.byKey(key)); |
574 | Rect childRect = tester.getRect(find.byKey(childKey)); |
575 | await tester.pumpAndSettle(); |
576 | expect(box.size, equals(const Size(100, 100))); |
577 | expect(childRect, equals(const Rect.fromLTRB(350, 250, 450, 350))); |
578 | |
579 | await buildTest(const VisualDensity(horizontal: 3.0, vertical: 3.0)); |
580 | await tester.pumpAndSettle(); |
581 | childRect = tester.getRect(find.byKey(childKey)); |
582 | expect(box.size, equals(const Size(124, 124))); |
583 | expect(childRect, equals(const Rect.fromLTRB(350, 250, 450, 350))); |
584 | |
585 | await buildTest(const VisualDensity(horizontal: -3.0, vertical: -3.0)); |
586 | await tester.pumpAndSettle(); |
587 | childRect = tester.getRect(find.byKey(childKey)); |
588 | expect(box.size, equals(const Size(100, 100))); |
589 | expect(childRect, equals(const Rect.fromLTRB(350, 250, 450, 350))); |
590 | |
591 | await buildTest(VisualDensity.standard, useText: true); |
592 | await tester.pumpAndSettle(); |
593 | childRect = tester.getRect(find.byKey(childKey)); |
594 | expect(box.size, equals(const Size(88, 48))); |
595 | expect(childRect, equals(const Rect.fromLTRB(372.0, 293.0, 428.0, 307.0))); |
596 | |
597 | await buildTest(const VisualDensity(horizontal: 3.0, vertical: 3.0), useText: true); |
598 | await tester.pumpAndSettle(); |
599 | childRect = tester.getRect(find.byKey(childKey)); |
600 | expect(box.size, equals(const Size(100, 60))); |
601 | expect(childRect, equals(const Rect.fromLTRB(372.0, 293.0, 428.0, 307.0))); |
602 | |
603 | await buildTest(const VisualDensity(horizontal: -3.0, vertical: -3.0), useText: true); |
604 | await tester.pumpAndSettle(); |
605 | childRect = tester.getRect(find.byKey(childKey)); |
606 | expect(box.size, equals(const Size(76, 36))); |
607 | expect(childRect, equals(const Rect.fromLTRB(372.0, 293.0, 428.0, 307.0))); |
608 | }); |
609 | |
610 | testWidgets('RawMaterialButton changes mouse cursor when hovered' , (WidgetTester tester) async { |
611 | await tester.pumpWidget( |
612 | Directionality( |
613 | textDirection: TextDirection.ltr, |
614 | child: MouseRegion( |
615 | cursor: SystemMouseCursors.forbidden, |
616 | child: RawMaterialButton(onPressed: () {}, mouseCursor: SystemMouseCursors.text), |
617 | ), |
618 | ), |
619 | ); |
620 | |
621 | final TestGesture gesture = await tester.createGesture( |
622 | kind: PointerDeviceKind.mouse, |
623 | pointer: 1, |
624 | ); |
625 | await gesture.addPointer(location: Offset.zero); |
626 | |
627 | await tester.pump(); |
628 | |
629 | expect( |
630 | RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), |
631 | SystemMouseCursors.text, |
632 | ); |
633 | |
634 | // Test default cursor |
635 | await tester.pumpWidget( |
636 | Directionality( |
637 | textDirection: TextDirection.ltr, |
638 | child: MouseRegion( |
639 | cursor: SystemMouseCursors.forbidden, |
640 | child: RawMaterialButton(onPressed: () {}), |
641 | ), |
642 | ), |
643 | ); |
644 | |
645 | expect( |
646 | RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), |
647 | SystemMouseCursors.click, |
648 | ); |
649 | |
650 | // Test default cursor when disabled |
651 | await tester.pumpWidget( |
652 | const Directionality( |
653 | textDirection: TextDirection.ltr, |
654 | child: MouseRegion( |
655 | cursor: SystemMouseCursors.forbidden, |
656 | child: RawMaterialButton(onPressed: null), |
657 | ), |
658 | ), |
659 | ); |
660 | |
661 | expect( |
662 | RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), |
663 | SystemMouseCursors.basic, |
664 | ); |
665 | }); |
666 | } |
667 | |