Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Renzo-Olivares committed Apr 30, 2024
1 parent 3d34915 commit 8db991f
Show file tree
Hide file tree
Showing 2 changed files with 246 additions and 0 deletions.
185 changes: 185 additions & 0 deletions packages/flutter/test/material/text_field_test.dart
Expand Up @@ -2506,6 +2506,191 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
);

testWidgets('Can move cursor when dragging, when tap is on collapsed selection (iOS) - PageView', (WidgetTester tester) async {
// This is a regression test for
// https://github.com/flutter/flutter/issues/142624.
final TextEditingController controller = _textEditingController();
final PageController pageController = PageController();

await tester.pumpWidget(
MaterialApp(
home: Material(
child: PageView(
controller: pageController,
children: <Widget>[
Center(
child: TextField(
dragStartBehavior: DragStartBehavior.down,
controller: controller,
),
),
const SizedBox(
height: 200.0,
child: Center(
child: Text('Page 2'),
),
),
],
),
),
),
);

const String testValue = 'abc def ghi jkl mno pqr stu vwx yz';
await tester.enterText(find.byType(TextField), testValue);
await skipPastScrollingAnimation(tester);

final Offset aPos = textOffsetToPosition(tester, testValue.indexOf('a'));
final Offset gPos = textOffsetToPosition(tester, testValue.indexOf('g'));
final Offset iPos = textOffsetToPosition(tester, testValue.indexOf('i'));

// Tap on text field to gain focus, and set selection to '|a'. On iOS
// the selection is set to the word edge closest to the tap position.
// We await for kDoubleTapTimeout after the up event, so our next down event
// does not register as a double tap.
final TestGesture gesture = await tester.startGesture(aPos);
await tester.pump();
await gesture.up();
await tester.pumpAndSettle(kDoubleTapTimeout);

expect(controller.selection.isCollapsed, true);
expect(controller.selection.baseOffset, 0);

// If the position we tap during a drag start is on the collapsed selection, then
// we can move the cursor with a drag.
// Here we tap on '|a', where our selection was previously, and attempt move
// to '|g'.
await gesture.down(aPos);
await tester.pump();
await gesture.moveTo(gPos);
await tester.pumpAndSettle();

expect(controller.selection.isCollapsed, true);
expect(controller.selection.baseOffset, testValue.indexOf('g'));

// Release the pointer.
await gesture.up();
await tester.pumpAndSettle();

// If the position we tap during a drag start is on the collapsed selection, then
// we can move the cursor with a drag.
// Here we tap on '|g', where our selection was previously, and move to '|i'.
await gesture.down(gPos);
await tester.pump();
await gesture.moveTo(iPos);
await tester.pumpAndSettle();

expect(controller.selection.isCollapsed, true);
expect(controller.selection.baseOffset, testValue.indexOf('i'));

// End gesture and skip the magnifier hide animation, so it can release
// resources.
await gesture.up();
await tester.pumpAndSettle();

expect(pageController.page, isNotNull);
expect(pageController.page, 0.0);
// A horizontal drag directly on the TextField, but not on the current
// collapsed selection should move the page view to the next page.
final Rect textFieldRect = tester.getRect(find.byType(TextField));
await tester.dragFrom(textFieldRect.centerRight - const Offset(0.1, 0.0), const Offset(-500.0, 0.0));
await tester.pumpAndSettle();
expect(controller.selection.baseOffset, testValue.indexOf('i'));
expect(pageController.page, isNotNull);
expect(pageController.page, 1.0);
},
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
);

