I have a dynamic form system that builds widgets based on a json. One of the components that can be parsed is a Checkbox and a default value is passed to determine whether or not it is checked/unchecked initially. I'm writing a unit test for this and am running into trouble with semantics.
My test begins with checking the widget has been built (the following test is successful)
//create form
await tester.pumpWidget(buildTestableWidget(testWidget));
//setup Finder
Finder widgetFinder = find.widgetWithText(FormCheckbox, "test checkbox");
//test for widget
expect(widgetFinder, findsOneWidget);
The FormCheckbox
class is as follows
class FormCheckbox extends StatefulWidget {
final forms.Checkbox component;
FormCheckbox(this.component) : super(key: Key("${component.propertyKey().getId()}"));
_FormCheckboxState createState() => _FormCheckboxState(component);
}
class _FormCheckboxState extends State<FormCheckbox> {
_FormCheckboxState(this._component) {
this.boxValue = _component.isDefaultSelected();
}
final forms.Checkbox _component;
bool boxValue;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 16, right: 16, top: 6, bottom: 6),
child: ListTile(
leading: Material(
child: Checkbox(
value: boxValue,
onChanged: (bool newValue) {
setState(() {
boxValue = newValue;
});
})),
title: Text("${_component.getLabel()}"),
));
}
String validator(String value) {
//TODO: Implement validator
throw UnimplementedError();
}
}
Which despite everything else, has a Checkbox
component as a child which defaults to a boolean I can set (which I can confirm is definitely working properly).
I would expect, from looking at flutter's own tests for checkboxes here that I can use getSemantics
and expect it to equal a matchedSemantics
within which isChecked = true
as shown here
//test default value
expect(
tester.getSemantics(find.byType(Checkbox)),
matchesSemantics(
isChecked: true,
hasEnabledState: true,
isEnabled: true,
));
However the isChecked state is remaining as false, even after a tap with await tester.tap(find.byKey(Key("1")));
The error message given is
Expected: has semantics with actions: [] with flags: [
SemanticsFlag:SemanticsFlag.isChecked,
SemanticsFlag:SemanticsFlag.hasEnabledState,
SemanticsFlag:SemanticsFlag.isEnabled
]
Actual: SemanticsNode:<SemanticsNode#5(Rect.fromLTRB(0.0, 0.0, 800.0, 68.0), tags:
[RenderViewport.twoPane], flags: [hasEnabledState, isEnabled], label: "test checkbox",
textDirection: ltr)>
Which: flags were: [hasEnabledState, isEnabled]
What am I missing here? Why is a created Checkbox object with value: true not giving a semantics value of isChecked = true
I found the solution.
Edit: Update after @brightknight08's comment
final checkboxFinder = find.byKey(const Key('aKey'));
var checkbox = tester.firstWidget<Checkbox>(checkboxFinder);
expect(checkbox.value, false);
await tester.tap(checkboxFinder);
await tester.pump();
checkbox = tester.firstWidget<Checkbox>(checkboxFinder);
expect(checkbox.value, true);
I think it works the same way with find.byType(Checkbox)
.
another method:
expect(tester.widget<Checkbox>(find.byKey("your-key")).value, false);
or if you are using CheckboxListTile try the following
expect(tester.widget<CheckboxListTile>(find.byKey("your-key")).value, false);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With