import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:lightmeter/application.dart'; import 'package:lightmeter/application_wrapper.dart'; import 'package:lightmeter/environment.dart'; import 'package:lightmeter/generated/l10n.dart'; import 'package:lightmeter/res/dimens.dart'; import 'package:lightmeter/screens/metering/components/shared/exposure_pairs_list/widget_list_exposure_pairs.dart'; import 'package:lightmeter/screens/metering/screen_metering.dart'; import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; import '../mocks/iap_products_mock.dart'; import '../mocks/paid_features_mock.dart'; import 'finder_actions.dart'; import 'platform_channel_mock.dart'; const mockPhotoEv100 = 8.3; extension WidgetTesterCommonActions on WidgetTester { Future pumpApplication({ IAPProductStatus productStatus = IAPProductStatus.purchased, List? equipmentProfiles, String selectedEquipmentProfileId = '', List? availableFilms, List? filmsInUse, Film selectedFilm = const Film.other(), }) async { await pumpWidget( MockIAPProductsProvider( initialyPurchased: productStatus == IAPProductStatus.purchased, child: ApplicationWrapper( const Environment.dev(), child: MockIAPProviders( equipmentProfiles: equipmentProfiles, selectedEquipmentProfileId: selectedEquipmentProfileId, availableFilms: availableFilms, filmsInUse: filmsInUse, selectedFilm: selectedFilm, child: const Application(), ), ), ), ); await pumpAndSettle(); } Future takePhoto() async { await tap(find.measureButton()); await pump(const Duration(seconds: 2)); // wait for circular progress indicator await pump(const Duration(seconds: 1)); // wait for circular progress indicator await pumpAndSettle(); } Future toggleIncidentMetering(double ev) async { await tap(find.measureButton()); await sendMockIncidentEv(ev); await tap(find.measureButton()); await pumpAndSettle(); } Future openAnimatedPicker() async { await tap(find.byType(T)); await pumpAndSettle(Dimens.durationL); } Future openSettings() async { await tap(find.byTooltip(S.current.tooltipOpenSettings)); await pumpAndSettle(); } Future navigatorPop() async { (state(find.byType(Navigator)) as NavigatorState).pop(); await pumpAndSettle(Dimens.durationML); } } extension WidgetTesterListTileActions on WidgetTester { /// Useful for tapping a specific [ListTile] inside a specific screen or dialog Future tapDescendantTextOf(String text) async { await tap(find.descendant(of: find.byType(T), matching: find.text(text))); await pumpAndSettle(); } } extension WidgetTesterTextButtonActions on WidgetTester { Future tapSelectButton() => _tapTextButton(S.current.select); Future tapCancelButton() => _tapTextButton(S.current.cancel); Future tapSaveButton() => _tapTextButton(S.current.save); Future _tapTextButton(String text) async { final button = find.byWidgetPredicate( (widget) => widget is TextButton && widget.child is Text && (widget.child as Text?)?.data == text, ); expect(button, findsOneWidget); await tap(button); await pumpAndSettle(); } } extension WidgetTesterExposurePairsListActions on WidgetTester { Future scrollToTheLastExposurePair({ double ev = mockPhotoEv100, StopType stopType = StopType.third, EquipmentProfile equipmentProfile = defaultEquipmentProfile, }) async { final exposurePairs = MeteringContainerBuidler.buildExposureValues( ev, StopType.third, equipmentProfile, ); await scrollUntilVisible( find.byWidgetPredicate((widget) => widget is Row && widget.key == ValueKey(exposurePairs.length - 1)), 56, scrollable: find.descendant(of: find.byType(ExposurePairsList), matching: find.byType(Scrollable)), ); } }