Flutter_Pinput
Flutter_Pinput copied to clipboard
I have issue with test cases on pinput widget
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
Pinput version: [e.g. 1.1.10]
Result of: flutter doctor --verbose
[✓] 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
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
Also reported in the Patrol repository: https://github.com/leancodepl/patrol/issues/1409
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);
});
}
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:
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 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
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?
I use single EditableText
Which is hidden under the boxes.
https://github.com/Tkko/Flutter_Pinput/blob/e34e5f2e2bf155d41569a49c342be0c740b4a159/lib/src/pinput_state.dart#L376
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));