70 lines
2.2 KiB
Dart
70 lines
2.2 KiB
Dart
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
|
import "package:flutter_test/flutter_test.dart";
|
|
import "package:material_ui/material_ui.dart";
|
|
import "package:nexus/widgets/common/error_dialog.dart";
|
|
|
|
// Custom because `patrol_finder` gives me jQuery vibes, and that's Not GoodTM
|
|
extension PumpUntil on WidgetTester {
|
|
/// Pumps until [finder] finds something, failing if it doesn't within 30
|
|
/// seconds, or if the app shows an error.
|
|
Future<void> pumpUntil(Finder finder) async {
|
|
const timeout = Duration(seconds: 30);
|
|
|
|
String textsIn(Finder finder) =>
|
|
widgetList(
|
|
find.descendant(
|
|
of: finder,
|
|
matching: find.byWidgetPredicate(
|
|
(widget) => widget is Text || widget is SelectableText,
|
|
),
|
|
),
|
|
)
|
|
.map(
|
|
(widget) => switch (widget) {
|
|
Text(:final data) || SelectableText(:final data) => data,
|
|
_ => null,
|
|
},
|
|
)
|
|
.nonNulls
|
|
.join("\n");
|
|
|
|
final stopwatch = Stopwatch()..start();
|
|
while (stopwatch.elapsed < timeout) {
|
|
await pump(const .new(milliseconds: 100));
|
|
|
|
if (finder.evaluate().isNotEmpty) return;
|
|
|
|
final errorDialog = find.byType(ErrorDialog);
|
|
if (errorDialog.evaluate().isNotEmpty) {
|
|
fail(
|
|
"The app showed an error while waiting for $finder:\n"
|
|
"${textsIn(errorDialog)}",
|
|
);
|
|
}
|
|
}
|
|
|
|
final snackBar = find.byType(SnackBar);
|
|
final shown = find
|
|
.byType(RichText)
|
|
.hitTestable()
|
|
.evaluate()
|
|
.map((element) => (element.widget as RichText).text.toPlainText())
|
|
.where((text) => text.trim().isNotEmpty)
|
|
.toIList()
|
|
.removeDuplicates()
|
|
.join(" | ");
|
|
fail(
|
|
"Timed out after $timeout waiting for $finder"
|
|
"${snackBar.evaluate().isEmpty ? "" : "\nSnack bar: ${textsIn(snackBar)}"}"
|
|
"\nShown: $shown",
|
|
);
|
|
}
|
|
|
|
/// Taps [finder] once it can be tapped, like after animating in.
|
|
Future<void> tapWhenShown(Finder finder) async {
|
|
final tappable = finder.hitTestable();
|
|
await pumpUntil(tappable);
|
|
await tap(tappable.first);
|
|
await pump();
|
|
}
|
|
}
|