Flutter_Pinput icon indicating copy to clipboard operation
Flutter_Pinput copied to clipboard

I have issue with test cases on pinput widget

Open yroza opened this issue 1 year ago • 7 comments

Describe the bug I implemented patrol(https://patrol.leancode.co/) package for perform the integration testing in my current project. when I write the test cases for test the Pinput widget so I am not able to enter text in Pinput widget.

Screenshots Here is my code for test the pinput widget image

Pinput version: [e.g. 1.1.10]

Result of: flutter doctor --verbose

Flutter (Channel stable, 3.7.4, on macOS 13.3.1 22E772610a darwin-arm64, locale en-IN) • Flutter version 3.7.4 on channel stable at /Users/yash/Documents/FlutterSdk/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision b4bce91dd0 (4 months ago), 2023-02-21 09:50:50 +0800 • Engine revision 248290d6d5 • Dart version 2.19.2 • DevTools version 2.20.1

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0) • Android SDK at /Users/yash/Library/Android/sdk • Platform android-33, build-tools 33.0.0 • ANDROID_HOME = /Users/yash/Users/yash/Library/Android/sdk • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694) • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 14E222b • CocoaPods version 1.11.3

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

[✓] Android Studio (version 2022.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)

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

[✓] Connected device (3 available) • sdk gphone64 arm64 (mobile) • emulator-5554 • android-arm64 • Android 13 (API 33) (emulator) • macOS (desktop) • macos • darwin-arm64 • macOS 13.3.1 22E772610a darwin-arm64 • Chrome (web) • chrome • web-javascript • Google Chrome 114.0.5735.106

[✓] HTTP Host Availability • All required HTTP hosts are available

• No issues found!

Result of: patrol doctor

Patrol CLI version: 1.1.10 Program adb found in /Users/yash/Library/Android/sdk/platform-tools/adb Env var $ANDROID_HOME set to /Users/yash/Users/yash/Library/Android/sdk Program xcodebuild found in /usr/bin/xcodebuild Program ideviceinstaller found in /Users/yash/homebrew/bin/ideviceinstaller Program ios-deploy found in /Users/yash/homebrew/bin/ios-deploy

Smartphone (please complete the following information):

  • Device: [e.g. emulator-5554]
  • OS: [e.g. Android 13]

Additional context when I run the patrol develop command then I got this result image

yroza avatar Jun 08 '23 07:06 yroza

Also reported in the Patrol repository: https://github.com/leancodepl/patrol/issues/1409

bartekpacia avatar Jun 27 '23 23:06 bartekpacia

Hey @yroza @bartekpacia, can you confirm that this code snippet works for you as well?

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinput/pinput.dart';

void main() {
  testWidgets('Can enter value', (WidgetTester tester) async {
    String? fieldValue;
    int called = 0;
    final controller = TextEditingController();
    final focusNode = FocusNode();

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: Pinput(
            controller: controller,
            onChanged: (value) {
              fieldValue = value;
              called++;
            },
          ),
        ),
      ),
    );

    focusNode.requestFocus();
    await tester.pump();

    expect(fieldValue, isNull);
    expect(called, 0);

    await tester.enterText(find.byType(Pinput), '1111');
    await tester.testTextInput.receiveAction(TextInputAction.done);
    expect(fieldValue, equals('1111'));
    expect(called, 1);
  });
}

Tkko avatar Jun 28 '23 06:06 Tkko

Thanks @Tkko, this code works in a widget test (when run with flutter test test/pinput_test.dart).

When I run it in a real app on the device (with flutter run test/pinput_test.dart), it also works:

pinput_test.dart.webm

I had to modify your test slightly to use setState(), so the changes made are visible:

Test code
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pinput/pinput.dart';

void main() {
  testWidgets('Can enter value', (tester) async {
    String? fieldValue;
    var called = 0;
    final controller = TextEditingController();
    final focusNode = FocusNode();

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: StatefulBuilder(
            builder: (context, setState) {
              return Pinput(
                controller: controller,
                onChanged: (value) {
                  setState(() {
                    fieldValue = value;
                    called++;
                  });
                },
              );
            },
          ),
        ),
      ),
    );

    focusNode.requestFocus();
    await tester.pump();

    expect(fieldValue, isNull);
    expect(called, 0);

    await tester.enterText(find.byType(Pinput), '1111');
    await tester.pumpAndSettle(Duration(seconds: 2));
    await tester.testTextInput.receiveAction(TextInputAction.done);
    await tester.pumpAndSettle(Duration(seconds: 2));
    expect(fieldValue, equals('1111'));
    expect(called, 1);
  });
}

bartekpacia avatar Jun 28 '23 07:06 bartekpacia

@bartekpacia Perfect, I'm not sure how patrol works but Pinput uses an EditableText which is an underlying widget of TextField and CupertinoTextField so everything should work in the same way

Tkko avatar Jun 28 '23 08:06 Tkko

I'm curious whether you use a single EditableText for all of the number squares, or a single EditableText for each one of the number squares?

If you use a single EditableText for all, how does it work that you have a gap between the number squares?

bartekpacia avatar Jun 28 '23 08:06 bartekpacia

I use single EditableText Which is hidden under the boxes.

Screenshot 2023-06-28 at 12 15 30 PM

https://github.com/Tkko/Flutter_Pinput/blob/e34e5f2e2bf155d41569a49c342be0c740b4a159/lib/src/pinput_state.dart#L376

Tkko avatar Jun 28 '23 08:06 Tkko

For any one facing the same issue: add one duration to pump method before calling await tester.enterText(find.byType(Pinput), '1111'); example: await tester.pump(Duration(milliseconds: 500));

abdalmonem avatar May 07 '24 11:05 abdalmonem