testWidgets('Can move cursor when dragging, when tap is on collapsed selection (iOS) - TextField in Dismissible', (WidgetTester tester) async {
// This is a regression test for
// https://github.com/flutter/flutter/issues/124421.
final TextEditingController controller = _textEditingController();
bool dismissed = false;

await tester.pumpWidget(
MaterialApp(
home: Material(
child: ListView(
children: <Widget>[
Dismissible(
key: UniqueKey(),
onDismissed: (DismissDirection? direction) {
dismissed = true;
},
child: TextField(
dragStartBehavior: DragStartBehavior.down,
controller: controller,
),
),
],
),
),
),
);

const String testValue = 'abc def ghi jkl mno pqr stu vwx yz';
await tester.enterText(find.byType(TextField), testValue);
await skipPastScrollingAnimation(tester);

final Offset aPos = textOffsetToPosition(tester, testValue.indexOf('a'));
final Offset gPos = textOffsetToPosition(tester, testValue.indexOf('g'));
final Offset iPos = textOffsetToPosition(tester, testValue.indexOf('i'));

// Tap on text field to gain focus, and set selection to '|a'. On iOS
// the selection is set to the word edge closest to the tap position.
// We await for kDoubleTapTimeout after the up event, so our next down event
// does not register as a double tap.
final TestGesture gesture = await tester.startGesture(aPos);
await tester.pump();
await gesture.up();
await tester.pumpAndSettle(kDoubleTapTimeout);

expect(controller.selection.isCollapsed, true);
expect(controller.selection.baseOffset, 0);

// If the position we tap during a drag start is on the collapsed selection, then
// we can move the cursor with a drag.
// Here we tap on '|a', where our selection was previously, and attempt move
// to '|g'.
await gesture.down(aPos);
await tester.pump();
await gesture.moveTo(gPos);
await tester.pumpAndSettle();

expect(controller.selection.isCollapsed, true);
expect(controller.selection.baseOffset, testValue.indexOf('g'));

// Release the pointer.
await gesture.up();
await tester.pumpAndSettle();

// If the position we tap during a drag start is on the collapsed selection, then
// we can move the cursor with a drag.
// Here we tap on '|g', where our selection was previously, and move to '|i'.
await gesture.down(gPos);
await tester.pump();
await gesture.moveTo(iPos);
await tester.pumpAndSettle();

expect(controller.selection.isCollapsed, true);
expect(controller.selection.baseOffset, testValue.indexOf('i'));

// End gesture and skip the magnifier hide animation, so it can release
// resources.
await gesture.up();
await tester.pumpAndSettle();

expect(dismissed, false);
// A horizontal drag directly on the TextField, but not on the current
// collapsed selection should allow for the Dismissible to be dismissed.
await tester.dragFrom(tester.getRect(find.byType(TextField)).centerRight - const Offset(0.1, 0.0), const Offset(-400.0, 0.0));
await tester.pumpAndSettle();
expect(dismissed, true);
},
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
);

testWidgets('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
Expand Down
61 changes: 61 additions & 0 deletions packages/flutter/test/widgets/selectable_text_test.dart
Expand Up @@ -3395,6 +3395,67 @@ void main() {
},
);

testWidgets('PageView beats SelectableText drag gestures (iOS)', (WidgetTester tester) async {
// This is a regression test for
// https://github.com/flutter/flutter/issues/130198.
final PageController pageController = PageController();
const String testValue = 'abc def ghi jkl mno pqr stu vwx yz';

await tester.pumpWidget(
MaterialApp(
home: Material(
child: PageView(
controller: pageController,
children: const <Widget>[
Center(
child: SelectableText(testValue),
),
SizedBox(
height: 200.0,
child: Center(
child: Text('Page 2'),
),
),
],
),
),
),
);

await skipPastScrollingAnimation(tester);

final Offset gPos = textOffsetToPosition(tester, testValue.indexOf('g'));
final Offset pPos = textOffsetToPosition(tester, testValue.indexOf('p'));

// A double tap + drag should take precendence over parent drags.
final TestGesture gesture = await tester.startGesture(gPos);
await tester.pump();
await gesture.up();
await tester.pump();
await gesture.down(gPos);
await tester.pumpAndSettle();
await gesture.moveTo(pPos);
await tester.pump();
await gesture.up();
await tester.pumpAndSettle();
final TextEditingValue currentValue =
tester.state<EditableTextState>(find.byType(EditableText)).textEditingValue;
expect(currentValue.selection, TextSelection(baseOffset: testValue.indexOf('g'), extentOffset: testValue.indexOf('p') + 3));


expect(pageController.page, isNotNull);
expect(pageController.page, 0.0);
// A horizontal drag directly on the SelectableText should move the page
// view to the next page.
final Rect selectableTextRect = tester.getRect(find.byType(SelectableText));
await tester.dragFrom(selectableTextRect.centerRight - const Offset(0.1, 0.0), const Offset(-500.0, 0.0));
await tester.pumpAndSettle();
expect(pageController.page, isNotNull);
expect(pageController.page, 1.0);
},
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
);

testWidgets(
'long press tap cannot initiate a double tap',
(WidgetTester tester) async {
Expand Down

0 comments on commit 8db991f

Please sign in to comment.