Compare commits

..

No commits in common. "a70ce5012a22c507e0e9cae0545d98f9c52d1787" and "df32f6a30e9f04eb37ae5a9d4e8ff7ca9d284279" have entirely different histories.

8 changed files with 245 additions and 214 deletions

View file

@ -65,5 +65,64 @@ jobs:
flutter analyze lib --fatal-infos flutter analyze lib --fatal-infos
run-integration-tests: run-integration-tests:
uses: ./.github/workflows/run_integration_tests.yml name: Run integration tests
secrets: inherit timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-13]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Override iap package with stub
id: override-iap
run: bash ./.github/scripts/stub_iap.sh
- name: Restore secrets
run: |
bash .github/scripts/restore_from_base64.sh "${{ secrets.CONSTANTS }}" "lib/constants.dart"
bash .github/scripts/restore_from_base64.sh "${{ secrets.GOOGLE_SERVICES_JSON_ANDROID }}" "android/app/google-services.json"
bash .github/scripts/restore_from_base64.sh "${{ secrets.GOOGLE_SERVICES_JSON_IOS }}" "ios/Runner/GoogleService-Info.plist"
- uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version: "3.10.0"
- name: Prepare flutter project
run: |
flutter --version
flutter pub get
flutter pub run intl_utils:generate
- name: Analyze project source
run: flutter analyze lib --fatal-infos
- name: Enable KVM
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Launch Android simulator & Run tests
if: ${{ matrix.os == 'ubuntu-latest' }}
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 33
target: default
arch: x86_64
profile: pixel_6
script: flutter test integration_test --flavor dev --dart-define cameraStubImage=assets/camera_stub_image.jpg
- name: Launch iOS simulator
uses: futureware-tech/simulator-action@v3
if: ${{ matrix.os == 'macos-13' }}
with:
model: "iPhone 15 Pro"
- name: Run tests
if: ${{ matrix.os == 'macos-13' }}
run: flutter test integration_test --flavor dev --dart-define cameraStubImage=assets/camera_stub_image.jpg

View file

@ -7,20 +7,14 @@ name: Run integration tests
on: on:
workflow_dispatch: workflow_dispatch:
workflow_call:
env:
BUILD_ARGS: --flavor dev --dart-define cameraStubImage=assets/camera_stub_image.jpg
TARGET: integration_test/run_all_tests.dart
jobs: jobs:
run-integration-tests: analyze_and_test:
name: Run integration tests name: Run integration tests
timeout-minutes: 30 timeout-minutes: 30
strategy: strategy:
fail-fast: false
matrix: matrix:
os: [ubuntu-latest, macos-13] os: [ubuntu-latest, macos-11]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -31,30 +25,22 @@ jobs:
id: override-iap id: override-iap
run: bash ./.github/scripts/stub_iap.sh run: bash ./.github/scripts/stub_iap.sh
- name: Restore secrets - name: Restore constants.dart
run: | run: bash .github/scripts/restore_from_base64.sh "${{ secrets.CONSTANTS }}" "lib/constants.dart"
bash .github/scripts/restore_from_base64.sh "${{ secrets.CONSTANTS }}" "lib/constants.dart"
bash .github/scripts/restore_from_base64.sh "${{ secrets.GOOGLE_SERVICES_JSON_ANDROID }}" "android/app/google-services.json"
bash .github/scripts/restore_from_base64.sh "${{ secrets.GOOGLE_SERVICES_JSON_IOS }}" "ios/Runner/GoogleService-Info.plist"
- uses: subosito/flutter-action@v2 - uses: subosito/flutter-action@v2
with: with:
channel: "stable" channel: "stable"
flutter-version: "3.10.0" flutter-version: "3.10.0"
- name: Build app - name: Prepare flutter project
run: | run: |
flutter --version flutter --version
flutter pub get flutter pub get
flutter pub run intl_utils:generate flutter pub run intl_utils:generate
flutter analyze lib --fatal-infos
if [ "${{ matrix.os }}" == "macos-13" ] - name: Analyze project source
then run: flutter analyze lib --fatal-infos
cd ios
pod install
cd ..
fi
flutter build ${{ matrix.os == 'ubuntu-latest' && 'apk --debug' || 'ios --no-codesign --simulator --debug' }} $BUILD_ARGS -t $TARGET
- name: Enable KVM - name: Enable KVM
if: ${{ matrix.os == 'ubuntu-latest' }} if: ${{ matrix.os == 'ubuntu-latest' }}
@ -70,14 +56,14 @@ jobs:
api-level: 33 api-level: 33
target: default target: default
arch: x86_64 arch: x86_64
profile: pixel_6 profile: Pixel 6
script: flutter test $TARGET $BUILD_ARGS script: flutter test integration_test --flavor dev --dart-define cameraStubImage=assets/camera_stub_image.jpg
- name: Launch iOS simulator - name: Launch iOS simulator
uses: futureware-tech/simulator-action@v3 uses: futureware-tech/simulator-action@v3
if: ${{ matrix.os == 'macos-13' }} if: ${{ matrix.os == 'macos-11' }}
with: with:
model: "iPhone 15 Pro" model: "iPhone 15"
- name: Run tests - name: Run tests
if: ${{ matrix.os == 'macos-13' }} if: ${{ matrix.os == 'macos-11' }}
run: flutter test $TARGET $BUILD_ARGS run: flutter test integration_test --flavor dev --dart-define cameraStubImage=assets/camera_stub_image.jpg

