Unverified Commit 78367258 authored by derdilla's avatar derdilla Committed by GitHub

Test cover cupertino text field for memory leaks. (#135804)

parent cfe7afdc
......@@ -17,6 +17,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../widgets/clipboard_utils.dart';
import '../widgets/editable_text_utils.dart' show OverflowWidgetTextEditingController;
......@@ -208,15 +209,17 @@ void main() {
});
testWidgets(
testWidgetsWithLeakTracking(
'Live Text button shows and hides correctly when LiveTextStatus changes',
(WidgetTester tester) async {
final LiveTextInputTester liveTextInputTester = LiveTextInputTester();
addTearDown(liveTextInputTester.dispose);
final TextEditingController controller = TextEditingController(text: '');
addTearDown(controller.dispose);
const Key key = ValueKey<String>('TextField');
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
final Widget app = MaterialApp(
theme: ThemeData(platform: TargetPlatform.iOS),
home: Scaffold(
......@@ -250,7 +253,7 @@ void main() {
},
);
testWidgets('Look Up shows up on iOS only', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Look Up shows up on iOS only', (WidgetTester tester) async {
String? lastLookUp;
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
......@@ -264,6 +267,7 @@ void main() {
final TextEditingController controller = TextEditingController(
text: 'Test',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -299,7 +303,7 @@ void main() {
skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu.
);
testWidgets('Search Web shows up on iOS only', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Search Web shows up on iOS only', (WidgetTester tester) async {
String? lastSearch;
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
......@@ -313,6 +317,7 @@ void main() {
final TextEditingController controller = TextEditingController(
text: 'Test',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -348,7 +353,7 @@ void main() {
skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu.
);
testWidgets('Share shows up on iOS only', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Share shows up on iOS only', (WidgetTester tester) async {
String? lastShare;
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
......@@ -362,6 +367,7 @@ void main() {
final TextEditingController controller = TextEditingController(
text: 'Test',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -397,10 +403,11 @@ void main() {
skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu.
);
testWidgets('can use the desktop cut/copy/paste buttons on Mac', (WidgetTester tester) async {
testWidgetsWithLeakTracking('can use the desktop cut/copy/paste buttons on Mac', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'blah1 blah2',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -472,11 +479,13 @@ void main() {
skip: kIsWeb, // [intended] the web handles this on its own.
);
testWidgets('can get text selection color initially on desktop', (WidgetTester tester) async {
testWidgetsWithLeakTracking('can get text selection color initially on desktop', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
final TextEditingController controller = TextEditingController(
text: 'blah1 blah2',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -502,10 +511,11 @@ void main() {
);
});
testWidgets('Activates the text field when receives semantics focus on Mac, Windows', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Activates the text field when receives semantics focus on Mac, Windows', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner!;
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget(
CupertinoApp(
home: CupertinoTextField(focusNode: focusNode),
......@@ -552,7 +562,7 @@ void main() {
semantics.dispose();
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS, TargetPlatform.windows }));
testWidgets(
testWidgetsWithLeakTracking(
'takes available space horizontally and takes intrinsic space vertically no-strut',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -573,7 +583,7 @@ void main() {
},
);
testWidgets('sets cursorOpacityAnimates on EditableText correctly', (WidgetTester tester) async {
testWidgetsWithLeakTracking('sets cursorOpacityAnimates on EditableText correctly', (WidgetTester tester) async {
// True
......@@ -598,7 +608,7 @@ void main() {
expect(editableText.cursorOpacityAnimates, false);
});
testWidgets(
testWidgetsWithLeakTracking(
'takes available space horizontally and takes intrinsic space vertically',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -619,7 +629,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'uses DefaultSelectionStyle for selection and cursor colors if provided',
(WidgetTester tester) async {
const Color selectionColor = Colors.black;
......@@ -645,11 +655,12 @@ void main() {
},
);
testWidgets('Text field drops selection color when losing focus', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Text field drops selection color when losing focus', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/103341.
final Key key1 = UniqueKey();
final Key key2 = UniqueKey();
final TextEditingController controller1 = TextEditingController();
addTearDown(controller1.dispose);
const Color selectionColor = Colors.orange;
const Color cursorColor = Colors.red;
......@@ -702,7 +713,7 @@ void main() {
expect(state2.widget.selectionColor, selectionColor);
});
testWidgets(
testWidgetsWithLeakTracking(
'multi-lined text fields are intrinsically taller no-strut',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -726,7 +737,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'multi-lined text fields are intrinsically taller',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -747,7 +758,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'strut height override',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -776,7 +787,7 @@ void main() {
skip: isBrowser, // https://github.com/flutter/flutter/issues/32243
);
testWidgets(
testWidgetsWithLeakTracking(
'strut forces field taller',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -806,7 +817,7 @@ void main() {
skip: isBrowser, // https://github.com/flutter/flutter/issues/32243
);
testWidgets(
testWidgetsWithLeakTracking(
'default text field has a border',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -861,7 +872,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'decoration can be overridden',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -884,14 +895,16 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'text entries are padded by default',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(text: 'initial');
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoTextField(
controller: TextEditingController(text: 'initial'),
controller: controller,
),
),
),
......@@ -904,7 +917,7 @@ void main() {
},
);
testWidgets('iOS cursor has offset', (WidgetTester tester) async {
testWidgetsWithLeakTracking('iOS cursor has offset', (WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: CupertinoTextField(),
......@@ -915,7 +928,7 @@ void main() {
expect(editableText.cursorOffset, const Offset(-2.0 / 3.0, 0));
});
testWidgets('Cursor radius is 2.0', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cursor radius is 2.0', (WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: CupertinoTextField(),
......@@ -928,7 +941,7 @@ void main() {
expect(renderEditable.cursorRadius, const Radius.circular(2.0));
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('Cupertino cursor android golden', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cupertino cursor android golden', (WidgetTester tester) async {
final Widget widget = CupertinoApp(
home: Center(
child: RepaintBoundary(
......@@ -955,7 +968,7 @@ void main() {
);
});
testWidgets('Cupertino cursor golden', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cupertino cursor golden', (WidgetTester tester) async {
final Widget widget = CupertinoApp(
home: Center(
child: RepaintBoundary(
......@@ -984,10 +997,11 @@ void main() {
);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets(
testWidgetsWithLeakTracking(
'can control text content via controller',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -1011,7 +1025,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'placeholder respects textAlign',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -1036,7 +1050,7 @@ void main() {
},
);
testWidgets('placeholder dark mode', (WidgetTester tester) async {
testWidgetsWithLeakTracking('placeholder dark mode', (WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
theme: CupertinoThemeData(brightness: Brightness.dark),
......@@ -1053,7 +1067,7 @@ void main() {
expect(placeholder.style!.color!.value, CupertinoColors.placeholderText.darkColor.value);
});
testWidgets(
testWidgetsWithLeakTracking(
'placeholders are lightly colored and disappears once typing starts',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -1076,7 +1090,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
"placeholderStyle modifies placeholder's style and doesn't affect text's style",
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -1110,17 +1124,20 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'prefix widget is in front of the text',
(WidgetTester tester) async {
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
final TextEditingController controller = TextEditingController(text: 'input');
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: CupertinoTextField(
focusNode: focusNode,
prefix: const Icon(CupertinoIcons.add),
controller: TextEditingController(text: 'input'),
controller: controller,
),
),
),
......@@ -1140,7 +1157,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'prefix widget respects visibility mode',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -1177,10 +1194,11 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'suffix widget is after the text',
(WidgetTester tester) async {
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -1206,7 +1224,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'suffix widget respects visibility mode',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -1230,7 +1248,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'can customize padding',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -1250,7 +1268,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'padding is in between prefix and suffix no-strut',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -1308,7 +1326,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'padding is in between prefix and suffix',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -1364,10 +1382,11 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'clear button shows with right visibility mode',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -1435,10 +1454,11 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'clear button removes text',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -1464,11 +1484,12 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'tapping clear button also calls onChanged when text not empty',
(WidgetTester tester) async {
String value = 'text entry';
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -1494,10 +1515,11 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'clear button yields precedence to suffix',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -1533,7 +1555,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'font style controls intrinsic height no-strut',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -1572,7 +1594,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'font style controls intrinsic height',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -1608,7 +1630,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'RTL puts attachments to the right places',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -1638,7 +1660,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'text fields with no max lines can grow no-strut',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -1667,7 +1689,7 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'text fields with no max lines can grow',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -1695,8 +1717,9 @@ void main() {
},
);
testWidgets('cannot enter new lines onto single line TextField', (WidgetTester tester) async {
testWidgetsWithLeakTracking('cannot enter new lines onto single line TextField', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -1713,10 +1736,11 @@ void main() {
expect(controller.text, 'abcdef');
});
testWidgets('toolbar colors change with theme brightness, but nothing else', (WidgetTester tester) async {
testWidgetsWithLeakTracking('toolbar colors change with theme brightness, but nothing else', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: "j'aime la poutine",
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -1775,10 +1799,11 @@ void main() {
expect(text.style!.fontWeight, FontWeight.w400);
}, skip: isContextMenuProvidedByPlatform); // [intended] only applies to platforms where we supply the context menu.
testWidgets('text field toolbar options correctly changes options on Apple Platforms', (WidgetTester tester) async {
testWidgetsWithLeakTracking('text field toolbar options correctly changes options on Apple Platforms', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Column(
......@@ -1825,10 +1850,11 @@ void main() {
skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu.
);
testWidgets('text field toolbar options correctly changes options on non-Apple Platforms', (WidgetTester tester) async {
testWidgetsWithLeakTracking('text field toolbar options correctly changes options on non-Apple Platforms', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Column(
......@@ -1880,8 +1906,9 @@ void main() {
skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu.
);
testWidgets('Read only text field', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Read only text field', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(text: 'readonly');
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -1917,7 +1944,7 @@ void main() {
expect(find.text('Cut'), findsNothing);
}, skip: isContextMenuProvidedByPlatform); // [intended] only applies to platforms where we supply the context menu.
testWidgets('copy paste', (WidgetTester tester) async {
testWidgetsWithLeakTracking('copy paste', (WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: Column(
......@@ -1970,12 +1997,13 @@ void main() {
expect(Visibility.of(placeholder2Element), false);
}, skip: isContextMenuProvidedByPlatform); // [intended] only applies to platforms where we supply the context menu.
testWidgets(
testWidgetsWithLeakTracking(
'tap moves cursor to the edge of the word it tapped on',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -2001,12 +2029,13 @@ void main() {
expect(find.byType(CupertinoButton), findsNothing);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }));
testWidgets(
testWidgetsWithLeakTracking(
'slow double tap does not trigger double tap',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
// On iOS/iPadOS, during a tap we select the edge of the word closest to the tap.
// On macOS, we select the precise position of the tap.
final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS;
......@@ -2035,12 +2064,13 @@ void main() {
expect(find.byType(CupertinoButton), isContextMenuProvidedByPlatform ? findsNothing : isTargetPlatformIOS ? findsNWidgets(2) : findsNothing);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets(
testWidgetsWithLeakTracking(
'Tapping on a collapsed selection toggles the toolbar',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neigse Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neiges',
);
addTearDown(controller.dispose);
// On iOS/iPadOS, during a tap we select the edge of the word closest to the tap.
await tester.pumpWidget(
CupertinoApp(
......@@ -2120,12 +2150,13 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
);
testWidgets(
testWidgetsWithLeakTracking(
'Tapping on a non-collapsed selection toggles the toolbar and retains the selection',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
// On iOS/iPadOS, during a tap we select the edge of the word closest to the tap.
await tester.pumpWidget(
CupertinoApp(
......@@ -2194,12 +2225,13 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
);
testWidgets(
testWidgetsWithLeakTracking(
'double tap selects word for non-Apple platforms',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -2249,12 +2281,13 @@ void main() {
variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS}),
);
testWidgets(
testWidgetsWithLeakTracking(
'double tap selects word for Apple platforms',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -2308,12 +2341,13 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
);
testWidgets(
testWidgetsWithLeakTracking(
'double tap does not select word on read-only obscured field',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -2346,10 +2380,11 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'Can double click + drag with a mouse to select word by word',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -2395,10 +2430,11 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'Can double tap + drag to select word by word',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -2450,9 +2486,14 @@ void main() {
await tester.pump();
expect(find.byType(CupertinoButton), isContextMenuProvidedByPlatform ? findsNothing : findsNWidgets(4));
},
// TODO(derdilla): remove after fixing and leak track other failing tests in
// this file. https://github.com/flutter/flutter/issues/135803
leakTrackingTestConfig: const LeakTrackingTestConfig(notDisposedAllowList:
<String, int?>{'ValueNotifier<_OverlayEntryWidgetState?>': 1})
);
//
testWidgets('Readonly text field does not have tap action', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Readonly text field does not have tap action', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(
......@@ -2471,12 +2512,13 @@ void main() {
semantics.dispose();
});
testWidgets(
testWidgetsWithLeakTracking(
'double tap selects word and first tap of double tap moves cursor',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
// On iOS/iPadOS, during a tap we select the edge of the word closest to the tap.
// On macOS, we select the precise position of the tap.
final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS;
......@@ -2516,12 +2558,13 @@ void main() {
expect(find.byType(CupertinoButton), isContextMenuProvidedByPlatform ? findsNothing : (isTargetPlatformIOS ? findsNWidgets(6) : findsNWidgets(3)));
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets(
testWidgetsWithLeakTracking(
'double tap hold selects word',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -2575,12 +2618,13 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'tap after a double tap select is not affected',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
// On iOS/iPadOS, during a tap we select the edge of the word closest to the tap.
// On macOS, we select the precise position of the tap.
final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS;
......@@ -2620,10 +2664,11 @@ void main() {
expect(find.byType(CupertinoButton), findsNothing);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('double tapping a space selects the previous word on iOS', (WidgetTester tester) async {
testWidgetsWithLeakTracking('double tapping a space selects the previous word on iOS', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: ' blah blah \n blah',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -2689,10 +2734,11 @@ void main() {
expect(controller.value.selection.extentOffset, 14);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('double tapping a space selects the space on Mac', (WidgetTester tester) async {
testWidgetsWithLeakTracking('double tapping a space selects the space on Mac', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: ' blah blah',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -2743,10 +2789,11 @@ void main() {
expect(controller.value.selection.extentOffset, 1);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS }));
testWidgets('double clicking a space selects the space on Mac', (WidgetTester tester) async {
testWidgetsWithLeakTracking('double clicking a space selects the space on Mac', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: ' blah blah',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -2810,12 +2857,13 @@ void main() {
expect(controller.value.selection.extentOffset, 1);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS }));
testWidgets(
testWidgetsWithLeakTracking(
'An obscured CupertinoTextField is not selectable when disabled',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -2858,12 +2906,13 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'A read-only obscured CupertinoTextField is not selectable',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -2906,12 +2955,13 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'An obscured CupertinoTextField is selectable by default',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -2953,10 +3003,11 @@ void main() {
},
);
testWidgets('An obscured TextField has correct default context menu', (WidgetTester tester) async {
testWidgetsWithLeakTracking('An obscured TextField has correct default context menu', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -2997,12 +3048,13 @@ void main() {
expect(find.text('Cut'), findsNothing);
}, skip: isContextMenuProvidedByPlatform); // [intended] only applies to platforms where we supply the context menu.
testWidgets(
testWidgetsWithLeakTracking(
'long press selects the word at the long press position and shows toolbar on non-Apple platforms',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -3030,12 +3082,13 @@ void main() {
variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
);
testWidgets(
testWidgetsWithLeakTracking(
'long press moves cursor to the exact long press position and shows toolbar on Apple platforms',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -3074,12 +3127,13 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
);
testWidgets(
testWidgetsWithLeakTracking(
'long press tap cannot initiate a double tap',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -3124,12 +3178,13 @@ void main() {
expect(find.byType(CupertinoButton), findsNothing);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets(
testWidgetsWithLeakTracking(
'long press drag selects word by word and shows toolbar on lift on non-Apple platforms',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -3188,12 +3243,13 @@ void main() {
variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
);
testWidgets(
testWidgetsWithLeakTracking(
'long press drag on a focused TextField moves the cursor under the drag and shows toolbar on lift on Apple platforms',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -3263,10 +3319,11 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
);
testWidgets('long press drag can edge scroll on non-Apple platforms', (WidgetTester tester) async {
testWidgetsWithLeakTracking('long press drag can edge scroll on non-Apple platforms', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neiges',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -3349,10 +3406,11 @@ void main() {
expect(firstCharEndpoint[0].point.dx, moreOrLessEquals(-310.30, epsilon: 1));
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('long press drag can edge scroll on Apple platforms', (WidgetTester tester) async {
testWidgetsWithLeakTracking('long press drag can edge scroll on Apple platforms', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neiges',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -3450,12 +3508,13 @@ void main() {
expect(firstCharEndpoint[0].point.dx, moreOrLessEquals(-310.20, epsilon: 0.25));
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets(
testWidgetsWithLeakTracking(
'long tap after a double tap select is not affected',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
// On iOS/iPadOS, during a tap we select the edge of the word closest to the tap.
// On macOS, we select the precise position of the tap.
final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS;
......@@ -3502,12 +3561,13 @@ void main() {
expect(find.byType(CupertinoButton), findsNWidgets(toolbarButtons));
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets(
testWidgetsWithLeakTracking(
'double tap after a long tap is not affected',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
// On iOS/iPadOS, during a tap we select the edge of the word closest to the tap.
// On macOS, we select the precise position of the tap.
final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS;
......@@ -3561,12 +3621,13 @@ void main() {
expect(find.byType(CupertinoButton), isContextMenuProvidedByPlatform ? findsNothing : (isTargetPlatformIOS ? findsNWidgets(6) : findsNWidgets(3)));
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets(
testWidgetsWithLeakTracking(
'double tap chains work',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -3640,11 +3701,12 @@ void main() {
'all good people\n' // 22 + 16 => 38
'to come to the aid\n' // 38 + 19 => 57
'of their country.'; // 57 + 17 => 74
testWidgets(
testWidgetsWithLeakTracking(
'Can triple tap to select a paragraph on mobile platforms when tapping at a word edge',
(WidgetTester tester) async {
// TODO(Renzo-Olivares): Enable, currently broken because selection overlay blocks the TextSelectionGestureDetector.
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
final bool isTargetPlatformApple = defaultTargetPlatform == TargetPlatform.iOS;
await tester.pumpWidget(
......@@ -3700,10 +3762,11 @@ void main() {
skip: true, // https://github.com/flutter/flutter/issues/123415
);
testWidgets(
testWidgetsWithLeakTracking(
'Can triple tap to select a paragraph on mobile platforms',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
final bool isTargetPlatformApple = defaultTargetPlatform == TargetPlatform.iOS;
await tester.pumpWidget(
......@@ -3758,11 +3821,12 @@ void main() {
variant: TargetPlatformVariant.mobile(),
);
testWidgets(
testWidgetsWithLeakTracking(
'Triple click at the beginning of a line should not select the previous paragraph',
(WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/132126
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -3815,11 +3879,12 @@ void main() {
variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.linux }),
);
testWidgets(
testWidgetsWithLeakTracking(
'Triple click at the end of text should select the previous paragraph',
(WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/132126.
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -3873,12 +3938,13 @@ void main() {
variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.linux }),
);
testWidgets(
testWidgetsWithLeakTracking(
'triple tap chains work on Non-Apple mobile platforms',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -3963,12 +4029,13 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.fuchsia }),
);
testWidgets(
testWidgetsWithLeakTracking(
'triple tap chains work on Apple platforms',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure\nThe fox jumped over the fence.',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -4063,12 +4130,13 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
);
testWidgets(
testWidgetsWithLeakTracking(
'triple click chains work',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: testValueA,
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -4180,12 +4248,13 @@ void main() {
variant: TargetPlatformVariant.desktop(),
);
testWidgets(
testWidgetsWithLeakTracking(
'triple click after a click on desktop platforms',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: testValueA,
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -4244,12 +4313,13 @@ void main() {
variant: TargetPlatformVariant.desktop(),
);
testWidgets(
testWidgetsWithLeakTracking(
'Can triple tap to select all on a single-line textfield on mobile platforms',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: testValueB,
);
addTearDown(controller.dispose);
final bool isTargetPlatformApple = defaultTargetPlatform == TargetPlatform.iOS;
await tester.pumpWidget(
......@@ -4299,12 +4369,13 @@ void main() {
variant: TargetPlatformVariant.mobile(),
);
testWidgets(
testWidgetsWithLeakTracking(
'Can triple click to select all on a single-line textfield on desktop platforms',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: testValueA,
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -4355,10 +4426,11 @@ void main() {
variant: TargetPlatformVariant.desktop(),
);
testWidgets(
testWidgetsWithLeakTracking(
'Can triple click to select a line on Linux',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -4416,10 +4488,11 @@ void main() {
variant: TargetPlatformVariant.only(TargetPlatform.linux),
);
testWidgets(
testWidgetsWithLeakTracking(
'Can triple click to select a paragraph',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -4477,10 +4550,11 @@ void main() {
variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.linux }),
);
testWidgets(
testWidgetsWithLeakTracking(
'Can triple click + drag to select line by line on Linux',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -4579,10 +4653,11 @@ void main() {
variant: TargetPlatformVariant.only(TargetPlatform.linux),
);
testWidgets(
testWidgetsWithLeakTracking(
'Can triple click + drag to select paragraph by paragraph',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -4681,12 +4756,13 @@ void main() {
variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.linux }),
);
testWidgets(
testWidgetsWithLeakTracking(
'Going past triple click retains the selection on Apple platforms',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: testValueA,
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -4768,12 +4844,13 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
);
testWidgets(
testWidgetsWithLeakTracking(
'Tap count resets when going past a triple tap on Android, Fuchsia, and Linux',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: testValueA,
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -4882,12 +4959,13 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.linux }),
);
testWidgets(
testWidgetsWithLeakTracking(
'Double click and triple click alternate on Windows',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: testValueA,
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -5000,10 +5078,11 @@ void main() {
);
});
testWidgets('force press selects word', (WidgetTester tester) async {
testWidgetsWithLeakTracking('force press selects word', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -5055,10 +5134,11 @@ void main() {
expect(find.byType(CupertinoButton), matchToolbarButtons);
});
testWidgets('force press on unsupported devices falls back to tap', (WidgetTester tester) async {
testWidgetsWithLeakTracking('force press on unsupported devices falls back to tap', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
// On iOS/iPadOS, during a tap we select the edge of the word closest to the tap.
// On macOS, we select the precise position of the tap.
final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS;
......@@ -5098,10 +5178,11 @@ void main() {
expect(find.byType(CupertinoButton), findsNothing);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('Cannot drag one handle past the other', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cannot drag one handle past the other', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'abc def ghi',
);
addTearDown(controller.dispose);
// On iOS/iPadOS, during a tap we select the edge of the word closest to the tap.
// On macOS, we select the precise position of the tap.
final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS;
......@@ -5165,11 +5246,12 @@ void main() {
expect(controller.selection.extentOffset, 5);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('Dragging between multiple lines keeps the contact point at the same place on the handle on Android', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Dragging between multiple lines keeps the contact point at the same place on the handle on Android', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
// 11 first line, 19 second line, 17 third line = length 49
text: 'a big house\njumped over a mouse\nOne more line yay',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -5363,11 +5445,12 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android }),
);
testWidgets('Dragging between multiple lines keeps the contact point at the same place on the handle on iOS', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Dragging between multiple lines keeps the contact point at the same place on the handle on iOS', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
// 11 first line, 19 second line, 17 third line = length 49
text: 'a big house\njumped over a mouse\nOne more line yay',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -5552,8 +5635,9 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
);
testWidgets('Selection updates on tap down (Desktop platforms)', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Selection updates on tap down (Desktop platforms)', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -5593,8 +5677,9 @@ void main() {
variant: TargetPlatformVariant.desktop(),
);
testWidgets('Selection updates on tap up (Mobile platforms)', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Selection updates on tap up (Mobile platforms)', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
final bool isTargetPlatformApple = defaultTargetPlatform == TargetPlatform.iOS;
await tester.pumpWidget(
......@@ -5649,8 +5734,9 @@ void main() {
variant: TargetPlatformVariant.mobile(),
);
testWidgets('Can select text by dragging with a mouse', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Can select text by dragging with a mouse', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -5684,8 +5770,9 @@ void main() {
expect(controller.selection.extentOffset, testValue.indexOf('g'));
});
testWidgets('Cursor should not move on a quick touch drag when touch does not begin on previous selection (iOS)', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cursor should not move on a quick touch drag when touch does not begin on previous selection (iOS)', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -5731,6 +5818,7 @@ void main() {
testWidgets('Can move cursor when dragging, when tap is on collapsed selection (iOS)', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -5778,6 +5866,7 @@ void main() {
testWidgets('Can move cursor when dragging, when tap is on collapsed selection (iOS) - multiline', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -5824,10 +5913,11 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
);
testWidgets('Can move cursor when dragging, when tap is on collapsed selection (iOS) - ListView', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Can move cursor when dragging, when tap is on collapsed selection (iOS) - ListView', (WidgetTester tester) async {
// This is a regression test for
// https://github.com/flutter/flutter/issues/122519
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -5902,6 +5992,7 @@ void main() {
testWidgets('Can move cursor when dragging (Android)', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -5944,10 +6035,11 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.fuchsia }),
);
testWidgets('Continuous dragging does not cause flickering', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Continuous dragging does not cause flickering', (WidgetTester tester) async {
int selectionChangedCount = 0;
const String testValue = 'abc def ghi';
final TextEditingController controller = TextEditingController(text: testValue);
addTearDown(controller.dispose);
controller.addListener(() {
selectionChangedCount++;
......@@ -5996,10 +6088,11 @@ void main() {
expect(controller.selection.extentOffset, 9);
});
testWidgets('Tap does not show handles nor toolbar', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Tap does not show handles nor toolbar', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'abc def ghi',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -6018,10 +6111,11 @@ void main() {
expect(editableText.selectionOverlay!.toolbarIsVisible, isFalse);
});
testWidgets('Long press shows toolbar but not handles', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Long press shows toolbar but not handles', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'abc def ghi',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -6042,12 +6136,13 @@ void main() {
expect(editableText.selectionOverlay!.toolbarIsVisible, isContextMenuProvidedByPlatform ? isFalse : isTrue);
});
testWidgets(
testWidgetsWithLeakTracking(
'Double tap shows handles and toolbar if selection is not collapsed',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'abc def ghi',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -6071,12 +6166,13 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'Double tap shows toolbar but not handles if selection is collapsed',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'abc def ghi',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -6100,12 +6196,13 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'Mouse long press does not show handles nor toolbar',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'abc def ghi',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -6131,12 +6228,13 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'Mouse double tap does not show handles nor toolbar',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'abc def ghi',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -6182,7 +6280,7 @@ void main() {
},
);
testWidgets('onTap is called upon tap', (WidgetTester tester) async {
testWidgetsWithLeakTracking('onTap is called upon tap', (WidgetTester tester) async {
int tapCount = 0;
await tester.pumpWidget(
CupertinoApp(
......@@ -6211,7 +6309,7 @@ void main() {
expect(tapCount, 2);
});
testWidgets(
testWidgetsWithLeakTracking(
'onTap does not work when the text field is disabled',
(WidgetTester tester) async {
int tapCount = 0;
......@@ -6268,8 +6366,9 @@ void main() {
},
);
testWidgets('Focus test when the text field is disabled', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Focus test when the text field is disabled', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -6305,7 +6404,7 @@ void main() {
expect(focusNode.hasFocus, false);
});
testWidgets(
testWidgetsWithLeakTracking(
'text field respects theme',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -6343,13 +6442,14 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'Check the toolbar appears below the TextField when there is not enough space above the TextField to show it',
(WidgetTester tester) async {
// This is a regression test for
// https://github.com/flutter/flutter/issues/29808
const String testValue = 'abc def ghi';
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -6414,7 +6514,7 @@ void main() {
skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu.
);
testWidgets('text field respects keyboardAppearance from theme', (WidgetTester tester) async {
testWidgetsWithLeakTracking('text field respects keyboardAppearance from theme', (WidgetTester tester) async {
final List<MethodCall> log = <MethodCall>[];
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
log.add(methodCall);
......@@ -6438,7 +6538,7 @@ void main() {
expect(((setClient.arguments as List<dynamic>).last as Map<String, dynamic>)['keyboardAppearance'], 'Brightness.dark');
});
testWidgets('text field can override keyboardAppearance from theme', (WidgetTester tester) async {
testWidgetsWithLeakTracking('text field can override keyboardAppearance from theme', (WidgetTester tester) async {
final List<MethodCall> log = <MethodCall>[];
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
log.add(methodCall);
......@@ -6464,7 +6564,7 @@ void main() {
expect(((setClient.arguments as List<dynamic>).last as Map<String, dynamic>)['keyboardAppearance'], 'Brightness.light');
});
testWidgets('cursorColor respects theme', (WidgetTester tester) async {
testWidgetsWithLeakTracking('cursorColor respects theme', (WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: CupertinoTextField(),
......@@ -6506,7 +6606,7 @@ void main() {
expect(renderEditable.cursorColor, const Color(0xFFF44336));
});
testWidgets('cursor can override color from theme', (WidgetTester tester) async {
testWidgetsWithLeakTracking('cursor can override color from theme', (WidgetTester tester) async {
const CupertinoDynamicColor cursorColor = CupertinoDynamicColor.withBrightness(
color: Color(0x12345678),
darkColor: Color(0x87654321),
......@@ -6541,9 +6641,10 @@ void main() {
expect(editableText.cursorColor.value, 0x87654321);
});
testWidgets('shows selection handles', (WidgetTester tester) async {
testWidgetsWithLeakTracking('shows selection handles', (WidgetTester tester) async {
const String testText = 'lorem ipsum';
final TextEditingController controller = TextEditingController(text: testText);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -6573,9 +6674,11 @@ void main() {
expect(right.opacity.value, equals(1.0));
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('when CupertinoTextField would be blocked by keyboard, it is shown with enough space for the selection handle', (WidgetTester tester) async {
testWidgetsWithLeakTracking('when CupertinoTextField would be blocked by keyboard, it is shown with enough space for the selection handle', (WidgetTester tester) async {
final ScrollController scrollController = ScrollController();
addTearDown(scrollController.dispose);
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(CupertinoApp(
theme: const CupertinoThemeData(),
......@@ -6601,7 +6704,9 @@ void main() {
expect(scrollController.offset, 27.0);
});
testWidgets('disabled state golden', (WidgetTester tester) async {
testWidgetsWithLeakTracking('disabled state golden', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(text: 'lorem');
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: DecoratedBox(
......@@ -6613,7 +6718,7 @@ void main() {
child: RepaintBoundary(
key: const ValueKey<int>(1),
child: CupertinoTextField(
controller: TextEditingController(text: 'lorem'),
controller: controller,
enabled: false,
),
),
......@@ -6629,13 +6734,16 @@ void main() {
);
});
testWidgets(
testWidgetsWithLeakTracking(
'Can drag the left handle while the right handle remains off-screen',
(WidgetTester tester) async {
// Text is longer than textfield width.
const String testValue = 'aaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbb';
final TextEditingController controller = TextEditingController(text: testValue);
addTearDown(controller.dispose);
final ScrollController scrollController = ScrollController();
addTearDown(scrollController.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -6712,13 +6820,15 @@ void main() {
},
);
testWidgets(
testWidgetsWithLeakTracking(
'Can drag the right handle while the left handle remains off-screen',
(WidgetTester tester) async {
// Text is longer than textfield width.
const String testValue = 'aaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbb';
final TextEditingController controller = TextEditingController(text: testValue);
addTearDown(controller.dispose);
final ScrollController scrollController = ScrollController();
addTearDown(scrollController.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -6785,7 +6895,7 @@ void main() {
);
group('Text selection toolbar', () {
testWidgets('Collapsed selection works', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Collapsed selection works', (WidgetTester tester) async {
tester.view.physicalSize = const Size(400, 400);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset);
......@@ -6858,6 +6968,7 @@ void main() {
// Top Right collapsed selection. The toolbar should flip vertically, and
// the arrow should not point exactly to the caret because the caret is
// too close to the right.
controller.dispose();
controller = TextEditingController(text: List<String>.filled(200, 'a').join());
await tester.pumpWidget(
CupertinoApp(
......@@ -6918,7 +7029,9 @@ void main() {
// Normal centered collapsed selection. The toolbar arrow should point down, and
// it should point exactly to the caret.
controller.dispose();
controller = TextEditingController(text: List<String>.filled(200, 'a').join());
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
debugShowCheckedModeBanner: false,
......@@ -6971,7 +7084,7 @@ void main() {
);
});
testWidgets('selecting multiple words works', (WidgetTester tester) async {
testWidgetsWithLeakTracking('selecting multiple words works', (WidgetTester tester) async {
tester.view.physicalSize = const Size(400, 400);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset);
......@@ -6983,6 +7096,7 @@ void main() {
// Normal multiword collapsed selection. The toolbar arrow should point down, and
// it should point exactly to the caret.
controller = TextEditingController(text: List<String>.filled(20, 'a').join(' '));
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
debugShowCheckedModeBanner: false,
......@@ -7040,7 +7154,7 @@ void main() {
);
});
testWidgets('selecting multiline works', (WidgetTester tester) async {
testWidgetsWithLeakTracking('selecting multiline works', (WidgetTester tester) async {
tester.view.physicalSize = const Size(400, 400);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset);
......@@ -7052,6 +7166,7 @@ void main() {
// Normal multiline collapsed selection. The toolbar arrow should point down, and
// it should point exactly to the horizontal center of the text field.
controller = TextEditingController(text: List<String>.filled(20, 'a a ').join('\n'));
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
debugShowCheckedModeBanner: false,
......@@ -7115,11 +7230,12 @@ void main() {
// This is a regression test for
// https://github.com/flutter/flutter/issues/37046.
testWidgets('No exceptions when showing selection menu inside of nested Navigators', (WidgetTester tester) async {
testWidgetsWithLeakTracking('No exceptions when showing selection menu inside of nested Navigators', (WidgetTester tester) async {
const String testValue = '123456';
final TextEditingController controller = TextEditingController(
text: testValue,
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: CupertinoPageScaffold(
......@@ -7161,10 +7277,11 @@ void main() {
expect(tester.takeException(), null);
});
testWidgets('Drag selection hides the selection menu', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag selection hides the selection menu', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'blah1 blah2',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -7211,8 +7328,9 @@ void main() {
group('textAlignVertical position', () {
group('simple case', () {
testWidgets('align top (default)', (WidgetTester tester) async {
testWidgetsWithLeakTracking('align top (default)', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
const Size size = Size(200.0, 200.0);
await tester.pumpWidget(
CupertinoApp(
......@@ -7257,8 +7375,9 @@ void main() {
expect(tester.getTopLeft(find.byType(EditableText)).dy, moreOrLessEquals(207.0, epsilon: .0001));
});
testWidgets('align center', (WidgetTester tester) async {
testWidgetsWithLeakTracking('align center', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
const Size size = Size(200.0, 200.0);
await tester.pumpWidget(
CupertinoApp(
......@@ -7304,8 +7423,9 @@ void main() {
expect(tester.getTopLeft(find.byType(EditableText)).dy, moreOrLessEquals(291.5, epsilon: .0001));
});
testWidgets('align bottom', (WidgetTester tester) async {
testWidgetsWithLeakTracking('align bottom', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
const Size size = Size(200.0, 200.0);
await tester.pumpWidget(
CupertinoApp(
......@@ -7351,8 +7471,9 @@ void main() {
expect(tester.getTopLeft(find.byType(EditableText)).dy, moreOrLessEquals(376.0, epsilon: .0001));
});
testWidgets('align as a double', (WidgetTester tester) async {
testWidgetsWithLeakTracking('align as a double', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
const Size size = Size(200.0, 200.0);
await tester.pumpWidget(
CupertinoApp(
......@@ -7400,8 +7521,9 @@ void main() {
});
group('tall prefix', () {
testWidgets('align center (default when prefix)', (WidgetTester tester) async {
testWidgetsWithLeakTracking('align center (default when prefix)', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
const Size size = Size(200.0, 200.0);
await tester.pumpWidget(
CupertinoApp(
......@@ -7451,8 +7573,9 @@ void main() {
expect(tester.getTopLeft(find.byType(EditableText)).dy, moreOrLessEquals(291.5, epsilon: .0001));
});
testWidgets('align top', (WidgetTester tester) async {
testWidgetsWithLeakTracking('align top', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
const Size size = Size(200.0, 200.0);
await tester.pumpWidget(
CupertinoApp(
......@@ -7504,8 +7627,9 @@ void main() {
expect(tester.getTopLeft(find.byType(EditableText)).dy, moreOrLessEquals(241.5, epsilon: .0001));
});
testWidgets('align bottom', (WidgetTester tester) async {
testWidgetsWithLeakTracking('align bottom', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
const Size size = Size(200.0, 200.0);
await tester.pumpWidget(
CupertinoApp(
......@@ -7557,8 +7681,9 @@ void main() {
expect(tester.getTopLeft(find.byType(EditableText)).dy, moreOrLessEquals(341.5, epsilon: .0001));
});
testWidgets('align as a double', (WidgetTester tester) async {
testWidgetsWithLeakTracking('align as a double', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
const Size size = Size(200.0, 200.0);
await tester.pumpWidget(
CupertinoApp(
......@@ -7610,7 +7735,7 @@ void main() {
});
});
testWidgets(
testWidgetsWithLeakTracking(
'Long press on an autofocused field shows the selection menu',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -7637,7 +7762,7 @@ void main() {
);
});
testWidgets("Arrow keys don't move input focus", (WidgetTester tester) async {
testWidgetsWithLeakTracking("Arrow keys don't move input focus", (WidgetTester tester) async {
final TextEditingController controller1 = TextEditingController();
final TextEditingController controller2 = TextEditingController();
final TextEditingController controller3 = TextEditingController();
......@@ -7648,6 +7773,16 @@ void main() {
final FocusNode focusNode3 = FocusNode(debugLabel: 'Field 3');
final FocusNode focusNode4 = FocusNode(debugLabel: 'Field 4');
final FocusNode focusNode5 = FocusNode(debugLabel: 'Field 5');
addTearDown(focusNode1.dispose);
addTearDown(focusNode2.dispose);
addTearDown(focusNode3.dispose);
addTearDown(focusNode4.dispose);
addTearDown(focusNode5.dispose);
addTearDown(controller1.dispose);
addTearDown(controller2.dispose);
addTearDown(controller3.dispose);
addTearDown(controller4.dispose);
addTearDown(controller5.dispose);
// Lay out text fields in a "+" formation, and focus the center one.
await tester.pumpWidget(CupertinoApp(
......@@ -7724,7 +7859,7 @@ void main() {
expect(focusNode3.hasPrimaryFocus, isTrue);
}, variant: KeySimulatorTransitModeVariant.all());
testWidgets('Scrolling shortcuts are disabled in text fields', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Scrolling shortcuts are disabled in text fields', (WidgetTester tester) async {
bool scrollInvoked = false;
await tester.pumpWidget(
CupertinoApp(
......@@ -7758,7 +7893,7 @@ void main() {
expect(scrollInvoked, isFalse);
}, variant: KeySimulatorTransitModeVariant.all());
testWidgets('Cupertino text field semantics', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cupertino text field semantics', (WidgetTester tester) async {
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -7786,7 +7921,7 @@ void main() {
);
});
testWidgets('Disabled Cupertino text field semantics', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Disabled Cupertino text field semantics', (WidgetTester tester) async {
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -7815,10 +7950,11 @@ void main() {
);
});
testWidgets('text selection style 1', (WidgetTester tester) async {
testWidgetsWithLeakTracking('text selection style 1', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure\nhi\nwassssup!',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -7869,10 +8005,11 @@ void main() {
skip: kIsWeb, // [intended] the web has its own Select All.
);
testWidgets('text selection style 2', (WidgetTester tester) async {
testWidgetsWithLeakTracking('text selection style 2', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure\nhi\nwassssup!',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -7922,7 +8059,7 @@ void main() {
skip: kIsWeb, // [intended] the web has its own Select All.
);
testWidgets('textSelectionControls is passed to EditableText', (WidgetTester tester) async {
testWidgetsWithLeakTracking('textSelectionControls is passed to EditableText', (WidgetTester tester) async {
final MockTextSelectionControls selectionControl = MockTextSelectionControls();
await tester.pumpWidget(
CupertinoApp(
......@@ -7938,7 +8075,7 @@ void main() {
expect(widget.selectionControls, equals(selectionControl));
});
testWidgets('Do not add LengthLimiting formatter to the user supplied list', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Do not add LengthLimiting formatter to the user supplied list', (WidgetTester tester) async {
final List<TextInputFormatter> formatters = <TextInputFormatter>[];
await tester.pumpWidget(
......@@ -7971,7 +8108,7 @@ void main() {
await tester.pumpAndSettle();
}
testWidgets('using none enforcement.', (WidgetTester tester) async {
testWidgetsWithLeakTracking('using none enforcement.', (WidgetTester tester) async {
const MaxLengthEnforcement enforcement = MaxLengthEnforcement.none;
await setupWidget(tester, enforcement);
......@@ -7991,7 +8128,7 @@ void main() {
expect(state.currentTextEditingValue.composing, TextRange.empty);
});
testWidgets('using enforced.', (WidgetTester tester) async {
testWidgetsWithLeakTracking('using enforced.', (WidgetTester tester) async {
const MaxLengthEnforcement enforcement = MaxLengthEnforcement.enforced;
await setupWidget(tester, enforcement);
......@@ -8015,7 +8152,7 @@ void main() {
expect(state.currentTextEditingValue.composing, const TextRange(start: 3, end: 5));
});
testWidgets('using truncateAfterCompositionEnds.', (WidgetTester tester) async {
testWidgetsWithLeakTracking('using truncateAfterCompositionEnds.', (WidgetTester tester) async {
const MaxLengthEnforcement enforcement = MaxLengthEnforcement.truncateAfterCompositionEnds;
await setupWidget(tester, enforcement);
......@@ -8039,7 +8176,7 @@ void main() {
expect(state.currentTextEditingValue.composing, TextRange.empty);
});
testWidgets('using default behavior for different platforms.', (WidgetTester tester) async {
testWidgetsWithLeakTracking('using default behavior for different platforms.', (WidgetTester tester) async {
await setupWidget(tester, null);
final EditableTextState state = tester.state(find.byType(EditableText));
......@@ -8072,7 +8209,7 @@ void main() {
});
});
testWidgets('disabled widget changes background color', (WidgetTester tester) async {
testWidgetsWithLeakTracking('disabled widget changes background color', (WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: Center(
......@@ -8148,7 +8285,7 @@ void main() {
});
// Regression test for https://github.com/flutter/flutter/issues/78097.
testWidgets(
testWidgetsWithLeakTracking(
'still gets disabled background color when decoration is null',
(WidgetTester tester) async {
await tester.pumpWidget(
......@@ -8172,7 +8309,7 @@ void main() {
},
);
testWidgets('autofill info has placeholder text', (WidgetTester tester) async {
testWidgetsWithLeakTracking('autofill info has placeholder text', (WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: CupertinoTextField(
......@@ -8188,7 +8325,7 @@ void main() {
);
});
testWidgets('textDirection is passed to EditableText', (WidgetTester tester) async {
testWidgetsWithLeakTracking('textDirection is passed to EditableText', (WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: Center(
......@@ -8216,7 +8353,7 @@ void main() {
expect(rtlWidget.textDirection, TextDirection.rtl);
});
testWidgets('clipBehavior has expected defaults', (WidgetTester tester) async {
testWidgetsWithLeakTracking('clipBehavior has expected defaults', (WidgetTester tester) async {
await tester.pumpWidget(
const CupertinoApp(
home: CupertinoTextField(
......@@ -8228,7 +8365,9 @@ void main() {
expect(textField.clipBehavior, Clip.hardEdge);
});
testWidgets('Overflow clipBehavior none golden', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Overflow clipBehavior none golden', (WidgetTester tester) async {
final OverflowWidgetTextEditingController controller = OverflowWidgetTextEditingController();
addTearDown(controller.dispose);
final Widget widget = CupertinoApp(
home: RepaintBoundary(
key: const ValueKey<int>(1),
......@@ -8240,7 +8379,7 @@ void main() {
// Make sure the input field is not high enough for the WidgetSpan.
height: 50,
child: CupertinoTextField(
controller: OverflowWidgetTextEditingController(),
controller: controller,
clipBehavior: Clip.none,
),
),
......@@ -8262,10 +8401,11 @@ void main() {
);
});
testWidgets('can shift + tap to select with a keyboard (Apple platforms)', (WidgetTester tester) async {
testWidgetsWithLeakTracking('can shift + tap to select with a keyboard (Apple platforms)', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -8305,10 +8445,11 @@ void main() {
expect(controller.selection.extentOffset, 4);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('can shift + tap to select with a keyboard (non-Apple platforms)', (WidgetTester tester) async {
testWidgetsWithLeakTracking('can shift + tap to select with a keyboard (non-Apple platforms)', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -8350,11 +8491,13 @@ void main() {
expect(controller.selection.extentOffset, 4);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.linux, TargetPlatform.windows }));
testWidgets('shift tapping an unfocused field', (WidgetTester tester) async {
testWidgetsWithLeakTracking('shift tapping an unfocused field', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -8404,10 +8547,11 @@ void main() {
expect(controller.selection.extentOffset, 20);
}, variant: TargetPlatformVariant.all());
testWidgets('can shift + tap + drag to select with a keyboard (Apple platforms)', (WidgetTester tester) async {
testWidgetsWithLeakTracking('can shift + tap + drag to select with a keyboard (Apple platforms)', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS;
await tester.pumpWidget(
CupertinoApp(
......@@ -8510,10 +8654,11 @@ void main() {
expect(controller.selection.extentOffset, 26);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('can shift + tap + drag to select with a keyboard (non-Apple platforms)', (WidgetTester tester) async {
testWidgetsWithLeakTracking('can shift + tap + drag to select with a keyboard (non-Apple platforms)', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
final bool isTargetPlatformMobile = defaultTargetPlatform == TargetPlatform.android
|| defaultTargetPlatform == TargetPlatform.fuchsia;
await tester.pumpWidget(
......@@ -8617,10 +8762,11 @@ void main() {
expect(controller.selection.extentOffset, 26);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.linux, TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.windows }));
testWidgets('can shift + tap + drag to select with a keyboard, reversed (Apple platforms)', (WidgetTester tester) async {
testWidgetsWithLeakTracking('can shift + tap + drag to select with a keyboard, reversed (Apple platforms)', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
final bool isTargetPlatformIOS = defaultTargetPlatform == TargetPlatform.iOS;
await tester.pumpWidget(
CupertinoApp(
......@@ -8724,10 +8870,11 @@ void main() {
expect(controller.selection.extentOffset, 14);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('can shift + tap + drag to select with a keyboard, reversed (non-Apple platforms)', (WidgetTester tester) async {
testWidgetsWithLeakTracking('can shift + tap + drag to select with a keyboard, reversed (non-Apple platforms)', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure',
);
addTearDown(controller.dispose);
final bool isTargetPlatformMobile = defaultTargetPlatform == TargetPlatform.android
|| defaultTargetPlatform == TargetPlatform.fuchsia;
await tester.pumpWidget(
......@@ -8832,10 +8979,11 @@ void main() {
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.linux, TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.windows }));
// Regression test for https://github.com/flutter/flutter/issues/101587.
testWidgets('Right clicking menu behavior', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Right clicking menu behavior', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'blah1 blah2',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -8910,10 +9058,12 @@ void main() {
);
group('Right click focus', () {
testWidgets('Can right click to focus multiple times', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Can right click to focus multiple times', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/pull/103228
final FocusNode focusNode1 = FocusNode();
final FocusNode focusNode2 = FocusNode();
addTearDown(focusNode1.dispose);
addTearDown(focusNode2.dispose);
final UniqueKey key1 = UniqueKey();
final UniqueKey key2 = UniqueKey();
await tester.pumpWidget(
......@@ -8965,12 +9115,15 @@ void main() {
expect(focusNode2.hasFocus, isFalse);
});
testWidgets('Can right click to focus on previously selected word on Apple platforms', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Can right click to focus on previously selected word on Apple platforms', (WidgetTester tester) async {
final FocusNode focusNode1 = FocusNode();
final FocusNode focusNode2 = FocusNode();
addTearDown(focusNode1.dispose);
addTearDown(focusNode2.dispose);
final TextEditingController controller = TextEditingController(
text: 'first second',
);
addTearDown(controller.dispose);
final UniqueKey key1 = UniqueKey();
await tester.pumpWidget(
CupertinoApp(
......@@ -9065,8 +9218,9 @@ void main() {
});
group('context menu', () {
testWidgets('builds CupertinoAdaptiveTextSelectionToolbar by default', (WidgetTester tester) async {
testWidgetsWithLeakTracking('builds CupertinoAdaptiveTextSelectionToolbar by default', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(text: '');
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Column(
......@@ -9095,9 +9249,10 @@ void main() {
skip: kIsWeb, // [intended] on web the browser handles the context menu.
);
testWidgets('contextMenuBuilder is used in place of the default text selection toolbar', (WidgetTester tester) async {
testWidgetsWithLeakTracking('contextMenuBuilder is used in place of the default text selection toolbar', (WidgetTester tester) async {
final GlobalKey key = GlobalKey();
final TextEditingController controller = TextEditingController(text: '');
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Column(
......@@ -9138,7 +9293,7 @@ void main() {
final Widget fakeMagnifier = Container(key: UniqueKey());
group('magnifier builder', () {
testWidgets('should build custom magnifier if given', (WidgetTester tester) async {
testWidgetsWithLeakTracking('should build custom magnifier if given', (WidgetTester tester) async {
final Widget customMagnifier = Container(
key: UniqueKey(),
);
......@@ -9153,17 +9308,19 @@ void main() {
final BuildContext context =
tester.firstElement(find.byType(Placeholder));
final ValueNotifier<MagnifierInfo> magnifierInfo = ValueNotifier<MagnifierInfo>(MagnifierInfo.empty);
addTearDown(magnifierInfo.dispose);
expect(
defaultCupertinoTextField.magnifierConfiguration!.magnifierBuilder(
context,
MagnifierController(),
ValueNotifier<MagnifierInfo>(MagnifierInfo.empty),
magnifierInfo,
),
isA<Widget>().having((Widget widget) => widget.key, 'key', equals(customMagnifier.key)));
});
group('defaults', () {
testWidgets('should build CupertinoMagnifier on iOS and Android', (WidgetTester tester) async {
testWidgetsWithLeakTracking('should build CupertinoMagnifier on iOS and Android', (WidgetTester tester) async {
await tester.pumpWidget(const CupertinoApp(
home: CupertinoTextField(),
));
......@@ -9171,11 +9328,13 @@ void main() {
final BuildContext context = tester.firstElement(find.byType(CupertinoTextField));
final EditableText editableText = tester.widget(find.byType(EditableText));
final ValueNotifier<MagnifierInfo> magnifierInfo = ValueNotifier<MagnifierInfo>(MagnifierInfo.empty);
addTearDown(magnifierInfo.dispose);
expect(
editableText.magnifierConfiguration.magnifierBuilder(
context,
MagnifierController(),
ValueNotifier<MagnifierInfo>(MagnifierInfo.empty),
magnifierInfo,
),
isA<CupertinoTextMagnifier>());
},
......@@ -9183,7 +9342,7 @@ void main() {
<TargetPlatform>{TargetPlatform.iOS, TargetPlatform.android}));
});
testWidgets('should build nothing on all platforms but iOS and Android', (WidgetTester tester) async {
testWidgetsWithLeakTracking('should build nothing on all platforms but iOS and Android', (WidgetTester tester) async {
await tester.pumpWidget(const CupertinoApp(
home: CupertinoTextField(),
));
......@@ -9191,11 +9350,13 @@ void main() {
final BuildContext context = tester.firstElement(find.byType(CupertinoTextField));
final EditableText editableText = tester.widget(find.byType(EditableText));
final ValueNotifier<MagnifierInfo> magnifierInfo = ValueNotifier<MagnifierInfo>(MagnifierInfo.empty);
addTearDown(magnifierInfo.dispose);
expect(
editableText.magnifierConfiguration.magnifierBuilder(
context,
MagnifierController(),
ValueNotifier<MagnifierInfo>(MagnifierInfo.empty),
magnifierInfo,
),
isNull);
},
......@@ -9203,9 +9364,10 @@ void main() {
excluding: <TargetPlatform>{TargetPlatform.iOS, TargetPlatform.android}));
});
testWidgets('Can drag handles to show, unshow, and update magnifier',
testWidgetsWithLeakTracking('Can drag handles to show, unshow, and update magnifier',
(WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: CupertinoPageScaffold(
......@@ -9270,8 +9432,9 @@ void main() {
expect(find.byKey(fakeMagnifier.key!), findsNothing);
}, variant: TargetPlatformVariant.only(TargetPlatform.iOS));
testWidgets('Can drag to show, unshow, and update magnifier', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Can drag to show, unshow, and update magnifier', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -9369,8 +9532,9 @@ void main() {
expect(find.byKey(fakeMagnifier.key!), findsNothing);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.iOS }));
testWidgets('Can long press to show, unshow, and update magnifier on non-Apple platforms', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Can long press to show, unshow, and update magnifier on non-Apple platforms', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
final bool isTargetPlatformAndroid = defaultTargetPlatform == TargetPlatform.android;
await tester.pumpWidget(
CupertinoApp(
......@@ -9428,8 +9592,9 @@ void main() {
expect(find.byKey(fakeMagnifier.key!), findsNothing);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android }));
testWidgets('Can long press to show, unshow, and update magnifier on iOS', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Can long press to show, unshow, and update magnifier on iOS', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
final bool isTargetPlatformAndroid = defaultTargetPlatform == TargetPlatform.android;
await tester.pumpWidget(
CupertinoApp(
......@@ -9490,8 +9655,9 @@ void main() {
});
group('TapRegion integration', () {
testWidgets('Tapping outside loses focus on desktop', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Tapping outside loses focus on desktop', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Test Node');
addTearDown(focusNode.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -9516,8 +9682,9 @@ void main() {
expect(focusNode.hasPrimaryFocus, isFalse);
}, variant: TargetPlatformVariant.desktop());
testWidgets("Tapping outside doesn't lose focus on mobile", (WidgetTester tester) async {
testWidgetsWithLeakTracking("Tapping outside doesn't lose focus on mobile", (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Test Node');
addTearDown(focusNode.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -9543,12 +9710,14 @@ void main() {
expect(focusNode.hasPrimaryFocus, kIsWeb ? isFalse : isTrue);
}, variant: TargetPlatformVariant.mobile());
testWidgets("tapping on toolbar doesn't lose focus", (WidgetTester tester) async {
testWidgetsWithLeakTracking("tapping on toolbar doesn't lose focus", (WidgetTester tester) async {
final TextEditingController controller;
final EditableTextState state;
controller = TextEditingController(text: 'A B C');
addTearDown(controller.dispose);
final FocusNode focusNode = FocusNode(debugLabel: 'Test Node');
addTearDown(focusNode.dispose);
await tester.pumpWidget(
CupertinoApp(
debugShowCheckedModeBanner: false,
......@@ -9602,9 +9771,10 @@ void main() {
skip: kIsWeb, // [intended] The toolbar isn't rendered by Flutter on the web, it's rendered by the browser.
);
testWidgets("Tapping on border doesn't lose focus",
testWidgetsWithLeakTracking("Tapping on border doesn't lose focus",
(WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Test Node');
addTearDown(focusNode.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -9631,8 +9801,9 @@ void main() {
}, variant: TargetPlatformVariant.all());
});
testWidgets('Can drag handles to change selection correctly in multiline', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Can drag handles to change selection correctly in multiline', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
......@@ -9728,7 +9899,7 @@ void main() {
}
});
testWidgets('placeholder style overflow works', (WidgetTester tester) async {
testWidgetsWithLeakTracking('placeholder style overflow works', (WidgetTester tester) async {
final String placeholder = 'hint text' * 20;
const TextStyle placeholderStyle = TextStyle(
fontSize: 14.0,
......@@ -9752,7 +9923,7 @@ void main() {
expect(placeholderWidget.style!.overflow, placeholderStyle.overflow);
});
testWidgets('tapping on a misspelled word on iOS hides the handles and shows red selection', (WidgetTester tester) async {
testWidgetsWithLeakTracking('tapping on a misspelled word on iOS hides the handles and shows red selection', (WidgetTester tester) async {
tester.binding.platformDispatcher.nativeSpellCheckServiceDefinedTestValue =
true;
// The default derived color for the iOS text selection highlight.
......@@ -9760,6 +9931,7 @@ void main() {
final TextEditingController controller = TextEditingController(
text: 'test test testt',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -9825,10 +9997,11 @@ void main() {
skip: kIsWeb, // [intended]
);
testWidgets('text selection toolbar is hidden on tap down', (WidgetTester tester) async {
testWidgetsWithLeakTracking('text selection toolbar is hidden on tap down', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(
text: 'blah1 blah2',
);
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Center(
......@@ -9870,9 +10043,10 @@ void main() {
variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }),
);
testWidgets('Does not shrink in height when enters text when there is large single-line placeholder', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Does not shrink in height when enters text when there is large single-line placeholder', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/133241.
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Align(
......@@ -9894,8 +10068,9 @@ void main() {
expect(rectWithPlaceholder, rectWithText);
});
testWidgets('Does not match the height of a multiline placeholder', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Does not match the height of a multiline placeholder', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
addTearDown(controller.dispose);
await tester.pumpWidget(
CupertinoApp(
home: Align(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment