diff --git a/pubspec.lock b/pubspec.lock index 07910e32..2c0775f6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -599,14 +599,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.3" - golden_toolkit: - dependency: "direct dev" - description: - name: golden_toolkit - sha256: "8f74adab33154fe7b731395782797021f97d2edc52f7bfb85ff4f1b5c4a215f0" - url: "https://pub.dev" - source: hosted - version: "0.15.0" graphs: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index e05da616..d2bb7a35 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -83,7 +83,6 @@ dev_dependencies: drift_dev: ^2.26.0 flutter_lints: ^5.0.0 freezed: ^2.5.7 - golden_toolkit: ^0.15.0 json_serializable: ^6.9.4 mockito: ^5.4.4 network_image_mock: ^2.1.1 diff --git a/test/nutrition/goldens/nutritional_plan_1_default_view.png b/test/nutrition/goldens/nutritional_plan_1_default_view.png index 96302ceb..e2b0ae2f 100644 Binary files a/test/nutrition/goldens/nutritional_plan_1_default_view.png and b/test/nutrition/goldens/nutritional_plan_1_default_view.png differ diff --git a/test/nutrition/goldens/nutritional_plan_2_one_meal_with_ingredients.png b/test/nutrition/goldens/nutritional_plan_2_one_meal_with_ingredients.png index 09a8c964..dfebe909 100644 Binary files a/test/nutrition/goldens/nutritional_plan_2_one_meal_with_ingredients.png and b/test/nutrition/goldens/nutritional_plan_2_one_meal_with_ingredients.png differ diff --git a/test/nutrition/goldens/nutritional_plan_3_both_meals_with_ingredients.png b/test/nutrition/goldens/nutritional_plan_3_both_meals_with_ingredients.png index fd452e9e..7a0d5816 100644 Binary files a/test/nutrition/goldens/nutritional_plan_3_both_meals_with_ingredients.png and b/test/nutrition/goldens/nutritional_plan_3_both_meals_with_ingredients.png differ diff --git a/test/nutrition/nutritional_plan_screen_test.dart b/test/nutrition/nutritional_plan_screen_test.dart index d4829ef0..1200b3e0 100644 --- a/test/nutrition/nutritional_plan_screen_test.dart +++ b/test/nutrition/nutritional_plan_screen_test.dart @@ -16,12 +16,9 @@ * along with this program. If not, see . */ -import 'dart:io'; - import 'package:drift/native.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:golden_toolkit/golden_toolkit.dart'; import 'package:http/http.dart' as http; import 'package:mockito/annotations.dart'; import 'package:provider/provider.dart'; @@ -34,6 +31,7 @@ import 'package:wger/providers/nutrition.dart'; import 'package:wger/screens/nutritional_plan_screen.dart'; import '../../test_data/nutritional_plans.dart'; +import '../utils.dart'; import 'nutritional_plan_screen_test.mocks.dart'; @GenerateMocks([WgerBaseProvider, AuthProvider, http.Client]) @@ -67,6 +65,7 @@ void main() { ), ], child: MaterialApp( + key: GlobalKey(), locale: Locale(locale), localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, @@ -84,40 +83,38 @@ void main() { ); } - testGoldens( + testWidgets( 'Test the widgets on the nutritional plan screen', (tester) async { await loadAppFonts(); - final globalKey = GlobalKey(); - await tester.pumpWidgetBuilder( - Material(key: globalKey), - wrapper: materialAppWrapper( - localizations: [AppLocalizations.delegate], - ), - surfaceSize: const Size(500, 1000), - ); + + tester.view.physicalSize = const Size(500, 1000); + tester.view.devicePixelRatio = 1.0; // Ensure correct pixel ratio + await tester.pumpWidget(createNutritionalPlan()); await tester.tap(find.byType(TextButton)); await tester.pumpAndSettle(); - await screenMatchesGolden(tester, 'nutritional_plan_1_default_view', skip: !Platform.isLinux); + await expectLater(find.byType(NutritionalPlanScreen), + matchesGoldenFile('goldens/nutritional_plan_1_default_view.png')); // Default view shows plan description, info button, and no ingredients expect(find.text('Less fat, more protein'), findsOneWidget); - expect(find.byIcon(Icons.info_outline), findsNWidgets(3)); // 2 meals, 1 "other logs" + expect(find.byIcon(Icons.info_outline), + findsNWidgets(3)); // 2 meals, 1 "other logs" expect(find.byIcon(Icons.info), findsNothing); expect(find.text('100g Water'), findsNothing); expect(find.text('75g Burger soup'), findsNothing); // tap the first info button changes it and reveals ingredients for the first meal var infoOutlineButtons = find.byIcon(Icons.info_outline); - await tester.tap(infoOutlineButtons.first); // 2nd button shows up also, but is off-screen + await tester.tap(infoOutlineButtons + .first); // 2nd button shows up also, but is off-screen await tester.pumpAndSettle(); - await screenMatchesGolden( - tester, - 'nutritional_plan_2_one_meal_with_ingredients', - skip: !Platform.isLinux, - ); + await expectLater( + find.byType(NutritionalPlanScreen), + matchesGoldenFile( + 'goldens/nutritional_plan_2_one_meal_with_ingredients.png')); // Ingredients show up now expect(find.text('100g Water'), findsOneWidget); @@ -136,11 +133,11 @@ void main() { await tester.tap(infoOutlineButtons.first); await tester.pumpAndSettle(); - await screenMatchesGolden( - tester, - 'nutritional_plan_3_both_meals_with_ingredients', - skip: !Platform.isLinux, - ); + await expectLater( + find.byType(NutritionalPlanScreen), + matchesGoldenFile( + 'goldens/nutritional_plan_3_both_meals_with_ingredients.png')); + expect(find.byIcon(Icons.info_outline), findsOneWidget); expect(find.byIcon(Icons.info), findsNWidgets(2)); @@ -148,10 +145,15 @@ void main() { expect(find.text('300g Broccoli cake'), findsOneWidget); expect(find.byType(Card), findsNWidgets(3)); + + // Restore the original window size. + tester.view.resetPhysicalSize(); + tester.view.resetDevicePixelRatio(); }, ); - testWidgets('Tests the localization of times - EN', (WidgetTester tester) async { + testWidgets('Tests the localization of times - EN', + (WidgetTester tester) async { await tester.pumpWidget(createNutritionalPlan()); await tester.tap(find.byType(TextButton)); await tester.pumpAndSettle(); @@ -159,7 +161,8 @@ void main() { expect(find.textContaining('5:00 PM'), findsOneWidget); }); - testWidgets('Tests the localization of times - DE', (WidgetTester tester) async { + testWidgets('Tests the localization of times - DE', + (WidgetTester tester) async { await tester.pumpWidget(createNutritionalPlan(locale: 'de')); await tester.tap(find.byType(TextButton)); await tester.pumpAndSettle(); diff --git a/test/utils.dart b/test/utils.dart index 9244b4da..6d60ba79 100644 --- a/test/utils.dart +++ b/test/utils.dart @@ -16,6 +16,10 @@ * along with this program. If not, see . */ +import 'dart:convert'; + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; import 'package:wger/providers/auth.dart'; import 'package:wger/providers/exercises.dart'; @@ -30,3 +34,57 @@ final AuthProvider testAuthProvider = AuthProvider(MockClient(), false) // Test Exercises provider final mockBaseProvider = MockWgerBaseProvider(); final ExercisesProvider testExercisesProvider = ExercisesProvider(mockBaseProvider); + +// Load app fonts +Future loadAppFonts() async { + TestWidgetsFlutterBinding.ensureInitialized(); + + String derivedFontFamily(Map fontDefinition) { + const List overridableFonts = [ + 'Roboto', + '.SF UI Display', + '.SF UI Text', + '.SF Pro Text', + '.SF Pro Display', + ]; + + if (!fontDefinition.containsKey('family')) { + return ''; + } + + final String fontFamily = fontDefinition['family']; + + if (overridableFonts.contains(fontFamily)) { + return fontFamily; + } + + if (fontFamily.startsWith('packages/')) { + final fontFamilyName = fontFamily.split('/').last; + if (overridableFonts.any((font) => font == fontFamilyName)) { + return fontFamilyName; + } + } else { + for (final Map fontType in fontDefinition['fonts']) { + final String? asset = fontType['asset']; + if (asset != null && asset.startsWith('packages')) { + final packageName = asset.split('/')[1]; + return 'packages/$packageName/$fontFamily'; + } + } + } + return fontFamily; + } + + final fontManifest = await rootBundle.loadStructuredData>( + 'FontManifest.json', + (string) async => json.decode(string), + ); + + for (final Map font in fontManifest) { + final fontLoader = FontLoader(derivedFontFamily(font)); + for (final Map fontType in font['fonts']) { + fontLoader.addFont(rootBundle.load(fontType['asset'])); + } + await fontLoader.load(); + } +} \ No newline at end of file diff --git a/test/workout/goldens/routine_logs_screen_detail.png b/test/workout/goldens/routine_logs_screen_detail.png index 0af52b65..40c66843 100644 Binary files a/test/workout/goldens/routine_logs_screen_detail.png and b/test/workout/goldens/routine_logs_screen_detail.png differ diff --git a/test/workout/routine_logs_screen_test.dart b/test/workout/routine_logs_screen_test.dart index e1cad8ab..e3bada88 100644 --- a/test/workout/routine_logs_screen_test.dart +++ b/test/workout/routine_logs_screen_test.dart @@ -16,11 +16,8 @@ * along with this program. If not, see . */ -import 'dart:io'; - import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:golden_toolkit/golden_toolkit.dart'; import 'package:mockito/annotations.dart'; import 'package:provider/provider.dart'; import 'package:wger/l10n/generated/app_localizations.dart'; @@ -30,6 +27,7 @@ import 'package:wger/screens/routine_logs_screen.dart'; import 'package:wger/screens/routine_screen.dart'; import '../../test_data/routines.dart'; +import '../utils.dart'; import 'routine_logs_screen_test.mocks.dart'; @GenerateMocks([RoutinesProvider]) @@ -68,13 +66,15 @@ void main() { ); } - testGoldens('Test the widgets on the routine logs screen', (WidgetTester tester) async { + testWidgets('Test the widgets on the routine logs screen', + (WidgetTester tester) async { await loadAppFonts(); await tester.pumpWidget(renderWidget()); await tester.tap(find.byType(TextButton)); await tester.pumpAndSettle(); - await screenMatchesGolden(tester, 'routine_logs_screen_detail', skip: !Platform.isLinux); + await expectLater(find.byType(WorkoutLogsScreen), + matchesGoldenFile('goldens/routine_logs_screen_detail.png')); // expect(find.text('3 day workout'), findsOneWidget); diff --git a/test/workout/routine_screen_test.dart b/test/workout/routine_screen_test.dart index 8f3e4c14..97ad309c 100644 --- a/test/workout/routine_screen_test.dart +++ b/test/workout/routine_screen_test.dart @@ -16,12 +16,9 @@ * along with this program. If not, see . */ -import 'dart:io'; - import 'package:drift/native.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:golden_toolkit/golden_toolkit.dart'; import 'package:mockito/annotations.dart'; import 'package:provider/provider.dart'; import 'package:wger/database/exercises/exercise_database.dart'; @@ -32,6 +29,7 @@ import 'package:wger/providers/routines.dart'; import 'package:wger/screens/routine_screen.dart'; import '../../test_data/routines.dart'; +import '../utils.dart'; import 'routine_screen_test.mocks.dart'; @GenerateMocks([WgerBaseProvider]) @@ -70,13 +68,15 @@ void main() { ); } - testGoldens('Test the widgets on the routine screen', (WidgetTester tester) async { + testWidgets('Test the widgets on the routine screen', + (WidgetTester tester) async { await loadAppFonts(); await tester.pumpWidget(renderWidget()); await tester.tap(find.byType(TextButton)); await tester.pumpAndSettle(); - await screenMatchesGolden(tester, 'routine_screen_detail', skip: !Platform.isLinux); + await expectLater(find.byType(RoutineScreen), + matchesGoldenFile('goldens/routine_logs_screen_detail.png')); expect(find.text('3 day workout'), findsOneWidget);