View file

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:lightmeter/data/models/ev_source_type.dart'; import 'package:lightmeter/data/models/ev_source_type.dart';
import 'package:lightmeter/data/models/metering_screen_layout_config.dart'; import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:lightmeter/data/shared_prefs_service.dart'; import 'package:lightmeter/data/shared_prefs_service.dart';
@ -14,7 +15,6 @@ import 'package:lightmeter/screens/metering/components/shared/readings_container
import 'package:lightmeter/screens/metering/screen_metering.dart'; import 'package:lightmeter/screens/metering/screen_metering.dart';
import 'package:lightmeter/screens/settings/screen_settings.dart'; import 'package:lightmeter/screens/settings/screen_settings.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
import 'package:meta/meta.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import '../integration_test/utils/widget_tester_actions.dart'; import '../integration_test/utils/widget_tester_actions.dart';
@ -22,12 +22,10 @@ import 'mocks/paid_features_mock.dart';
const _mockPhotoEv100 = 8.3; const _mockPhotoEv100 = 8.3;
@isTestGroup void main() {
void testToggleLayoutFeatures(String description) { IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group(
description, void mockSharedPrefs() {
() {
setUp(() {
SharedPreferences.setMockInitialValues({ SharedPreferences.setMockInitialValues({
/// Metering values /// Metering values
UserPreferencesService.evSourceTypeKey: EvSourceType.camera.index, UserPreferencesService.evSourceTypeKey: EvSourceType.camera.index,
@ -39,10 +37,14 @@ void testToggleLayoutFeatures(String description) {
}.toJson(), }.toJson(),
), ),
}); });
}
setUp(() {
mockSharedPrefs();
}); });
testWidgets( testWidgets(
'Equipment profile picker', 'Hide equipment profile picker',
(tester) async { (tester) async {
await tester.pumpApplication(selectedEquipmentProfileId: mockEquipmentProfiles.first.id); await tester.pumpApplication(selectedEquipmentProfileId: mockEquipmentProfiles.first.id);
await tester.takePhoto(); await tester.takePhoto();
@ -69,16 +71,14 @@ void testToggleLayoutFeatures(String description) {
tester, tester,
'f/1.0', 'f/1.0',
'1/320', '1/320',
reason: reason: 'Aperture and shutter speed ranges must be reset to default values when equipment profile is reset.',
'Aperture and shutter speed ranges must be reset to default values when equipment profile is reset.',
); );
await tester.scrollToTheLastExposurePair(); await tester.scrollToTheLastExposurePair();
_expectExposurePairsListItem( _expectExposurePairsListItem(
tester, tester,
'f/45', 'f/45',
'6"', '6"',
reason: reason: 'Aperture and shutter speed ranges must be reset to default values when equipment profile is reset.',
'Aperture and shutter speed ranges must be reset to default values when equipment profile is reset.',
); );
// Enable layout feature // Enable layout feature
@ -91,7 +91,7 @@ void testToggleLayoutFeatures(String description) {
); );
testWidgets( testWidgets(
'Extreme exposure pairs container', 'Hide extreme exposure pairs container',
(tester) async { (tester) async {
await tester.pumpApplication(); await tester.pumpApplication();
await tester.takePhoto(); await tester.takePhoto();
@ -112,16 +112,14 @@ void testToggleLayoutFeatures(String description) {
tester, tester,
'f/1.0', 'f/1.0',
'1/320', '1/320',
reason: reason: 'Exposure pairs list must not be affected by the visibility of the extreme exposure pairs container.',
'Exposure pairs list must not be affected by the visibility of the extreme exposure pairs container.',
); );
await tester.scrollToTheLastExposurePair(); await tester.scrollToTheLastExposurePair();
_expectExposurePairsListItem( _expectExposurePairsListItem(
tester, tester,
'f/45', 'f/45',
'6"', '6"',
reason: reason: 'Exposure pairs list must not be affected by the visibility of the extreme exposure pairs container.',
'Exposure pairs list must not be affected by the visibility of the extreme exposure pairs container.',
); );
// Enable layout feature // Enable layout feature
@ -129,14 +127,13 @@ void testToggleLayoutFeatures(String description) {
_expectExtremeExposurePairs( _expectExtremeExposurePairs(
'f/1.0 - 1/320', 'f/1.0 - 1/320',
'f/45 - 6"', 'f/45 - 6"',
reason: reason: 'Exposure pairs list must not be affected by the visibility of the extreme exposure pairs container.',
'Exposure pairs list must not be affected by the visibility of the extreme exposure pairs container.',
); );
}, },
); );
testWidgets( testWidgets(
'Film picker', 'Hide film picker',
(tester) async { (tester) async {
await tester.pumpApplication(selectedFilm: mockFilms.first); await tester.pumpApplication(selectedFilm: mockFilms.first);
await tester.takePhoto(); await tester.takePhoto();
@ -181,8 +178,6 @@ void testToggleLayoutFeatures(String description) {
); );
}, },
); );
},
);
} }
extension on WidgetTester { extension on WidgetTester {

View file

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:lightmeter/data/models/ev_source_type.dart'; import 'package:lightmeter/data/models/ev_source_type.dart';
import 'package:lightmeter/data/models/metering_screen_layout_config.dart'; import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
import 'package:lightmeter/data/shared_prefs_service.dart'; import 'package:lightmeter/data/shared_prefs_service.dart';
@ -15,17 +16,16 @@ import 'package:lightmeter/screens/metering/components/shared/readings_container
import 'package:lightmeter/screens/settings/components/shared/disable/widget_disable.dart'; import 'package:lightmeter/screens/settings/components/shared/disable/widget_disable.dart';
import 'package:lightmeter/screens/settings/screen_settings.dart'; import 'package:lightmeter/screens/settings/screen_settings.dart';
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
import 'package:meta/meta.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import '../integration_test/utils/widget_tester_actions.dart'; import '../integration_test/utils/widget_tester_actions.dart';
import 'mocks/iap_products_mock.dart'; import 'mocks/iap_products_mock.dart';
@isTest void main() {
void testPurchases(String description) { IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets(
description, void mockSharedPrefs() {
(tester) async { // ignore: invalid_use_of_visible_for_testing_member
SharedPreferences.setMockInitialValues({ SharedPreferences.setMockInitialValues({
/// Metering values /// Metering values
UserPreferencesService.evSourceTypeKey: EvSourceType.camera.index, UserPreferencesService.evSourceTypeKey: EvSourceType.camera.index,
@ -38,7 +38,15 @@ void testPurchases(String description) {
}.toJson(), }.toJson(),
), ),
}); });
}
setUpAll(() {
mockSharedPrefs();
});
testWidgets(
'Purchase & refund premium features',
(tester) async {
await tester.pumpApplication(productStatus: IAPProductStatus.purchasable); await tester.pumpApplication(productStatus: IAPProductStatus.purchasable);
await tester.takePhoto(); await tester.takePhoto();

View file

@ -1,11 +0,0 @@
import 'package:integration_test/integration_test.dart';
import 'metering_screen_layout_test.dart';
import 'purchases_test.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testPurchases('Purchase & refund premium features');
testToggleLayoutFeatures('Toggle metering screen layout features');
}

View file

@ -50,8 +50,6 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
communicationBloc, communicationBloc,
const CameraInitState(), const CameraInitState(),
) { ) {
// ignore: avoid_print
print('CameraContainerBloc');
_observer = _WidgetsBindingObserver(_appLifecycleStateObserver); _observer = _WidgetsBindingObserver(_appLifecycleStateObserver);
WidgetsBinding.instance.addObserver(_observer); WidgetsBinding.instance.addObserver(_observer);

View file

@ -5,10 +5,7 @@ class MockCameraContainerBloc extends CameraContainerBloc {
super._meteringInteractor, super._meteringInteractor,
super.communicationBloc, super.communicationBloc,
super._analytics, super._analytics,
) { );
// ignore: avoid_print
print('MockCameraContainerBloc');
}
@override @override
Future<void> _onRequestPermission(_, Emitter emit) async { Future<void> _onRequestPermission(_, Emitter emit) async {

View file

@ -52,7 +52,6 @@ dev_dependencies:
integration_test: integration_test:
sdk: flutter sdk: flutter
lint: 2.1.2 lint: 2.1.2
meta: 1.9.1
mocktail: 0.3.0 mocktail: 0.3.0
test: 1.24.1 test: 1.24.1