[web] text_editing_test.dart nnbd; bump test dep (flutter/engine#26709)

This commit is contained in:
Yegor 2021-06-11 12:31:51 -07:00 committed by GitHub
parent 11ff18234d
commit 7a60f2fb7f
4 changed files with 139 additions and 135 deletions

View File

@ -10,8 +10,6 @@ import 'package:pedantic/pedantic.dart';
import 'package:stack_trace/stack_trace.dart';
import 'package:typed_data/typed_buffers.dart';
import 'package:test_api/src/utils.dart' show getErrorMessage;
/// An interface for running browser instances.
///
/// This is intentionally coarse-grained: browsers are controlled primary from
@ -123,8 +121,9 @@ abstract class Browser {
return;
}
_onExitCompleter.completeError(
Exception('Failed to run $name: ${getErrorMessage(error)}.'),
stackTrace);
Exception('Failed to run $name: $error.'),
stackTrace,
);
});
}

View File

@ -16,7 +16,7 @@ dev_dependencies:
image: 3.0.1
path: 1.8.0
quiver: 3.0.0
test: 1.16.6
test: 1.17.7
yaml: 3.0.0
watcher: 1.0.0
web_test_utils:

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.9
import 'dart:async';
import 'dart:html';
import 'dart:js_util' as js_util;
@ -23,9 +22,9 @@ const MethodCodec codec = JSONMethodCodec();
/// Add unit tests for [FirefoxTextEditingStrategy].
/// TODO(nurhan): https://github.com/flutter/flutter/issues/46891
DefaultTextEditingStrategy editingStrategy;
EditingState lastEditingState;
String lastInputAction;
DefaultTextEditingStrategy? editingStrategy;
EditingState? lastEditingState;
String? lastInputAction;
final InputConfiguration singlelineConfig = InputConfiguration(
inputType: EngineInputType.text,
@ -40,11 +39,11 @@ final InputConfiguration multilineConfig = InputConfiguration(
final Map<String, dynamic> flutterMultilineConfig =
createFlutterConfig('multiline');
void trackEditingState(EditingState editingState) {
void trackEditingState(EditingState? editingState) {
lastEditingState = editingState;
}
void trackInputAction(String inputAction) {
void trackInputAction(String? inputAction) {
lastInputAction = inputAction;
}
@ -62,7 +61,7 @@ void testMain() {
});
group('$GloballyPositionedTextEditingStrategy', () {
HybridTextEditing testTextEditing;
late HybridTextEditing testTextEditing;
setUp(() {
testTextEditing = HybridTextEditing();
@ -82,7 +81,7 @@ void testMain() {
expect(document.activeElement, document.body);
expect(defaultTextEditingRoot.activeElement, null);
editingStrategy.enable(
editingStrategy!.enable(
singlelineConfig,
onChange: trackEditingState,
onAction: trackInputAction,
@ -92,19 +91,19 @@ void testMain() {
defaultTextEditingRoot.querySelectorAll('input'),
hasLength(1),
);
final InputElement input = defaultTextEditingRoot.querySelector('input');
final Element input = defaultTextEditingRoot.querySelector('input')!;
// Now the editing element should have focus.
expect(document.activeElement, domRenderer.glassPaneElement);
expect(defaultTextEditingRoot.activeElement, input);
expect(editingStrategy.domElement, input);
expect(editingStrategy!.domElement, input);
expect(input.getAttribute('type'), null);
// Input is appended to the right point of the DOM.
expect(defaultTextEditingRoot.contains(editingStrategy.domElement), isTrue);
expect(defaultTextEditingRoot.contains(editingStrategy!.domElement), isTrue);
editingStrategy.disable();
editingStrategy!.disable();
expect(
defaultTextEditingRoot.querySelectorAll('input'),
hasLength(0),
@ -118,78 +117,78 @@ void testMain() {
final InputConfiguration config = InputConfiguration(
readOnly: true,
);
editingStrategy.enable(
editingStrategy!.enable(
config,
onChange: trackEditingState,
onAction: trackInputAction,
);
expect(defaultTextEditingRoot.querySelectorAll('input'), hasLength(1));
final InputElement input = defaultTextEditingRoot.querySelector('input');
expect(editingStrategy.domElement, input);
final Element input = defaultTextEditingRoot.querySelector('input')!;
expect(editingStrategy!.domElement, input);
expect(input.getAttribute('readonly'), 'readonly');
editingStrategy.disable();
editingStrategy!.disable();
});
test('Knows how to create password fields', () {
final InputConfiguration config = InputConfiguration(
obscureText: true,
);
editingStrategy.enable(
editingStrategy!.enable(
config,
onChange: trackEditingState,
onAction: trackInputAction,
);
expect(defaultTextEditingRoot.querySelectorAll('input'), hasLength(1));
final InputElement input = defaultTextEditingRoot.querySelector('input');
expect(editingStrategy.domElement, input);
final Element input = defaultTextEditingRoot.querySelector('input')!;
expect(editingStrategy!.domElement, input);
expect(input.getAttribute('type'), 'password');
editingStrategy.disable();
editingStrategy!.disable();
});
test('Knows to turn autocorrect off', () {
final InputConfiguration config = InputConfiguration(
autocorrect: false,
);
editingStrategy.enable(
editingStrategy!.enable(
config,
onChange: trackEditingState,
onAction: trackInputAction,
);
expect(defaultTextEditingRoot.querySelectorAll('input'), hasLength(1));
final InputElement input = defaultTextEditingRoot.querySelector('input');
expect(editingStrategy.domElement, input);
final Element input = defaultTextEditingRoot.querySelector('input')!;
expect(editingStrategy!.domElement, input);
expect(input.getAttribute('autocorrect'), 'off');
editingStrategy.disable();
editingStrategy!.disable();
});
test('Knows to turn autocorrect on', () {
final InputConfiguration config = InputConfiguration(
autocorrect: true,
);
editingStrategy.enable(
editingStrategy!.enable(
config,
onChange: trackEditingState,
onAction: trackInputAction,
);
expect(defaultTextEditingRoot.querySelectorAll('input'), hasLength(1));
final InputElement input = defaultTextEditingRoot.querySelector('input');
expect(editingStrategy.domElement, input);
final Element input = defaultTextEditingRoot.querySelector('input')!;
expect(editingStrategy!.domElement, input);
expect(input.getAttribute('autocorrect'), 'on');
editingStrategy.disable();
editingStrategy!.disable();
});
test('Can read editing state correctly', () {
editingStrategy.enable(
editingStrategy!.enable(
singlelineConfig,
onChange: trackEditingState,
onAction: trackInputAction,
);
final InputElement input = editingStrategy.domElement;
final InputElement input = editingStrategy!.domElement as InputElement;
input.value = 'foo bar';
input.dispatchEvent(Event.eventType('Event', 'input'));
expect(
@ -209,15 +208,15 @@ void testMain() {
});
test('Can set editing state correctly', () {
editingStrategy.enable(
editingStrategy!.enable(
singlelineConfig,
onChange: trackEditingState,
onAction: trackInputAction,
);
editingStrategy.setEditingState(
editingStrategy!.setEditingState(
EditingState(text: 'foo bar baz', baseOffset: 2, extentOffset: 7));
checkInputEditingState(editingStrategy.domElement, 'foo bar baz', 2, 7);
checkInputEditingState(editingStrategy!.domElement!, 'foo bar baz', 2, 7);
// There should be no input action.
expect(lastInputAction, isNull);
@ -226,7 +225,7 @@ void testMain() {
test('Multi-line mode also works', () {
// The textarea element is created lazily.
expect(document.getElementsByTagName('textarea'), hasLength(0));
editingStrategy.enable(
editingStrategy!.enable(
multilineConfig,
onChange: trackEditingState,
onAction: trackInputAction,
@ -234,10 +233,10 @@ void testMain() {
expect(defaultTextEditingRoot.querySelectorAll('textarea'), hasLength(1));
final TextAreaElement textarea =
defaultTextEditingRoot.querySelector('textarea');
defaultTextEditingRoot.querySelector('textarea') as TextAreaElement;
// Now the textarea should have focus.
expect(defaultTextEditingRoot.activeElement, textarea);
expect(editingStrategy.domElement, textarea);
expect(editingStrategy!.domElement, textarea);
textarea.value = 'foo\nbar';
textarea.dispatchEvent(Event.eventType('Event', 'input'));
@ -250,11 +249,11 @@ void testMain() {
);
// Can set textarea state correctly (and preserves new lines).
editingStrategy.setEditingState(
editingStrategy!.setEditingState(
EditingState(text: 'bar\nbaz', baseOffset: 2, extentOffset: 7));
checkTextAreaEditingState(textarea, 'bar\nbaz', 2, 7);
editingStrategy.disable();
editingStrategy!.disable();
// The textarea should be cleaned up.
expect(defaultTextEditingRoot.querySelectorAll('textarea'), hasLength(0));
// The focus is back to the body.
@ -270,7 +269,7 @@ void testMain() {
expect(document.getElementsByTagName('textarea'), hasLength(0));
// Use single-line config and expect an `<input>` to be created.
editingStrategy.enable(
editingStrategy!.enable(
singlelineConfig,
onChange: trackEditingState,
onAction: trackInputAction,
@ -279,12 +278,12 @@ void testMain() {
expect(defaultTextEditingRoot.querySelectorAll('textarea'), hasLength(0));
// Disable and check that all DOM elements were removed.
editingStrategy.disable();
editingStrategy!.disable();
expect(defaultTextEditingRoot.querySelectorAll('input'), hasLength(0));
expect(defaultTextEditingRoot.querySelectorAll('textarea'), hasLength(0));
// Use multi-line config and expect an `<textarea>` to be created.
editingStrategy.enable(
editingStrategy!.enable(
multilineConfig,
onChange: trackEditingState,
onAction: trackInputAction,
@ -293,7 +292,7 @@ void testMain() {
expect(defaultTextEditingRoot.querySelectorAll('textarea'), hasLength(1));
// Disable again and check that all DOM elements were removed.
editingStrategy.disable();
editingStrategy!.disable();
expect(defaultTextEditingRoot.querySelectorAll('input'), hasLength(0));
expect(defaultTextEditingRoot.querySelectorAll('textarea'), hasLength(0));
@ -305,7 +304,7 @@ void testMain() {
final InputConfiguration config = InputConfiguration(
inputAction: 'TextInputAction.done',
);
editingStrategy.enable(
editingStrategy!.enable(
config,
onChange: trackEditingState,
onAction: trackInputAction,
@ -315,7 +314,7 @@ void testMain() {
expect(lastInputAction, isNull);
dispatchKeyboardEvent(
editingStrategy.domElement,
editingStrategy!.domElement!,
'keydown',
keyCode: _kReturnKeyCode,
);
@ -329,7 +328,7 @@ void testMain() {
inputType: EngineInputType.multiline,
inputAction: 'TextInputAction.done',
);
editingStrategy.enable(
editingStrategy!.enable(
config,
onChange: trackEditingState,
onAction: trackInputAction,
@ -339,7 +338,7 @@ void testMain() {
expect(lastInputAction, isNull);
final KeyboardEvent event = dispatchKeyboardEvent(
editingStrategy.domElement,
editingStrategy!.domElement!,
'keydown',
keyCode: _kReturnKeyCode,
);
@ -351,17 +350,17 @@ void testMain() {
});
test('globally positions and sizes its DOM element', () {
editingStrategy.enable(
editingStrategy!.enable(
singlelineConfig,
onChange: trackEditingState,
onAction: trackInputAction,
);
expect(editingStrategy.isEnabled, isTrue);
expect(editingStrategy!.isEnabled, isTrue);
// No geometry should be set until setEditableSizeAndTransform is called.
expect(editingStrategy.domElement.style.transform, '');
expect(editingStrategy.domElement.style.width, '');
expect(editingStrategy.domElement.style.height, '');
expect(editingStrategy!.domElement!.style.transform, '');
expect(editingStrategy!.domElement!.style.width, '');
expect(editingStrategy!.domElement!.style.height, '');
testTextEditing.acceptCommand(TextInputSetEditableSizeAndTransform(geometry: EditableTextGeometry(
width: 13,
@ -370,30 +369,33 @@ void testMain() {
)), () {});
// setEditableSizeAndTransform calls placeElement, so expecting geometry to be applied.
expect(editingStrategy.domElement.style.transform,
expect(editingStrategy!.domElement!.style.transform,
'matrix(1, 0, 0, 1, 14, 15)');
expect(editingStrategy.domElement.style.width, '13px');
expect(editingStrategy.domElement.style.height, '12px');
expect(editingStrategy!.domElement!.style.width, '13px');
expect(editingStrategy!.domElement!.style.height, '12px');
});
});
group('$HybridTextEditing', () {
HybridTextEditing textEditing;
HybridTextEditing? textEditing;
final PlatformMessagesSpy spy = PlatformMessagesSpy();
int clientId = 0;
/// Emulates sending of a message by the framework to the engine.
void sendFrameworkMessage(dynamic message) {
textEditing.channel.handleTextInput(message, (ByteData data) {});
textEditing!.channel.handleTextInput(message, (ByteData? data) {});
}
/// Sends the necessary platform messages to activate a text field and show
/// the keyboard.
///
/// Returns the `clientId` used in the platform message.
int showKeyboard(
{String inputType, String inputAction, bool decimal = false}) {
int showKeyboard({
required String inputType,
String? inputAction,
bool decimal = false,
}) {
final MethodCall setClient = MethodCall(
'TextInput.setClient',
<dynamic>[
@ -419,7 +421,7 @@ void testMain() {
}
String getEditingInputMode() {
return textEditing.strategy.domElement.getAttribute('inputmode');
return textEditing!.strategy.domElement!.getAttribute('inputmode')!;
}
setUp(() {
@ -429,8 +431,8 @@ void testMain() {
tearDown(() {
spy.tearDown();
if (textEditing.isEditing) {
textEditing.stopEditing();
if (textEditing!.isEditing) {
textEditing!.stopEditing();
}
textEditing = null;
});
@ -453,7 +455,7 @@ void testMain() {
const MethodCall show = MethodCall('TextInput.show');
sendFrameworkMessage(codec.encodeMethodCall(show));
checkInputEditingState(textEditing.strategy.domElement, '', 0, 0);
checkInputEditingState(textEditing!.strategy.domElement, '', 0, 0);
const MethodCall setEditingState =
MethodCall('TextInput.setEditingState', <String, dynamic>{
@ -464,7 +466,7 @@ void testMain() {
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
checkInputEditingState(
textEditing.strategy.domElement, 'abcd', 2, 3);
textEditing!.strategy.domElement, 'abcd', 2, 3);
const MethodCall hide = MethodCall('TextInput.hide');
sendFrameworkMessage(codec.encodeMethodCall(hide));
@ -496,7 +498,7 @@ void testMain() {
sendFrameworkMessage(codec.encodeMethodCall(show));
checkInputEditingState(
textEditing.strategy.domElement, 'abcd', 2, 3);
textEditing!.strategy.domElement, 'abcd', 2, 3);
const MethodCall clearClient = MethodCall('TextInput.clearClient');
sendFrameworkMessage(codec.encodeMethodCall(clearClient));
@ -527,7 +529,7 @@ void testMain() {
const MethodCall show = MethodCall('TextInput.show');
sendFrameworkMessage(codec.encodeMethodCall(show));
final HtmlElement element = textEditing.strategy.domElement;
final Element element = textEditing!.strategy.domElement!;
expect(element.getAttribute('readonly'), 'readonly');
// Update the read-only config.
@ -569,11 +571,11 @@ void testMain() {
sendFrameworkMessage(codec.encodeMethodCall(show));
checkInputEditingState(
textEditing.strategy.domElement, 'abcd', 2, 3);
expect(textEditing.isEditing, isTrue);
textEditing!.strategy.domElement, 'abcd', 2, 3);
expect(textEditing!.isEditing, isTrue);
// DOM element is blurred.
textEditing.strategy.domElement.blur();
textEditing!.strategy.domElement!.blur();
// For ios-safari the connection is closed.
if (browserEngine == BrowserEngine.webkit &&
@ -591,7 +593,7 @@ void testMain() {
await Future<void>.delayed(Duration.zero);
// DOM element still keeps the focus.
expect(defaultTextEditingRoot.activeElement,
textEditing.strategy.domElement);
textEditing!.strategy.domElement);
}
},
// TODO(nurhan): https://github.com/flutter/flutter/issues/50769
@ -618,7 +620,7 @@ void testMain() {
sendFrameworkMessage(codec.encodeMethodCall(show));
checkInputEditingState(
textEditing.strategy.domElement, 'abcd', 2, 3);
textEditing!.strategy.domElement, 'abcd', 2, 3);
const MethodCall finishAutofillContext =
MethodCall('TextInput.finishAutofillContext', false);
@ -733,7 +735,7 @@ void testMain() {
// Form is added to DOM.
expect(defaultTextEditingRoot.querySelectorAll('form'), isNotEmpty);
FormElement formElement = defaultTextEditingRoot.querySelector('form');
FormElement formElement = defaultTextEditingRoot.querySelector('form') as FormElement;
final Completer<bool> submittedForm = Completer<bool>();
formElement.addEventListener(
'submit', (event) => submittedForm.complete(true));
@ -786,7 +788,7 @@ void testMain() {
// Form is added to DOM.
expect(defaultTextEditingRoot.querySelectorAll('form'), isNotEmpty);
FormElement formElement = defaultTextEditingRoot.querySelector('form');
FormElement formElement = defaultTextEditingRoot.querySelector('form') as FormElement;
final Completer<bool> submittedForm = Completer<bool>();
formElement.addEventListener(
'submit', (event) => submittedForm.complete(true));
@ -830,7 +832,7 @@ void testMain() {
sendFrameworkMessage(codec.encodeMethodCall(show));
checkInputEditingState(
textEditing.strategy.domElement, 'abcd', 2, 3);
textEditing!.strategy.domElement, 'abcd', 2, 3);
final MethodCall setClient2 = MethodCall(
'TextInput.setClient', <dynamic>[567, flutterSinglelineConfig]);
@ -872,7 +874,7 @@ void testMain() {
// The second [setEditingState] should override the first one.
checkInputEditingState(
textEditing.strategy.domElement, 'xyz', 0, 2);
textEditing!.strategy.domElement, 'xyz', 0, 2);
const MethodCall clearClient = MethodCall('TextInput.clearClient');
sendFrameworkMessage(codec.encodeMethodCall(clearClient));
@ -909,9 +911,9 @@ void testMain() {
// The second [setEditingState] should override the first one.
checkInputEditingState(
textEditing.strategy.domElement, 'abcd', 2, 3);
textEditing!.strategy.domElement, 'abcd', 2, 3);
final FormElement formElement = defaultTextEditingRoot.querySelector('form');
final FormElement formElement = defaultTextEditingRoot.querySelector('form') as FormElement;
// The form has one input element and one submit button.
expect(formElement.childNodes, hasLength(2));
@ -947,7 +949,7 @@ void testMain() {
sendFrameworkMessage(codec.encodeMethodCall(show));
final InputElement inputElement =
textEditing.strategy.domElement as InputElement;
textEditing!.strategy.domElement as InputElement;
expect(inputElement.value, 'abcd');
if (!(browserEngine == BrowserEngine.webkit &&
operatingSystem == OperatingSystem.macOs)) {
@ -968,11 +970,11 @@ void testMain() {
// Check the element still has focus. User can keep editing.
expect(defaultTextEditingRoot.activeElement,
textEditing.strategy.domElement);
textEditing!.strategy.domElement);
// Check the cursor location is the same.
checkInputEditingState(
textEditing.strategy.domElement, 'abcd', 2, 3);
textEditing!.strategy.domElement, 'abcd', 2, 3);
const MethodCall clearClient = MethodCall('TextInput.clearClient');
sendFrameworkMessage(codec.encodeMethodCall(clearClient));
@ -1019,9 +1021,9 @@ void testMain() {
// The second [setEditingState] should override the first one.
checkInputEditingState(
textEditing.strategy.domElement, 'abcd', 2, 3);
textEditing!.strategy.domElement, 'abcd', 2, 3);
final FormElement formElement = defaultTextEditingRoot.querySelector('form');
final FormElement formElement = defaultTextEditingRoot.querySelector('form') as FormElement;
// The form has 4 input elements and one submit button.
expect(formElement.childNodes, hasLength(5));
@ -1061,12 +1063,12 @@ void testMain() {
if (browserEngine == BrowserEngine.webkit &&
operatingSystem == OperatingSystem.iOs) {
expect(
textEditing.strategy.domElement
textEditing!.strategy.domElement!
.getAttribute('autocapitalize'),
'off');
} else {
expect(
textEditing.strategy.domElement
textEditing!.strategy.domElement!
.getAttribute('autocapitalize'),
isNull);
}
@ -1100,7 +1102,7 @@ void testMain() {
if (browserEngine == BrowserEngine.webkit &&
operatingSystem == OperatingSystem.iOs) {
expect(
textEditing.strategy.domElement
textEditing!.strategy.domElement!
.getAttribute('autocapitalize'),
'characters');
}
@ -1136,7 +1138,7 @@ void testMain() {
const MethodCall show = MethodCall('TextInput.show');
sendFrameworkMessage(codec.encodeMethodCall(show));
final HtmlElement domElement = textEditing.strategy.domElement;
final Element domElement = textEditing!.strategy.domElement!;
checkInputEditingState(domElement, 'abcd', 2, 3);
@ -1147,7 +1149,7 @@ void testMain() {
const Point<double>(160.0, 70.0)));
expect(domElement.style.transform,
'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 10, 20, 30, 1)');
expect(textEditing.strategy.domElement.style.font,
expect(textEditing!.strategy.domElement!.style.font,
'500 12px sans-serif');
const MethodCall clearClient = MethodCall('TextInput.clearClient');
@ -1192,7 +1194,7 @@ void testMain() {
});
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
final HtmlElement domElement = textEditing.strategy.domElement;
final HtmlElement domElement = textEditing!.strategy.domElement!;
checkInputEditingState(domElement, 'abcd', 2, 3);
@ -1207,7 +1209,7 @@ void testMain() {
'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 10, 20, 30, 1)',
);
expect(
textEditing.strategy.domElement.style.font,
textEditing!.strategy.domElement!.style.font,
'500 12px sans-serif',
);
@ -1215,11 +1217,11 @@ void testMain() {
if (browserEngine == BrowserEngine.blink ||
browserEngine == BrowserEngine.samsung ||
browserEngine == BrowserEngine.webkit) {
expect(textEditing.strategy.domElement.classes,
expect(textEditing!.strategy.domElement!.classes,
contains('transparentTextEditing'));
} else {
expect(
textEditing.strategy.domElement.classes.any(
textEditing!.strategy.domElement!.classes.any(
(element) => element.toString() == 'transparentTextEditing'),
isFalse);
}
@ -1255,7 +1257,7 @@ void testMain() {
const MethodCall show = MethodCall('TextInput.show');
sendFrameworkMessage(codec.encodeMethodCall(show));
final HtmlElement domElement = textEditing.strategy.domElement;
final HtmlElement domElement = textEditing!.strategy.domElement!;
checkInputEditingState(domElement, 'abcd', 2, 3);
@ -1267,7 +1269,7 @@ void testMain() {
expect(domElement.style.transform,
'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 10, 20, 30, 1)');
expect(
textEditing.strategy.domElement.style.font, '12px sans-serif');
textEditing!.strategy.domElement!.style.font, '12px sans-serif');
hideKeyboard();
},
@ -1275,9 +1277,9 @@ void testMain() {
skip: browserEngine == BrowserEngine.webkit);
test('Canonicalizes font family', () {
showKeyboard();
showKeyboard(inputType: 'text');
final HtmlElement input = textEditing.strategy.domElement;
final HtmlElement input = textEditing!.strategy.domElement!;
MethodCall setStyle;
@ -1316,7 +1318,7 @@ void testMain() {
// Check if the selection range is correct.
checkInputEditingState(
textEditing.strategy.domElement, 'xyz', 1, 2);
textEditing!.strategy.domElement, 'xyz', 1, 2);
const MethodCall setEditingState2 =
MethodCall('TextInput.setEditingState', <String, dynamic>{
@ -1328,7 +1330,7 @@ void testMain() {
// The negative offset values are applied to the dom element as 0.
checkInputEditingState(
textEditing.strategy.domElement, 'xyz', 0, 0);
textEditing!.strategy.domElement, 'xyz', 0, 0);
hideKeyboard();
});
@ -1349,7 +1351,7 @@ void testMain() {
const MethodCall show = MethodCall('TextInput.show');
sendFrameworkMessage(codec.encodeMethodCall(show));
final InputElement input = textEditing.strategy.domElement;
final InputElement input = textEditing!.strategy.domElement as InputElement;
input.value = 'something';
input.dispatchEvent(Event.eventType('Event', 'input'));
@ -1373,7 +1375,7 @@ void testMain() {
input.setSelectionRange(2, 5);
if (browserEngine == BrowserEngine.firefox) {
Event keyup = KeyboardEvent('keyup');
textEditing.strategy.domElement.dispatchEvent(keyup);
textEditing!.strategy.domElement!.dispatchEvent(keyup);
} else {
document.dispatchEvent(Event.eventType('Event', 'selectionchange'));
}
@ -1431,14 +1433,14 @@ void testMain() {
// The second [setEditingState] should override the first one.
checkInputEditingState(
textEditing.strategy.domElement, 'abcd', 2, 3);
textEditing!.strategy.domElement, 'abcd', 2, 3);
final FormElement formElement = defaultTextEditingRoot.querySelector('form');
final FormElement formElement = defaultTextEditingRoot.querySelector('form') as FormElement;
// The form has 4 input elements and one submit button.
expect(formElement.childNodes, hasLength(5));
// Autofill one of the form elements.
InputElement element = formElement.childNodes.first;
InputElement element = formElement.childNodes.first as InputElement;
if (browserEngine == BrowserEngine.firefox) {
expect(element.name,
BrowserAutofillHints.instance.flutterToEngine(hintForFirstElement));
@ -1482,7 +1484,7 @@ void testMain() {
const MethodCall show = MethodCall('TextInput.show');
sendFrameworkMessage(codec.encodeMethodCall(show));
final TextAreaElement textarea = textEditing.strategy.domElement;
final TextAreaElement textarea = textEditing!.strategy.domElement as TextAreaElement;
checkTextAreaEditingState(textarea, '', 0, 0);
// Can set editing state and preserve new lines.
@ -1500,7 +1502,7 @@ void testMain() {
textarea.dispatchEvent(Event.eventType('Event', 'input'));
textarea.setSelectionRange(2, 5);
if (browserEngine == BrowserEngine.firefox) {
textEditing.strategy.domElement
textEditing!.strategy.domElement!
.dispatchEvent(KeyboardEvent('keyup'));
} else {
document.dispatchEvent(Event.eventType('Event', 'selectionchange'));
@ -1624,7 +1626,7 @@ void testMain() {
expect(lastInputAction, isNull);
dispatchKeyboardEvent(
textEditing.strategy.domElement,
textEditing!.strategy.domElement!,
'keydown',
keyCode: _kReturnKeyCode,
);
@ -1647,7 +1649,7 @@ void testMain() {
);
final KeyboardEvent event = dispatchKeyboardEvent(
textEditing.strategy.domElement,
textEditing!.strategy.domElement!,
'keydown',
keyCode: _kReturnKeyCode,
);
@ -1670,7 +1672,7 @@ void testMain() {
['field1', 'field2', 'field3']);
final EngineAutofillForm autofillForm =
EngineAutofillForm.fromFrameworkMessage(
createAutofillInfo('username', 'field1'), fields);
createAutofillInfo('username', 'field1'), fields)!;
// Number of elements if number of fields sent to the constructor minus
// one (for the focused text element).
@ -1685,7 +1687,7 @@ void testMain() {
// 3 child nodes.
expect(form.childNodes, hasLength(3));
final InputElement firstElement = form.childNodes.first;
final InputElement firstElement = form.childNodes.first as InputElement;
// Autofill value is applied to the element.
expect(firstElement.name,
BrowserAutofillHints.instance.flutterToEngine('password'));
@ -1729,7 +1731,7 @@ void testMain() {
['zzyyxx', 'aabbcc', 'jjkkll']);
final EngineAutofillForm autofillForm =
EngineAutofillForm.fromFrameworkMessage(
createAutofillInfo('username', 'field1'), fields);
createAutofillInfo('username', 'field1'), fields)!;
expect(autofillForm.formIdentifier, 'aabbcc*jjkkll*zzyyxx');
});
@ -1742,7 +1744,7 @@ void testMain() {
['field1', 'fields2', 'field3']);
final EngineAutofillForm autofillForm =
EngineAutofillForm.fromFrameworkMessage(
createAutofillInfo('username', 'field1'), fields);
createAutofillInfo('username', 'field1'), fields)!;
final InputElement testInputElement = InputElement();
autofillForm.placeForm(testInputElement);
@ -1752,7 +1754,7 @@ void testMain() {
final FormElement form = autofillForm.formElement;
expect(form.childNodes, hasLength(4));
final FormElement formOnDom = defaultTextEditingRoot.querySelector('form');
final FormElement formOnDom = defaultTextEditingRoot.querySelector('form') as FormElement;
// Form is attached to the DOM.
expect(form, equals(formOnDom));
@ -1765,7 +1767,7 @@ void testMain() {
final List<dynamic> fields = createFieldValues(['username'], ['field1']);
final EngineAutofillForm autofillForm =
EngineAutofillForm.fromFrameworkMessage(
createAutofillInfo('username', 'field1'), fields);
createAutofillInfo('username', 'field1'), fields)!;
// The focused element is the only field. Form should be empty after
// the initialization (focus element is appended later).
@ -1776,7 +1778,7 @@ void testMain() {
final FormElement form = autofillForm.formElement;
// Submit button is added to the form.
expect(form.childNodes, isNotEmpty);
final InputElement inputElement = form.childNodes.first;
final InputElement inputElement = form.childNodes.first as InputElement;
expect(inputElement.type, 'submit');
// The submit button should have class `submitBtn`.
@ -1785,7 +1787,7 @@ void testMain() {
test('Return null if no focused element', () {
final List<dynamic> fields = createFieldValues(['username'], ['field1']);
final EngineAutofillForm autofillForm =
final EngineAutofillForm? autofillForm =
EngineAutofillForm.fromFrameworkMessage(null, fields);
expect(autofillForm, isNull);
@ -1877,7 +1879,7 @@ void testMain() {
setUp(() {
editingStrategy =
GloballyPositionedTextEditingStrategy(HybridTextEditing());
editingStrategy.enable(
editingStrategy!.enable(
singlelineConfig,
onChange: trackEditingState,
onAction: trackInputAction,
@ -1903,7 +1905,7 @@ void testMain() {
});
test('Configure input element from the editing state', () {
final InputElement input = defaultTextEditingRoot.querySelector('input');
final InputElement input = defaultTextEditingRoot.querySelector('input') as InputElement;
_editingState =
EditingState(text: 'Test', baseOffset: 1, extentOffset: 2);
@ -1916,14 +1918,14 @@ void testMain() {
test('Configure text area element from the editing state', () {
cleanTextEditingStrategy();
editingStrategy.enable(
editingStrategy!.enable(
multilineConfig,
onChange: trackEditingState,
onAction: trackInputAction,
);
final TextAreaElement textArea =
defaultTextEditingRoot.querySelector('textarea');
defaultTextEditingRoot.querySelector('textarea') as TextAreaElement;
_editingState =
EditingState(text: 'Test', baseOffset: 1, extentOffset: 2);
@ -1935,7 +1937,7 @@ void testMain() {
});
test('Get Editing State from input element', () {
final InputElement input = defaultTextEditingRoot.querySelector('input');
final InputElement input = defaultTextEditingRoot.querySelector('input') as InputElement;
input.value = 'Test';
input.selectionStart = 1;
input.selectionEnd = 2;
@ -1949,13 +1951,13 @@ void testMain() {
test('Get Editing State from text area element', () {
cleanTextEditingStrategy();
editingStrategy.enable(
editingStrategy!.enable(
multilineConfig,
onChange: trackEditingState,
onAction: trackInputAction,
);
final TextAreaElement input = defaultTextEditingRoot.querySelector('textarea');
final TextAreaElement input = defaultTextEditingRoot.querySelector('textarea') as TextAreaElement;
input.value = 'Test';
input.selectionStart = 1;
input.selectionEnd = 2;
@ -1968,7 +1970,7 @@ void testMain() {
});
test('Compare two editing states', () {
final InputElement input = defaultTextEditingRoot.querySelector('input');
final InputElement input = defaultTextEditingRoot.querySelector('input') as InputElement;
input.value = 'Test';
input.selectionStart = 1;
input.selectionEnd = 2;
@ -1989,7 +1991,7 @@ void testMain() {
KeyboardEvent dispatchKeyboardEvent(
EventTarget target,
String type, {
int keyCode,
required int keyCode,
}) {
final Function jsKeyboardEvent = js_util.getProperty(window, 'KeyboardEvent');
final List<dynamic> eventArgs = <dynamic>[
@ -2007,7 +2009,7 @@ KeyboardEvent dispatchKeyboardEvent(
}
MethodCall configureSetStyleMethodCall(int fontSize, String fontFamily,
int textAlignIndex, int fontWeightIndex, int textDirectionIndex) {
int textAlignIndex, int? fontWeightIndex, int textDirectionIndex) {
return MethodCall('TextInput.setStyle', <String, dynamic>{
'fontSize': fontSize,
'fontFamily': fontFamily,
@ -2029,9 +2031,9 @@ MethodCall configureSetSizeAndTransformMethodCall(
/// Will disable editing element which will also clean the backup DOM
/// element from the page.
void cleanTextEditingStrategy() {
if (editingStrategy != null && editingStrategy.isEnabled) {
if (editingStrategy != null && editingStrategy!.isEnabled) {
// Clean up all the DOM elements and event listeners.
editingStrategy.disable();
editingStrategy!.disable();
}
}
@ -2041,7 +2043,10 @@ void cleanTestFlags() {
}
void checkInputEditingState(
InputElement input, String text, int start, int end) {
Element? element, String text, int start, int end) {
expect(element, isNotNull);
expect(element, isA<InputElement>());
final InputElement input = element as InputElement;
expect(defaultTextEditingRoot.activeElement, input);
expect(input.value, text);
expect(input.selectionStart, start);
@ -2082,9 +2087,9 @@ Map<String, dynamic> createFlutterConfig(
bool obscureText = false,
bool autocorrect = true,
String textCapitalization = 'TextCapitalization.none',
String inputAction,
String autofillHint,
List<String> autofillHintsForFields,
String? inputAction,
String? autofillHint,
List<String>? autofillHintsForFields,
bool decimal = false,
}) {
return <String, dynamic>{

View File

@ -6,7 +6,7 @@ environment:
dependencies:
js: 0.6.3
stream_channel: 2.1.0
test: 1.16.6
test: 1.17.7
webkit_inspection_protocol: 1.0.0
ui:
path: ../../lib/web_ui