added more expectations to e2e test

This commit is contained in:
Vadim 2024-03-11 22:10:25 +01:00
parent aeef317523
commit d33cadc4fa
3 changed files with 68 additions and 274 deletions

View file

@ -53,8 +53,11 @@ void main() {
await _expectMeteringState( await _expectMeteringState(
tester, tester,
equipmentProfile: mockEquipmentProfiles[0], equipmentProfile: mockEquipmentProfiles[0],
film: mockFilms[0],
fastest: 'f/1.8 - 1/400', fastest: 'f/1.8 - 1/400',
slowest: 'f/16 - 1/5', slowest: 'f/16 - 1/5',
iso: '400',
nd: 'None',
ev: mockPhotoEv100 + 2, ev: mockPhotoEv100 + 2,
); );
@ -62,25 +65,44 @@ void main() {
/// Add ND to shoot another scene /// Add ND to shoot another scene
await tester.openPickerAndSelect<NdValuePicker, NdValue>('2'); await tester.openPickerAndSelect<NdValuePicker, NdValue>('2');
expectPickerTitle<NdValuePicker>('2');
await _expectMeteringStateAndMeasure( await _expectMeteringStateAndMeasure(
tester, tester,
equipmentProfile: mockEquipmentProfiles[0], equipmentProfile: mockEquipmentProfiles[0],
film: mockFilms[0],
fastest: 'f/1.8 - 1/200', fastest: 'f/1.8 - 1/200',
slowest: 'f/16 - 1/2.5', slowest: 'f/16 - 1/2.5',
iso: '400',
nd: '2',
ev: mockPhotoEv100 + 2 - 1, ev: mockPhotoEv100 + 2 - 1,
); );
/// Select another lens without ND /// Select another lens without ND
await tester.openPickerAndSelect<EquipmentProfilePicker, EquipmentProfile>(mockEquipmentProfiles[1].name);
await tester.openPickerAndSelect<NdValuePicker, NdValue>('None'); await tester.openPickerAndSelect<NdValuePicker, NdValue>('None');
expectPickerTitle<NdValuePicker>('None');
await _expectMeteringStateAndMeasure( await _expectMeteringStateAndMeasure(
tester, tester,
equipmentProfile: mockEquipmentProfiles[0], equipmentProfile: mockEquipmentProfiles[1],
fastest: 'f/1.8 - 1/400', film: mockFilms[0],
slowest: 'f/16 - 1/5', fastest: 'f/3.5 - 1/100',
slowest: 'f/22 - 1/2.5',
iso: '400',
nd: 'None',
ev: mockPhotoEv100 + 2, ev: mockPhotoEv100 + 2,
); );
/// Set another wilm and set the same ISO
await tester.openPickerAndSelect<IsoValuePicker, IsoValue>('200');
await tester.openPickerAndSelect<FilmPicker, Film>(mockFilms[1].name);
await _expectMeteringStateAndMeasure(
tester,
equipmentProfile: mockEquipmentProfiles[1],
film: mockFilms[1],
fastest: 'f/3.5 - 1/50',
slowest: 'f/22 - 1/1.3',
iso: '200',
nd: 'None',
ev: mockPhotoEv100 + 1,
);
}, },
); );
} }
@ -96,13 +118,19 @@ extension on WidgetTester {
Future<void> _expectMeteringState( Future<void> _expectMeteringState(
WidgetTester tester, { WidgetTester tester, {
required EquipmentProfile equipmentProfile, required EquipmentProfile equipmentProfile,
required Film film,
required String fastest, required String fastest,
required String slowest, required String slowest,
required String iso,
required String nd,
required double ev, required double ev,
String? reason, String? reason,
}) async { }) async {
expectPickerTitle<EquipmentProfilePicker>(equipmentProfile.name); expectPickerTitle<EquipmentProfilePicker>(equipmentProfile.name);
expectPickerTitle<FilmPicker>(film.name);
expectExtremeExposurePairs(fastest, slowest); expectExtremeExposurePairs(fastest, slowest);
expectPickerTitle<IsoValuePicker>(iso);
expectPickerTitle<NdValuePicker>(nd);
expectExposurePairsListItem(tester, fastest.split(' - ')[0], fastest.split(' - ')[1]); expectExposurePairsListItem(tester, fastest.split(' - ')[0], fastest.split(' - ')[1]);
await tester.scrollToTheLastExposurePair(equipmentProfile: equipmentProfile); await tester.scrollToTheLastExposurePair(equipmentProfile: equipmentProfile);
expectExposurePairsListItem(tester, slowest.split(' - ')[0], slowest.split(' - ')[1]); expectExposurePairsListItem(tester, slowest.split(' - ')[0], slowest.split(' - ')[1]);
@ -112,23 +140,32 @@ Future<void> _expectMeteringState(
Future<void> _expectMeteringStateAndMeasure( Future<void> _expectMeteringStateAndMeasure(
WidgetTester tester, { WidgetTester tester, {
required EquipmentProfile equipmentProfile, required EquipmentProfile equipmentProfile,
required Film film,
required String fastest, required String fastest,
required String slowest, required String slowest,
required String iso,
required String nd,
required double ev, required double ev,
}) async { }) async {
await _expectMeteringState( await _expectMeteringState(
tester, tester,
equipmentProfile: equipmentProfile, equipmentProfile: equipmentProfile,
film: film,
fastest: fastest, fastest: fastest,
slowest: slowest, slowest: slowest,
iso: iso,
nd: nd,
ev: ev, ev: ev,
); );
await tester.takePhoto(); await tester.takePhoto();
await _expectMeteringState( await _expectMeteringState(
tester, tester,
equipmentProfile: equipmentProfile, equipmentProfile: equipmentProfile,
film: film,
fastest: fastest, fastest: fastest,
slowest: slowest, slowest: slowest,
iso: iso,
nd: nd,
ev: ev, ev: ev,
reason: reason:
'Metering screen state must be the same before and after the measurement assuming that the scene is exactly the same.', 'Metering screen state must be the same before and after the measurement assuming that the scene is exactly the same.',

View file

@ -1,264 +0,0 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:lightmeter/data/models/ev_source_type.dart';
import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:lightmeter/data/shared_prefs_service.dart';
import 'package:lightmeter/generated/l10n.dart';
import 'package:lightmeter/screens/metering/components/bottom_controls/components/measure_button/widget_button_measure.dart';
import 'package:lightmeter/screens/metering/components/shared/exposure_pairs_list/components/exposure_pairs_list_item/widget_item_list_exposure_pairs.dart';
import 'package:lightmeter/screens/metering/components/shared/exposure_pairs_list/widget_list_exposure_pairs.dart';
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/equipment_profile_picker/widget_picker_equipment_profiles.dart';
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/extreme_exposure_pairs_container/widget_container_extreme_exposure_pairs.dart';
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/film_picker/widget_picker_film.dart';
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/iso_picker/widget_picker_iso.dart';
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/nd_picker/widget_picker_nd.dart';
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/shared/animated_dialog_picker/components/dialog_picker/widget_picker_dialog.dart';
import 'package:lightmeter/screens/metering/screen_metering.dart';
import 'package:lightmeter/screens/settings/screen_settings.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
import 'package:meta/meta.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../integration_test/utils/widget_tester_actions.dart';
import 'mocks/paid_features_mock.dart';
const mockPhotoFastestAperture = ApertureValue(1, StopType.full);
const mockPhotoSlowestAperture = ApertureValue(45, StopType.full);
const mockPhotoFastestShutterSpeed = ShutterSpeedValue(320, true, StopType.third);
const mockPhotoSlowestShutterSpeed = ShutterSpeedValue(6, false, StopType.third);
const mockPhotoFastestExposurePair = ExposurePair(mockPhotoFastestAperture, mockPhotoFastestShutterSpeed);
const mockPhotoSlowestExposurePair = ExposurePair(mockPhotoSlowestAperture, mockPhotoSlowestShutterSpeed);
class MeteringValuesExpectation {
final String fastestExposurePair;
final String slowestExposurePair;
final double ev;
const MeteringValuesExpectation(
this.fastestExposurePair,
this.slowestExposurePair,
this.ev,
);
}
@isTestGroup
void testMeteringScreenPickers(String description) {
group(
description,
() {
setUp(() {
SharedPreferences.setMockInitialValues({
/// Metering values
UserPreferencesService.evSourceTypeKey: EvSourceType.camera.index,
UserPreferencesService.meteringScreenLayoutKey: json.encode(
{
MeteringScreenLayoutFeature.equipmentProfiles: true,
MeteringScreenLayoutFeature.extremeExposurePairs: true,
MeteringScreenLayoutFeature.filmPicker: true,
}.toJson(),
),
});
});
group(
'Select film',
() {
testMeteringPicker<FilmPicker, Film>(
'with the same ISO',
expectBefore: MeteringValuesExpectation(
mockPhotoFastestExposurePair.toString(),
mockPhotoSlowestExposurePair.toString(),
mockPhotoEv100,
),
valueToSelect: mockFilms[0].name,
expectAfter: MeteringValuesExpectation(
mockPhotoFastestExposurePair.toString(),
'$mockPhotoSlowestAperture - ${mockFilms[0].reciprocityFailure(mockPhotoSlowestShutterSpeed)}',
mockPhotoEv100,
),
);
testMeteringPicker<FilmPicker, Film>(
'with greater ISO',
expectBefore: MeteringValuesExpectation(
mockPhotoFastestExposurePair.toString(),
mockPhotoSlowestExposurePair.toString(),
mockPhotoEv100,
),
valueToSelect: mockFilms[1].name,
expectAfter: MeteringValuesExpectation(
mockPhotoFastestExposurePair.toString(),
'$mockPhotoSlowestAperture - ${mockFilms[1].reciprocityFailure(mockPhotoSlowestShutterSpeed)}',
mockPhotoEv100,
),
);
},
);
testMeteringPicker<IsoValuePicker, IsoValue>(
'Select ISO +1 EV',
expectBefore: MeteringValuesExpectation(
mockPhotoFastestExposurePair.toString(),
mockPhotoSlowestExposurePair.toString(),
mockPhotoEv100,
),
valueToSelect: '400',
expectAfter: MeteringValuesExpectation(
'$mockPhotoFastestAperture - 1/1250',
'$mockPhotoSlowestAperture - 1.6"',
mockPhotoEv100 + 2,
),
);
testMeteringPicker<NdValuePicker, NdValue>(
'Select ND -1 EV',
expectBefore: MeteringValuesExpectation(
mockPhotoFastestExposurePair.toString(),
mockPhotoSlowestExposurePair.toString(),
mockPhotoEv100,
),
valueToSelect: '2',
expectAfter: MeteringValuesExpectation(
'$mockPhotoFastestAperture - 1/160',
'$mockPhotoSlowestAperture - 13"',
mockPhotoEv100 - 1,
),
);
testWidgets(
description,
(tester) async {
Future<void> selectAndExpect<P, V>(
String valueToSelect,
MeteringValuesExpectation expectation, {
String? reason,
}) async {
/// Verify, that EV is recalculated with a new setting
await tester.openPickerAndSelect<P, V>(valueToSelect);
_expectPickerTitle<P>(valueToSelect);
expectExposurePairsContainer(expectation.fastestExposurePair, expectation.slowestExposurePair);
expectMeasureButton(expectation.ev);
/// Make sure, that the selected setting is applied in the subsequent measurements
await tester.takePhoto();
await tester.takePhoto();
expectExposurePairsContainer(expectation.fastestExposurePair, expectation.slowestExposurePair);
expectMeasureButton(expectation.ev);
}
await tester.pumpApplication();
await tester.takePhoto();
await selectAndExpect<IsoValuePicker, IsoValue>(
'400',
MeteringValuesExpectation(
'$mockPhotoFastestAperture - 1/1250',
'$mockPhotoSlowestAperture - 1.6"',
mockPhotoEv100 + 2,
),
reason: 'Selecting ISO value must change EV value and therefore exposure pairs.',
);
await selectAndExpect<NdValuePicker, NdValue>(
'2',
MeteringValuesExpectation(
'$mockPhotoFastestAperture - 1/640',
'$mockPhotoSlowestAperture - 3"',
mockPhotoEv100 - 1,
),
reason: 'Selecting ND value must change EV value and therefore exposure pairs.',
);
await selectAndExpect<FilmPicker, Film>(
mockFilms[0].name,
MeteringValuesExpectation(
mockPhotoFastestExposurePair.toString(),
'$mockPhotoSlowestAperture - ${mockFilms[0].reciprocityFailure(mockPhotoSlowestShutterSpeed)}',
mockPhotoEv100,
),
reason: 'Selecting with the same ISO must change nothing exept exposure pairs due to reciprocity.',
);
await selectAndExpect<FilmPicker, Film>(
mockFilms[1].name,
MeteringValuesExpectation(
mockPhotoFastestExposurePair.toString(),
'$mockPhotoSlowestAperture - ${mockFilms[0].reciprocityFailure(mockPhotoSlowestShutterSpeed)}',
mockPhotoEv100,
),
reason:
'Selecting with a different ISO must must indicate push/pull and can change nothing exept exposure pairs due to reciprocity.',
);
},
);
},
);
}
/// Runs the picker test
///
/// 1. Takes photo and verifies `expectBefore` values
/// 2. Opens a picker and select the provided value
/// 3. Verifies `expectAfter`
/// 4. Takes photo and verifies `expectAfter` values
@isTest
void testMeteringPicker<P, V>(
String description, {
required MeteringValuesExpectation expectBefore,
required String valueToSelect,
required MeteringValuesExpectation expectAfter,
bool? skip,
}) {
testWidgets(
description,
(tester) async {
await tester.pumpApplication();
// Verify initial EV
await tester.toggleIncidentMetering(expectBefore.ev);
expectExposurePairsContainer(expectBefore.fastestExposurePair, expectBefore.slowestExposurePair);
expectMeasureButton(expectBefore.ev);
/// Verify, that EV is recalculated with a new setting
await tester.openPickerAndSelect<P, V>(valueToSelect);
expectExposurePairsContainer(expectAfter.fastestExposurePair, expectAfter.slowestExposurePair);
expectMeasureButton(expectAfter.ev);
/// Make sure, that the selected setting is applied in the subsequent measurements
await tester.toggleIncidentMetering(expectBefore.ev);
expectExposurePairsContainer(expectAfter.fastestExposurePair, expectAfter.slowestExposurePair);
expectMeasureButton(expectAfter.ev);
},
skip: skip,
);
}
extension on WidgetTester {
Future<void> openPickerAndSelect<P, V>(String valueToSelect) async {
await openAnimatedPicker<P>();
await tapDescendantTextOf<DialogPicker<V>>(valueToSelect);
await tapSelectButton();
}
}
void _expectPickerTitle<T>(String title, {String? reason}) {
expect(find.descendant(of: find.byType(T), matching: find.text(title)), findsOneWidget, reason: reason);
}
void expectExposurePairsContainer(String fastest, String slowest) {
final pickerFinder = find.byType(ExtremeExposurePairsContainer);
expect(pickerFinder, findsOneWidget);
expect(find.descendant(of: pickerFinder, matching: find.text(S.current.fastestExposurePair)), findsOneWidget);
expect(find.descendant(of: pickerFinder, matching: find.text(fastest)), findsOneWidget);
expect(find.descendant(of: pickerFinder, matching: find.text(S.current.slowestExposurePair)), findsOneWidget);
expect(find.descendant(of: pickerFinder, matching: find.text(slowest)), findsOneWidget);
}
void expectMeasureButton(double ev) {
find.descendant(
of: find.byType(MeteringMeasureButton),
matching: find.text('${ev.toStringAsFixed(1)}\n${S.current.ev}'),
);
}

View file

@ -92,13 +92,34 @@ final mockEquipmentProfiles = [
IsoValue(3200, StopType.full), IsoValue(3200, StopType.full),
], ],
), ),
const EquipmentProfile( EquipmentProfile(
id: '2', id: '2',
name: 'Praktica + Jupiter', name: 'Praktica + Jupiter',
apertureValues: ApertureValue.values, apertureValues: ApertureValue.values.sublist(
ndValues: NdValue.values, ApertureValue.values.indexOf(const ApertureValue(3.5, StopType.third)),
shutterSpeedValues: ShutterSpeedValue.values, ApertureValue.values.indexOf(const ApertureValue(22, StopType.full)) + 1,
isoValues: IsoValue.values, ),
ndValues: const [
NdValue(0),
NdValue(2),
NdValue(4),
NdValue(8),
],
shutterSpeedValues: ShutterSpeedValue.values.sublist(
ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(1000, true, StopType.full)),
ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(16, false, StopType.full)) + 1,
),
isoValues: const [
IsoValue(50, StopType.full),
IsoValue(100, StopType.full),
IsoValue(200, StopType.full),
IsoValue(250, StopType.third),
IsoValue(400, StopType.full),
IsoValue(500, StopType.third),
IsoValue(800, StopType.full),
IsoValue(1600, StopType.full),
IsoValue(3200, StopType.full),
],
), ),
]; ];