diff --git a/.vscode/launch.json b/.vscode/launch.json index 165b107..13bf9aa 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -78,6 +78,32 @@ ], "program": "lib/main_dev.dart" }, + { + "name": "convenient_test_android", + "request": "launch", + "type": "dart", + "codeLens": { + "for": [ + "run-file", + "debug-file" + ], + "path": "conv_test", + "title": "${debugType} Conv Test" + }, + "args": [ + "--flavor", + "dev", + "--disable-service-auth-codes", + "--dart-define", + "CONVENIENT_TEST_MANAGER_HOST=10.0.2.2", + "--dart-define", + "CONVENIENT_TEST_APP_CODE_DIR=lib/main_dev.dart -d 'emulator-5554'", + ], + "vmAdditionalArgs": [ + "--host-vmservice-port=9753", + ], + "program": "conv_test/main_test.dart", + }, { "name": "dev Profile", "request": "launch", diff --git a/Makefile b/Makefile index 0978015..81261f5 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,10 @@ run-stage-profile: run-prod-profile: flutter run --profile --flavor prod -t lib/main_prod.dart +# Convinient Test Android +test-convenient-android: + flutter run conv_test/main_test.dart --flavor dev --host-vmservice-port 9753 --disable-service-auth-codes --dart-define CONVENIENT_TEST_MANAGER_HOST=10.0.2.2 --dart-define CONVENIENT_TEST_APP_CODE_DIR=$PWD -d "emulator-5554" + # Release Builds run-dev-release: flutter run --release --flavor dev -t lib/main_dev.dart diff --git a/conv_test/main_test.dart b/conv_test/main_test.dart new file mode 100644 index 0000000..7f6343f --- /dev/null +++ b/conv_test/main_test.dart @@ -0,0 +1,77 @@ +import 'package:convenient_test_dev/convenient_test_dev.dart'; +import 'package:convenient_test_dev/src/support/get_it.dart'; +import 'package:counter_workshop/main.dart' as main_app; +import 'package:counter_workshop/src/core/routing/router.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:go_router/go_router.dart'; + +void main() { + convenientTestMain(MyConvenientTestSlot(), () { + group('add überstunden', () { + tTestWidgets('Open Überstunden', (t) async { + await find.text('Überstunden').should(findsOneWidget); + await find.text('Überstunden').tap(); + await t.get('counter_text_Überstunden').should(findsOneWidget); + await find.byIcon(Icons.add).should(findsOneWidget); + await find.byIcon(Icons.add).tap(); + await find.byIcon(Icons.add).tap(); + await find.byIcon(Icons.add).tap(); + await find.textContaining('24').should(findsOneWidget); + await t.pageBack(); + await find.text('Überstunden').should(findsOneWidget); + await find.textContaining('24').should(findsOneWidget); + }); + }); + + group('open settings', () { + tTestWidgets('Open Settings Check English', (t) async { + await find.byIcon(Icons.settings).should(findsOneWidget); + await find.byIcon(Icons.settings).tap(); + await find.text('German').should(findsOneWidget); + await find.text('German').tap(); + await find.text('Deutsch').should(findsOneWidget); + await find.text('German').should(findsNothing); + }); + }); + + group('open add dialog', () { + tTestWidgets('should open page', (t) async { + await t.goRouteCommand('counters'); + await find.byIcon(Icons.add).should(findsOneWidget); + await find.byIcon(Icons.add).tap(); + }); + }); + + group('my custom test group', () { + tTestWidgets('calling custom method', (t) async { + await t.myCustomCommand(); + }); + }); + }); +} + +class MyConvenientTestSlot extends ConvenientTestSlot { + @override + Future appMain(AppMainExecuteMode mode) async => main_app.main(); + + @override + BuildContext? getNavContext(ConvenientTest t) { + return router.routerDelegate.navigatorKey.currentContext!; + } +} + +extension on ConvenientTest { + Future myCustomCommand() async { + // Do anything you like... This is just a normal function + debugPrint('Hello, world!'); + } + + Future goRouteCommand(name) async { + await pump(); + // If await, will wait forever until the page is popped - surely we do not want that + // ignore: use_build_context_synchronously + myGetIt.get().getNavContext(this)!.goNamed(name); + await pumpAndSettle(); + } +} diff --git a/lib/src/app.dart b/lib/src/app.dart index 8e2e96c..aa2b6f0 100644 --- a/lib/src/app.dart +++ b/lib/src/app.dart @@ -1,3 +1,4 @@ +import 'package:convenient_test/convenient_test.dart'; import 'package:counter_workshop/flavors.dart'; import 'package:counter_workshop/src/core/routing/router.dart'; import 'package:counter_workshop/src/core/theme/app.theme.dart'; @@ -67,18 +68,20 @@ class AppView extends StatelessWidget { @override Widget build(BuildContext context) { final appTheme = AppTheme(); - return MaterialApp.router( - title: F.title, - locale: locale, - theme: appTheme.light, - darkTheme: appTheme.dark, - themeMode: ThemeMode.system, - debugShowCheckedModeBanner: false, - routeInformationProvider: router.routeInformationProvider, - routeInformationParser: router.routeInformationParser, - routerDelegate: router.routerDelegate, - localizationsDelegates: AppLocalizations.localizationsDelegates, - supportedLocales: AppLocalizations.supportedLocales, + return ConvenientTestWrapperWidget( + child: MaterialApp.router( + title: F.title, + locale: locale, + theme: appTheme.light, + darkTheme: appTheme.dark, + themeMode: ThemeMode.system, + debugShowCheckedModeBanner: false, + routeInformationProvider: router.routeInformationProvider, + routeInformationParser: router.routeInformationParser, + routerDelegate: router.routerDelegate, + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, + ), ); } } diff --git a/lib/src/core/routing/router.dart b/lib/src/core/routing/router.dart index 46d5e82..a13430a 100644 --- a/lib/src/core/routing/router.dart +++ b/lib/src/core/routing/router.dart @@ -10,6 +10,7 @@ final router = GoRouter( initialLocation: '/counters', routes: [ GoRoute( + name: 'counters', path: '/counters', builder: (context, state) => const DashboardPage(), routes: [ diff --git a/lib/src/features/counter/presentation/edit/view/edit_counter.page.dart b/lib/src/features/counter/presentation/edit/view/edit_counter.page.dart index f383c64..aa0d480 100644 --- a/lib/src/features/counter/presentation/edit/view/edit_counter.page.dart +++ b/lib/src/features/counter/presentation/edit/view/edit_counter.page.dart @@ -78,7 +78,10 @@ class CounterView extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - CounterText(counterValue: state.counterModel.value), + CounterText( + counterValue: state.counterModel.value, + counterName: state.counterModel.name, + ), Text(state.counterModel.name, style: theme.textTheme.caption), ], ), diff --git a/lib/src/features/counter/presentation/edit/view/widgets/counter_text.widget.dart b/lib/src/features/counter/presentation/edit/view/widgets/counter_text.widget.dart index fba6ef6..11b9572 100644 --- a/lib/src/features/counter/presentation/edit/view/widgets/counter_text.widget.dart +++ b/lib/src/features/counter/presentation/edit/view/widgets/counter_text.widget.dart @@ -1,15 +1,24 @@ +import 'package:convenient_test/convenient_test.dart'; import 'package:flutter/material.dart'; class CounterText extends StatelessWidget { - const CounterText({super.key, required this.counterValue}); + const CounterText({ + super.key, + required this.counterValue, + required this.counterName, + }); final int counterValue; + final String counterName; @override Widget build(BuildContext context) { final theme = Theme.of(context); - return Text( - '$counterValue', - style: theme.textTheme.headlineLarge, + return Mark( + name: 'counter_text_$counterName', + child: Text( + '$counterValue', + style: theme.textTheme.headlineLarge, + ), ); } } diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index cccf817..0d56f51 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,6 +5,8 @@ import FlutterMacOS import Foundation +import path_provider_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 068a6ec..504f9b7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -16,14 +16,14 @@ packages: source: hosted version: "4.7.0" archive: - dependency: transitive + dependency: "direct overridden" description: name: archive url: "https://pub.dartlang.org" source: hosted version: "3.3.1" args: - dependency: transitive + dependency: "direct overridden" description: name: args url: "https://pub.dartlang.org" @@ -148,6 +148,34 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.16.0" + convenient_test: + dependency: "direct main" + description: + name: convenient_test + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + convenient_test_common: + dependency: transitive + description: + name: convenient_test_common + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + convenient_test_common_dart: + dependency: transitive + description: + name: convenient_test_common_dart + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + convenient_test_dev: + dependency: "direct dev" + description: + name: convenient_test_dev + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" convert: dependency: transitive description: @@ -204,13 +232,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" file: dependency: transitive description: name: file url: "https://pub.dartlang.org" source: hosted - version: "6.1.4" + version: "6.1.2" fixnum: dependency: transitive description: @@ -230,6 +265,11 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "8.1.1" + flutter_driver: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" flutter_flavorizr: dependency: "direct dev" description: @@ -273,6 +313,13 @@ packages: description: flutter source: sdk version: "0.0.0" + freezed_annotation: + dependency: transitive + description: + name: freezed_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" frontend_server_client: dependency: transitive description: @@ -280,6 +327,18 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.3" + fuchsia_remote_debug_protocol: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + get_it: + dependency: transitive + description: + name: get_it + url: "https://pub.dartlang.org" + source: hosted + version: "7.2.0" glob: dependency: transitive description: @@ -294,6 +353,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.4.1" + googleapis_auth: + dependency: transitive + description: + name: googleapis_auth + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" graphs: dependency: transitive description: @@ -301,6 +367,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + grpc: + dependency: transitive + description: + name: grpc + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" html: dependency: transitive description: @@ -315,6 +388,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.13.5" + http2: + dependency: transitive + description: + name: http2 + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" http_multi_server: dependency: transitive description: @@ -336,6 +416,11 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.2.0" + integration_test: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" intl: dependency: "direct main" description: @@ -420,6 +505,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" + mobx: + dependency: transitive + description: + name: mobx + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" nested: dependency: transitive description: @@ -441,6 +533,55 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.2" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.20" + path_provider_ios: + dependency: transitive + description: + name: path_provider_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.7" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" petitparser: dependency: transitive description: @@ -448,6 +589,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.0.0" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" pool: dependency: transitive description: @@ -455,6 +610,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.5.1" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.4" + protobuf: + dependency: transitive + description: + name: protobuf + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" provider: dependency: transitive description: @@ -476,6 +645,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.1" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + recase: + dependency: transitive + description: + name: recase + url: "https://pub.dartlang.org" + source: hosted + version: "4.1.0" shelf: dependency: transitive description: @@ -537,6 +720,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.1" + sync_http: + dependency: transitive + description: + name: sync_http + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.1" term_glyph: dependency: transitive description: @@ -558,6 +748,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + tuple: + dependency: transitive + description: + name: tuple + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" typed_data: dependency: transitive description: @@ -579,6 +776,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.2" + vm_service: + dependency: transitive + description: + name: vm_service + url: "https://pub.dartlang.org" + source: hosted + version: "9.0.0" watcher: dependency: transitive description: @@ -593,6 +797,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.2.0" + webdriver: + dependency: transitive + description: + name: webdriver + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0+2" xml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 304ce75..33f22f8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,6 +21,11 @@ dependencies: go_router: ^4.4.1 logging: ^1.0.2 logging_appenders: ^1.0.0 + convenient_test: ^1.2.0 + +dependency_overrides: + args: ^2.1.1 + archive: 3.3.1 dev_dependencies: flutter_test: @@ -31,6 +36,7 @@ dev_dependencies: flutter_launcher_icons: ^0.10.0 flutter_native_splash: ^2.2.8 flutter_flavorizr: ^2.1.4 + convenient_test_dev: ^1.2.0 flavorizr: ide: "vscode"