- LibraryFilter: word search on names; muscle (primary), equipment and level choices that widen within a filter and narrow across filters - ExerciseBrowser (reusable for the Plan picker) with search field, filter sheets showing live result counts, a clear button and an empty state - Exercise detail: start/end Flip Animation at each Mode's pace (still with reduced motion), facts, main/secondary muscles, numbered steps Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
84 lines
2.8 KiB
Dart
84 lines
2.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:zenxercise/src/exercises/views/exercise_detail_view.dart';
|
|
import 'package:zenxercise/src/exercises/views/flip_animation.dart';
|
|
|
|
import '../support/test_app.dart';
|
|
|
|
void main() {
|
|
Future<void> openLibrary(WidgetTester tester) async {
|
|
usePhoneScreen(tester);
|
|
await pumpApp(tester);
|
|
await tester.tap(find.byTooltip('Library'));
|
|
await tester.pumpAndSettle();
|
|
}
|
|
|
|
testWidgets('search narrows the list and the count follows', (tester) async {
|
|
await openLibrary(tester);
|
|
|
|
await tester.enterText(find.byType(TextField), 'calf');
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('Calf Stretch'), findsOneWidget);
|
|
expect(find.text('90/90 Hamstring'), findsNothing);
|
|
expect(find.text('1 of 2 stretches'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('a muscle filter narrows the list and clearing brings everything back', (tester) async {
|
|
await openLibrary(tester);
|
|
|
|
await tester.tap(find.text('Muscle'));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.widgetWithText(FilterChip, 'Calves'));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.text('Show 1 result'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('Calf Stretch'), findsOneWidget);
|
|
expect(find.text('90/90 Hamstring'), findsNothing);
|
|
|
|
await tester.tap(find.byTooltip('Clear filters'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('90/90 Hamstring'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('no matches says so and offers to clear', (tester) async {
|
|
await openLibrary(tester);
|
|
|
|
await tester.enterText(find.byType(TextField), 'zzz');
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('No matches'), findsOneWidget);
|
|
|
|
await tester.tap(find.text('Clear filters'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('90/90 Hamstring'), findsOneWidget);
|
|
expect(find.text('zzz'), findsNothing);
|
|
});
|
|
|
|
testWidgets('an Exercise opens its detail page, whose images flip', (tester) async {
|
|
await openLibrary(tester);
|
|
|
|
await tester.tap(find.text('90/90 Hamstring'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.byType(ExerciseDetailView), findsOneWidget);
|
|
int frame() => tester.state<FlipAnimationState>(find.byType(FlipAnimation)).frame;
|
|
expect(frame(), 0);
|
|
await tester.pump(const Duration(milliseconds: 1500));
|
|
expect(frame(), 1);
|
|
|
|
final page = find.descendant(of: find.byType(ExerciseDetailView), matching: find.byType(Scrollable)).first;
|
|
for (final text in ['Hamstrings', 'Calves', 'Lie on your back.']) {
|
|
await tester.scrollUntilVisible(find.text(text), 100, scrollable: page);
|
|
expect(find.text(text), findsOneWidget);
|
|
}
|
|
|
|
// Leave the page so its flip timer stops.
|
|
await tester.pageBack();
|
|
await tester.pumpAndSettle();
|
|
});
|
|
}
|