mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[web] Fix and enable editable_text_test.dart (#64516)
This commit is contained in:
parent
be7c7faee6
commit
707f995de3
@ -92,7 +92,6 @@ const List<String> kWebTestFileKnownFailures = <String>[
|
||||
'test/widgets/selectable_text_test.dart',
|
||||
'test/widgets/color_filter_test.dart',
|
||||
'test/widgets/editable_text_cursor_test.dart',
|
||||
'test/widgets/editable_text_test.dart',
|
||||
'test/material/animated_icons_private_test.dart',
|
||||
'test/material/data_table_test.dart',
|
||||
'test/cupertino/nav_bar_transition_test.dart',
|
||||
|
||||
@ -1627,6 +1627,11 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
|
||||
if (!_shouldCreateInputConnection) {
|
||||
return;
|
||||
}
|
||||
if (widget.readOnly) {
|
||||
// In the read-only case, we only care about selection changes, and reject
|
||||
// everything else.
|
||||
value = _value.copyWith(selection: value.selection);
|
||||
}
|
||||
_receivedRemoteTextEditingValue = value;
|
||||
if (value.text != _value.text) {
|
||||
hideToolbar();
|
||||
|
||||
@ -300,7 +300,12 @@ void main() {
|
||||
controller.text = 'test';
|
||||
await tester.idle();
|
||||
expect(tester.testTextInput.editingState['text'], equals('test'));
|
||||
expect(tester.testTextInput.setClientArgs['inputType']['name'], equals('TextInputType.name'));
|
||||
expect(
|
||||
tester.testTextInput.setClientArgs['inputType']['name'],
|
||||
// On web, we don't infer the keyboard type as "name". We only infer
|
||||
// on iOS and macOS.
|
||||
kIsWeb ? equals('TextInputType.address') : equals('TextInputType.name'),
|
||||
);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('infer keyboard types from autofillHints: non-ios',
|
||||
@ -1106,9 +1111,10 @@ void main() {
|
||||
cause: SelectionChangedCause.tap,
|
||||
);
|
||||
await tester.pump();
|
||||
expect(state.showToolbar(), true);
|
||||
// On web, we don't let Flutter show the toolbar.
|
||||
expect(state.showToolbar(), kIsWeb ? isFalse : isTrue);
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Paste'), findsOneWidget);
|
||||
expect(find.text('Paste'), kIsWeb ? findsNothing : findsOneWidget);
|
||||
|
||||
// Hide the menu again.
|
||||
state.hideToolbar();
|
||||
@ -1118,9 +1124,10 @@ void main() {
|
||||
// Can show the menu with text and a selection.
|
||||
controller.text = 'blah';
|
||||
await tester.pump();
|
||||
expect(state.showToolbar(), true);
|
||||
// On web, we don't let Flutter show the toolbar.
|
||||
expect(state.showToolbar(), kIsWeb ? isFalse : isTrue);
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Paste'), findsOneWidget);
|
||||
expect(find.text('Paste'), kIsWeb ? findsNothing : findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('can show the toolbar after clearing all text', (WidgetTester tester) async {
|
||||
@ -1158,9 +1165,10 @@ void main() {
|
||||
await tester.pump();
|
||||
|
||||
// Should be able to show the toolbar.
|
||||
expect(state.showToolbar(), true);
|
||||
// On web, we don't let Flutter show the toolbar.
|
||||
expect(state.showToolbar(), kIsWeb ? isFalse : isTrue);
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Paste'), findsOneWidget);
|
||||
expect(find.text('Paste'), kIsWeb ? findsNothing : findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('can dynamically disable options in toolbar', (WidgetTester tester) async {
|
||||
@ -1190,10 +1198,11 @@ void main() {
|
||||
cause: SelectionChangedCause.tap,
|
||||
);
|
||||
await tester.pump();
|
||||
expect(state.showToolbar(), true);
|
||||
// On web, we don't let Flutter show the toolbar.
|
||||
expect(state.showToolbar(), kIsWeb ? isFalse : isTrue);
|
||||
await tester.pump();
|
||||
expect(find.text('Select all'), findsOneWidget);
|
||||
expect(find.text('Copy'), findsOneWidget);
|
||||
expect(find.text('Select all'), kIsWeb ? findsNothing : findsOneWidget);
|
||||
expect(find.text('Copy'), kIsWeb ? findsNothing : findsOneWidget);
|
||||
expect(find.text('Paste'), findsNothing);
|
||||
expect(find.text('Cut'), findsNothing);
|
||||
});
|
||||
@ -1220,7 +1229,8 @@ void main() {
|
||||
tester.state<EditableTextState>(find.byType(EditableText));
|
||||
await tester.tap(find.byType(EditableText));
|
||||
await tester.pump();
|
||||
expect(state.showToolbar(), true);
|
||||
// On web, we don't let Flutter show the toolbar.
|
||||
expect(state.showToolbar(), kIsWeb ? isFalse : isTrue);
|
||||
await tester.pump();
|
||||
expect(find.text('Select All'), findsNothing);
|
||||
expect(find.text('Copy'), findsNothing);
|
||||
@ -1256,10 +1266,11 @@ void main() {
|
||||
cause: SelectionChangedCause.tap,
|
||||
);
|
||||
await tester.pump();
|
||||
expect(state.showToolbar(), true);
|
||||
// On web, we don't let Flutter show the toolbar.
|
||||
expect(state.showToolbar(), kIsWeb ? isFalse : isTrue);
|
||||
await tester.pump();
|
||||
expect(find.text('Select all'), findsNothing);
|
||||
expect(find.text('Copy'), findsOneWidget);
|
||||
expect(find.text('Copy'), kIsWeb ? findsNothing : findsOneWidget);
|
||||
expect(find.text('Paste'), findsNothing);
|
||||
expect(find.text('Cut'), findsNothing);
|
||||
});
|
||||
@ -1294,10 +1305,11 @@ void main() {
|
||||
cause: SelectionChangedCause.tap,
|
||||
);
|
||||
await tester.pump();
|
||||
expect(state.showToolbar(), true);
|
||||
// On web, we don't let Flutter show the toolbar.
|
||||
expect(state.showToolbar(), kIsWeb ? isFalse : isTrue);
|
||||
await tester.pump();
|
||||
expect(find.text('Select all'), findsOneWidget);
|
||||
expect(find.text('Copy'), findsOneWidget);
|
||||
expect(find.text('Select all'), kIsWeb ? findsNothing : findsOneWidget);
|
||||
expect(find.text('Copy'), kIsWeb ? findsNothing : findsOneWidget);
|
||||
expect(find.text('Paste'), findsNothing);
|
||||
expect(find.text('Cut'), findsNothing);
|
||||
});
|
||||
@ -1308,6 +1320,7 @@ void main() {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: EditableText(
|
||||
readOnly: true,
|
||||
controller: controller,
|
||||
backgroundCursorColor: Colors.grey,
|
||||
focusNode: focusNode,
|
||||
@ -1317,21 +1330,25 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final EditableTextState state =
|
||||
tester.state<EditableTextState>(find.byType(EditableText));
|
||||
// Interact with the field to establish the input connection.
|
||||
final Offset topLeft = tester.getTopLeft(find.byType(EditableText));
|
||||
await tester.tapAt(topLeft + const Offset(0.0, 5.0));
|
||||
await tester.pump();
|
||||
|
||||
// Select the first word "Lorem".
|
||||
state.renderEditable.selectWordsInRange(
|
||||
from: Offset.zero,
|
||||
cause: SelectionChangedCause.tap,
|
||||
);
|
||||
controller.selection = const TextSelection(baseOffset: 0, extentOffset: 5);
|
||||
await tester.pump();
|
||||
|
||||
if (kIsWeb) {
|
||||
// On the web, a regular connection to the platform should've been made
|
||||
// with the `readOnly` flag set to true.
|
||||
expect(tester.testTextInput.hasAnyClients, isTrue);
|
||||
expect(tester.testTextInput.setClientArgs['readOnly'], isTrue);
|
||||
expect(tester.testTextInput.editingState['text'], equals('Lorem'));
|
||||
expect(
|
||||
tester.testTextInput.editingState['text'],
|
||||
'Lorem ipsum dolor sit amet',
|
||||
);
|
||||
expect(tester.testTextInput.editingState['selectionBase'], 0);
|
||||
expect(tester.testTextInput.editingState['selectionExtent'], 5);
|
||||
} else {
|
||||
// On non-web platforms, a read-only field doesn't need a connection with
|
||||
// the platform.
|
||||
@ -1345,6 +1362,7 @@ void main() {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: EditableText(
|
||||
readOnly: true,
|
||||
controller: controller,
|
||||
backgroundCursorColor: Colors.grey,
|
||||
focusNode: focusNode,
|
||||
@ -1354,22 +1372,29 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
final EditableTextState state =
|
||||
tester.state<EditableTextState>(find.byType(EditableText));
|
||||
|
||||
// Select something.
|
||||
state.renderEditable.selectWordsInRange(
|
||||
from: Offset.zero,
|
||||
cause: SelectionChangedCause.tap,
|
||||
);
|
||||
// Interact with the field to establish the input connection.
|
||||
final Offset topLeft = tester.getTopLeft(find.byType(EditableText));
|
||||
await tester.tapAt(topLeft + const Offset(0.0, 5.0));
|
||||
await tester.pump();
|
||||
|
||||
expect(tester.testTextInput.hasAnyClients, kIsWeb ? isTrue : isFalse);
|
||||
if (kIsWeb) {
|
||||
// On the web, the input connection exists, but text updates should be
|
||||
// ignored.
|
||||
tester.testTextInput.enterText('Foo bar');
|
||||
// No change.
|
||||
expect(controller.text, 'Lorem ipsum dolor sit amet');
|
||||
tester.testTextInput.updateEditingValue(const TextEditingValue(
|
||||
text: 'Foo bar',
|
||||
selection: TextSelection(baseOffset: 0, extentOffset: 3),
|
||||
composing: TextRange(start: 3, end: 4),
|
||||
));
|
||||
// Only selection should change.
|
||||
expect(
|
||||
controller.value,
|
||||
const TextEditingValue(
|
||||
text: 'Lorem ipsum dolor sit amet',
|
||||
selection: TextSelection(baseOffset: 0, extentOffset: 3),
|
||||
composing: TextRange.empty,
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@ -1405,7 +1430,10 @@ void main() {
|
||||
await tester.pump();
|
||||
|
||||
expect(changedValue, clipboardContent);
|
||||
});
|
||||
|
||||
// On web, we don't show the Flutter toolbar and instead rely on the browser
|
||||
// toolbar. Until we change that, this test should remain skipped.
|
||||
}, skip: kIsWeb);
|
||||
|
||||
// The variants to test in the focus handling test.
|
||||
final ValueVariant<TextInputAction> focusVariants = ValueVariant<
|
||||
@ -2271,7 +2299,8 @@ void main() {
|
||||
expect(controller.selection.extentOffset, 9);
|
||||
|
||||
semantics.dispose();
|
||||
});
|
||||
// https://github.com/flutter/flutter/issues/64507
|
||||
}, skip: kIsWeb);
|
||||
|
||||
testWidgets('can extend selection with a11y means - character', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
@ -2472,7 +2501,8 @@ void main() {
|
||||
expect(controller.selection.extentOffset, 9);
|
||||
|
||||
semantics.dispose();
|
||||
});
|
||||
// https://github.com/flutter/flutter/issues/64507
|
||||
}, skip: kIsWeb);
|
||||
|
||||
testWidgets('password fields have correct semantics', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
@ -3466,7 +3496,10 @@ void main() {
|
||||
// at all. Again, both handles should be invisible.
|
||||
scrollable.controller.jumpTo(0);
|
||||
await verifyVisibility(HandlePositionInViewport.rightEdge, false, HandlePositionInViewport.rightEdge, false);
|
||||
});
|
||||
|
||||
// On web, we don't show the Flutter toolbar and instead rely on the browser
|
||||
// toolbar. Until we change that, this test should remain skipped.
|
||||
}, skip: kIsWeb);
|
||||
|
||||
testWidgets('text selection handle visibility RTL', (WidgetTester tester) async {
|
||||
// Text with two separate words to select.
|
||||
@ -3525,7 +3558,10 @@ void main() {
|
||||
expect(state.selectionOverlay.handlesAreVisible, isTrue);
|
||||
expect(controller.selection.base.offset, 0);
|
||||
expect(controller.selection.extent.offset, 5);
|
||||
});
|
||||
|
||||
// On web, we don't show the Flutter toolbar and instead rely on the browser
|
||||
// toolbar. Until we change that, this test should remain skipped.
|
||||
}, skip: kIsWeb);
|
||||
|
||||
const String testText = 'Now is the time for\n'
|
||||
'all good people\n'
|
||||
@ -4121,19 +4157,23 @@ void main() {
|
||||
|
||||
testWidgets('keyboard text selection works as expected on linux', (WidgetTester tester) async {
|
||||
await testTextEditing(tester, platform: 'linux');
|
||||
});
|
||||
// On web, using keyboard for selection is handled by the browser.
|
||||
}, skip: kIsWeb);
|
||||
|
||||
testWidgets('keyboard text selection works as expected on android', (WidgetTester tester) async {
|
||||
await testTextEditing(tester, platform: 'android');
|
||||
});
|
||||
// On web, using keyboard for selection is handled by the browser.
|
||||
}, skip: kIsWeb);
|
||||
|
||||
testWidgets('keyboard text selection works as expected on fuchsia', (WidgetTester tester) async {
|
||||
await testTextEditing(tester, platform: 'fuchsia');
|
||||
});
|
||||
// On web, using keyboard for selection is handled by the browser.
|
||||
}, skip: kIsWeb);
|
||||
|
||||
testWidgets('keyboard text selection works as expected on macos', (WidgetTester tester) async {
|
||||
await testTextEditing(tester, platform: 'macos');
|
||||
});
|
||||
// On web, using keyboard for selection is handled by the browser.
|
||||
}, skip: kIsWeb);
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/31287
|
||||
testWidgets('text selection handle visibility', (WidgetTester tester) async {
|
||||
@ -4301,7 +4341,10 @@ void main() {
|
||||
// at all. Again, both handles should be invisible.
|
||||
scrollable.controller.jumpTo(0);
|
||||
await verifyVisibility(HandlePositionInViewport.rightEdge, false, HandlePositionInViewport.rightEdge, false);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
// On web, we don't show the Flutter toolbar and instead rely on the browser
|
||||
// toolbar. Until we change that, this test should remain skipped.
|
||||
}, skip: kIsWeb, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets("scrolling doesn't bounce", (WidgetTester tester) async {
|
||||
// 3 lines of text, where the last line overflows and requires scrolling.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user