enterText method

Future<void> enterText(
  1. Finder finder,
  2. String text, {
  3. SettlePolicy? settlePolicy,
  4. Duration? visibleTimeout,
  5. Duration? settleTimeout,
  6. Alignment alignment = Alignment.center,
  7. bool enablePatrolLog = true,
})

Waits until finder finds at least 1 visible widget and then enters text into it.

Example:

// enters text into the first widget having Key('email')
await $(#email).enterText(user@example.com);

If the finder finds more than 1 widget, you can choose which one to enter text into:

// enters text into the third TextField widget
await $(TextField).at(2).enterText('Code ought to be lean');

This method automatically calls WidgetTester.pumpAndSettle after entering text. If you want to disable this behavior, set settlePolicy to SettlePolicy.noSettle.

See also:

Implementation

Future<void> enterText(
  Finder finder,
  String text, {
  SettlePolicy? settlePolicy,
  Duration? visibleTimeout,
  Duration? settleTimeout,
  Alignment alignment = Alignment.center,
  bool enablePatrolLog = true,
}) {
  if (!kIsWeb) {
    // Fix for enterText() not working in release mode on real iOS devices.
    // See https://github.com/flutter/flutter/pull/89703
    // Also the fix for enterText() is not able to interact with the same
    // textfield 2 times in the same test.
    // See https://github.com/flutter/flutter/issues/134604
    tester.testTextInput.register();
  }
  return TestAsyncUtils.guard(
    () => wrapWithPatrolLog(
      action: 'enterText',
      value: text,
      finder: finder,
      color: AnsiCodes.magenta,
      enablePatrolLog: enablePatrolLog,
      function: () async {
        final resolvedFinder = await waitUntilVisible(
          finder,
          timeout: visibleTimeout,
          alignment: alignment,
          enablePatrolLog: false,
        );

        // Workaround for enterText() not working in release mode on real iOS devices.
        // [EditableTextState._openInputConnection] is not called when the text field is focused.
        // So we need to attach text input connection manually.
        if (!kIsWeb && io.Platform.isIOS && kReleaseMode) {
          final editableTextState = tester.state<EditableTextState>(
            find.descendant(
              of: resolvedFinder.first,
              matching: find.byType(EditableText),
              matchRoot: true,
            ),
          );
          final effectiveAutofillClient =
              editableTextState.widget.autofillClient;

          TextInput.attach(
            editableTextState,
            effectiveAutofillClient?.textInputConfiguration ??
                const TextInputConfiguration(),
          );
        }

        await tester.enterText(resolvedFinder.first, text);

        if (!kIsWeb) {
          // After interaction is done, we need to reset the testTextInput
          // to not interfere with consecutive interactions in the same test.
          tester.testTextInput.reset();
        }
        await _performPump(
          settlePolicy: settlePolicy,
          settleTimeout: settleTimeout,
        );
      },
    ),
  );
}