Compare commits

...

4 commits

Author SHA1 Message Date
Vadim
a70ce5012a lints 2024-03-05 11:27:06 +01:00
Vadim
ecf3643ffe debug prints :) 2024-03-05 11:19:52 +01:00
Vadim
80f33d3b4d removed ipa signing for ios test 2024-03-05 10:49:19 +01:00
Vadim
7edd18bb41 combined all tests in one file 2024-03-05 10:42:05 +01:00
8 changed files with 213 additions and 244 deletions

View file

@ -65,64 +65,5 @@ jobs:
flutter analyze lib --fatal-infos flutter analyze lib --fatal-infos
run-integration-tests: run-integration-tests:
name: Run integration tests uses: ./.github/workflows/run_integration_tests.yml
timeout-minutes: 30 secrets: inherit
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,14 +7,20 @@ 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:
analyze_and_test: run-integration-tests:
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-11] os: [ubuntu-latest, macos-13]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -25,22 +31,30 @@ jobs:
id: override-iap id: override-iap
run: bash ./.github/scripts/stub_iap.sh run: bash ./.github/scripts/stub_iap.sh
- name: Restore constants.dart - name: Restore secrets
run: bash .github/scripts/restore_from_base64.sh "${{ secrets.CONSTANTS }}" "lib/constants.dart" 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 - uses: subosito/flutter-action@v2
with: with:
channel: "stable" channel: "stable"
flutter-version: "3.10.0" flutter-version: "3.10.0"
- name: Prepare flutter project - name: Build app
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
- name: Analyze project source if [ "${{ matrix.os }}" == "macos-13" ]
run: flutter analyze lib --fatal-infos then
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' }}
@ -56,14 +70,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 integration_test --flavor dev --dart-define cameraStubImage=assets/camera_stub_image.jpg script: flutter test $TARGET $BUILD_ARGS
- name: Launch iOS simulator - name: Launch iOS simulator
uses: futureware-tech/simulator-action@v3 uses: futureware-tech/simulator-action@v3
if: ${{ matrix.os == 'macos-11' }} if: ${{ matrix.os == 'macos-13' }}
with: with:
model: "iPhone 15" model: "iPhone 15 Pro"
- name: Run tests - name: Run tests
if: ${{ matrix.os == 'macos-11' }} if: ${{ matrix.os == 'macos-13' }}
run: flutter test integration_test --flavor dev --dart-define cameraStubImage=assets/camera_stub_image.jpg run: flutter test $TARGET $BUILD_ARGS

View file

@ -2,7 +2,6 @@ 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,6 +14,7 @@ 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,10 +22,12 @@ import 'mocks/paid_features_mock.dart';
const _mockPhotoEv100 = 8.3; const _mockPhotoEv100 = 8.3;
void main() { @isTestGroup
IntegrationTestWidgetsFlutterBinding.ensureInitialized(); void testToggleLayoutFeatures(String description) {
group(
void mockSharedPrefs() { description,
() {
setUp(() {
SharedPreferences.setMockInitialValues({ SharedPreferences.setMockInitialValues({
/// Metering values /// Metering values
UserPreferencesService.evSourceTypeKey: EvSourceType.camera.index, UserPreferencesService.evSourceTypeKey: EvSourceType.camera.index,
@ -37,14 +39,10 @@ void main() {
}.toJson(), }.toJson(),
), ),
}); });
}
setUp(() {
mockSharedPrefs();
}); });
testWidgets( testWidgets(
'Hide equipment profile picker', '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();
@ -71,14 +69,16 @@ void main() {
tester, tester,
'f/1.0', 'f/1.0',
'1/320', '1/320',
reason: 'Aperture and shutter speed ranges must be reset to default values when equipment profile is reset.', reason:
'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: 'Aperture and shutter speed ranges must be reset to default values when equipment profile is reset.', reason:
'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 main() {
); );
testWidgets( testWidgets(
'Hide extreme exposure pairs container', 'Extreme exposure pairs container',
(tester) async { (tester) async {
await tester.pumpApplication(); await tester.pumpApplication();
await tester.takePhoto(); await tester.takePhoto();
@ -112,14 +112,16 @@ void main() {
tester, tester,
'f/1.0', 'f/1.0',
'1/320', '1/320',
reason: 'Exposure pairs list must not be affected by the visibility of the extreme exposure pairs container.', reason:
'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: 'Exposure pairs list must not be affected by the visibility of the extreme exposure pairs container.', reason:
'Exposure pairs list must not be affected by the visibility of the extreme exposure pairs container.',
); );
// Enable layout feature // Enable layout feature
@ -127,13 +129,14 @@ void main() {
_expectExtremeExposurePairs( _expectExtremeExposurePairs(
'f/1.0 - 1/320', 'f/1.0 - 1/320',
'f/45 - 6"', 'f/45 - 6"',
reason: 'Exposure pairs list must not be affected by the visibility of the extreme exposure pairs container.', reason:
'Exposure pairs list must not be affected by the visibility of the extreme exposure pairs container.',
); );
}, },
); );
testWidgets( testWidgets(
'Hide film picker', 'Film picker',
(tester) async { (tester) async {
await tester.pumpApplication(selectedFilm: mockFilms.first); await tester.pumpApplication(selectedFilm: mockFilms.first);
await tester.takePhoto(); await tester.takePhoto();
@ -178,6 +181,8 @@ void main() {
); );
}, },
); );
},
);
} }
extension on WidgetTester { extension on WidgetTester {

View file

@ -2,7 +2,6 @@ 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';
@ -16,16 +15,17 @@ 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';
void main() { @isTest
IntegrationTestWidgetsFlutterBinding.ensureInitialized(); void testPurchases(String description) {
testWidgets(
void mockSharedPrefs() { description,
// ignore: invalid_use_of_visible_for_testing_member (tester) async {
SharedPreferences.setMockInitialValues({ SharedPreferences.setMockInitialValues({
/// Metering values /// Metering values
UserPreferencesService.evSourceTypeKey: EvSourceType.camera.index, UserPreferencesService.evSourceTypeKey: EvSourceType.camera.index,
@ -38,15 +38,7 @@ void main() {
}.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

@ -0,0 +1,11 @@
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,6 +50,8 @@ 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,7 +5,10 @@ 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,6 +52,7 @@ 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