flutter/flutter

[Integration_test 2.5] tester.enterText is broken in release mode

rxlabz opened this issue · 19 comments

Since the Flutter 2.5 upgrade, tester.enterText() seems broken in my web integration tests in --release mode.
When I run flutter drive with --no-headless, I can see that no text is added in text fields.

Steps to Reproduce

You can reproduce it with this repo https://github.com/rxlabz/text_drive

sh drive_web.sh
sh drive_web_release.sh

You can also see the result of 3 GH actions workflows in the project :

  1. the first is running the integration_test without --release (https://github.com/rxlabz/text_drive/blob/master/.github/workflows/integration.yaml) => it works ( all tests passed ) https://github.com/rxlabz/text_drive/actions/runs/1217290271

  2. the other uses--release (https://github.com/rxlabz/text_drive/blob/master/.github/workflows/integration_release.yaml) and fails => https://github.com/rxlabz/text_drive/actions/runs/1217290268

  3. the last one is running with flutter 2.2.3 in --release https://github.com/rxlabz/text_drive/actions/runs/1217434660/workflow => it works https://github.com/rxlabz/text_drive/runs/3556551737

App
import 'package:flutter/material.dart';

void main() {
  runApp(const App());
}

class App extends StatelessWidget {
  const App({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) => const MaterialApp(home: MainScreen());
}

class MainScreen extends StatefulWidget {
  const MainScreen({Key? key}) : super(key: key);

  @override
  State<MainScreen> createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  final TextEditingController controller = TextEditingController();

  String value = 'test';

  @override
  void initState() {
    super.initState();
    controller.addListener(() => setState(() => value = controller.text));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            TextFormField(key: const Key('field'), controller: controller),
            Text(value)
          ],
        ),
      ),
    );
  }
}
integration test
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:text_drive/main.dart';

void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

  testWidgets("failing test example", (WidgetTester tester) async {
    await tester.pumpWidget(const App());

    final input = find.byKey(const Key('field'));
    expect(input, findsOneWidget);

    expect(find.text('test'), findsOneWidget);

    await tester.tap(input);
    await tester.enterText(input, 'Hello');

    // same result with `updateEditingValue`
    // (cf.https://flutter.dev/docs/release/breaking-changes/enterText-trailing-caret)
    // await tester.showKeyboard(input);
    // await tester.pumpAndSettle();
    //tester.testTextInput.updateEditingValue(
    //  const TextEditingValue(text: 'Hello'),
    //);

    await tester.pump();

    expect(find.text('Hello'), findsNWidgets(2));
  });
}

@rxlabz
Thanks for reporting. This is strange, because I have a working integration_test login screen demo app which used to work until recently. After reading this issue, I tried to run it on web in debug and release mode which isn't working for me as well. On login screen, no action takes place:

Screenshot 2021-09-10 at 5 26 01 PM

But I verified this on stable 2.2.3, 2.5.0 and latest master, but on all of them, the test isn't entering any input.
Without --no-headless too, I don't think it's working.

I doubt if it's related to the chrome driver. Because it worked for Chrome 91, but now my Chrome version is 93, so I installed compatible chrome driver.

Does your code sample run locally in release mode ?

@darshankawar yes, the app runs normally with flutter run -d chrome --release

@rxlabz
Sorry, I meant the integration_test in release mode locally.

@darshankawar :) sorry I wasn't sure.
Locally, it's the same than on GitHub actions : in release mode the integration test passes with Flutter 2.2.3, not with Flutter 2.5.

Thanks. Verified the same on stable 2.2.3 and on stable 2.5.0 in release mode and I see the same behavior.

stable flutter doctor -v
[✓] Flutter (Channel stable, 2.2.3, on Mac OS X 10.15.4 19E2269 darwin-x64,
    locale en-GB)
    • Flutter version 2.2.3 at /Users/dhs/documents/fluttersdk/flutter
    • Framework revision f4abaa0735 (2 months ago), 2021-07-01 12:46:11 -0700
    • Engine revision 241c87ad80
    • Dart version 2.13.4

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.3, Build version 12C33
    • CocoaPods version 1.10.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] VS Code (version 1.58.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.21.0

[✓] Connected device (3 available)
    • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729 • ios
      • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)
    • macOS (desktop)            • macos                                •
      darwin-x64     • Mac OS X 10.15.4 19E2269 darwin-x64
    • Chrome (web)               • chrome                               •
      web-javascript • Google Chrome 93.0.4577.63

• No issues found!


[✓] Flutter (Channel stable, 2.5.0, on Mac OS X 10.15.4 19E2269 darwin-x64,
    locale en-GB)
    • Flutter version 2.5.0 at /Users/dhs/documents/fluttersdk/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 4cc385b4b8 (5 days ago), 2021-09-07 23:01:49 -0700
    • Engine revision f0826da7ef
    • Dart version 2.14.0

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.3, Build version 12C33
    • CocoaPods version 1.10.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] VS Code (version 1.58.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.21.0

[✓] Connected device (3 available)
    • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729 • ios
      • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)
    • macOS (desktop)            • macos                                •
      darwin-x64     • Mac OS X 10.15.4 19E2269 darwin-x64
    • Chrome (web)               • chrome                               •
      web-javascript • Google Chrome 93.0.4577.63

• No issues found!

It's not just in web mode. I have the same issue with running the integration tests on a real Android device. #89917

I am seeing this on both Android and iOS. When integration testing, tester.enterText() does nothing.

Please keep an eye on this PR : #89703

Removing the web label as this is a framework issue.

@Lukas-Koelbl I downgraded the version of Flutter.

Related issue: #91492

In the issue I raised, linked above, you will see the same problem; however, I have also included the output in the chrome console (different from the terminal output when NOT running with --debug). Hopefully this can help to better diagnose the issue.

I'm not sure how this is wired up on the web side - it's more one for @yjbanov or @hterkelsen I think. Or maybe @mdebbar.

FWIW, I'm temporarily setting the text using (tester.firstWidget(<finder>) as TextField).controller?.text = 'My Text' as a workaround.

Please keep an eye on this PR : #89703

This PR does not change anything. It justs adds documentation.

Another workaround is to register the tester.testTextInput and disable the semantics cf. #91492 (comment)

testWidgets(
  'a test',
  (t){
    tester.testTextInput.register();
    // ...
  },
  semanticsEnabled:false,
);
lhimo commented

@rxlabz Does it actually work? It doesn't for me apparently

@lhimo yes it works in my projects. I just notice that tester.testTextInput should be registered to make it work. you can see it here https://github.com/rxlabz/text_drive/runs/5091722721?check_suite_focus=true

Data point for anyone having the same bug in ios, I can confirm simply adding tester.testTextInput.register(); at the start of the test fixes the text input for iOS on profile integration tests (previously would only work in debug builds). I did not need to disable semantics.