diff --git a/Makefile b/Makefile index 4c56e2c..fa652bc 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,10 @@ -fix: - dart fix --apply lib +run_integration_test rit: + flutter run -t integration_test/hello_test.dart fmt: - dart format lib + dart fix --apply lib + dart fix --apply integration_test + dart format lib integration_test build-runner-watch watch: # flutter pub run build_runner build -d -v @@ -36,8 +38,3 @@ cloc: run-web: CHROME_EXECUTABLE="./scripts/google-chrome-unsafe.sh" flutter run -d chrome - -integration_test it: - flutter drive \ - --driver=test_driver/integration_test.dart \ - --target=integration_test/hello_test.dart \ No newline at end of file diff --git a/integration_test/hello_test.dart b/integration_test/hello_test.dart index 55469c1..d0bc005 100644 --- a/integration_test/hello_test.dart +++ b/integration_test/hello_test.dart @@ -1,10 +1,60 @@ +import 'dart:io'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import 'package:nocodb/main.dart'; + +// https://github.com/flutter/flutter/issues/88765#issuecomment-1113140289 +Future waitFor( + final WidgetTester tester, + final Finder finder, { + final Duration timeout = const Duration(seconds: 20), +}) async { + final end = DateTime.now().add(timeout); + + do { + if (DateTime.now().isAfter(end)) { + throw Exception('Timed out waiting for $finder'); + } + + await tester.pumpAndSettle(); + await Future.delayed(const Duration(milliseconds: 100)); + } while (finder.evaluate().isEmpty); +} void main() { + HttpOverrides.global = null; IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - testWidgets('failing test example', (WidgetTester tester) async { - expect(2 + 2, equals(5)); + testWidgets('sign in', (final WidgetTester tester) async { + await tester.pumpWidget( + const ProviderScope( + child: App(), + ), + ); + await waitFor(tester, find.text('SIGN IN')); + + await tester.enterText( + find.byKey(const ValueKey('email')), + 'enm10k@gmail.com', + ); + await tester.enterText( + find.byKey(const ValueKey('password')), + 'hogehoge', + ); + await tester.enterText( + find.byKey(const ValueKey('endpoint')), + 'http://10.0.2.2:8080', + ); + await tester.tap( + find.byKey(const ValueKey('sign_in_button')), + ); + + await tester.pumpAndSettle(); + + await waitFor(tester, find.text('Projects')); + // expect(2 + 2, equals(5)); }); -} \ No newline at end of file +} diff --git a/lib/features/core/components/dialog/fields_dialog.dart b/lib/features/core/components/dialog/fields_dialog.dart index 6983424..7987bf7 100644 --- a/lib/features/core/components/dialog/fields_dialog.dart +++ b/lib/features/core/components/dialog/fields_dialog.dart @@ -156,9 +156,7 @@ class FieldsDialog extends HookConsumerWidget { ), InkWell( onTap: () { - ref - .read(viewProvider.notifier) - .showSystemFields(); + ref.read(viewProvider.notifier).showSystemFields(); }, child: Row( children: [ diff --git a/lib/features/core/providers/providers.dart b/lib/features/core/providers/providers.dart index d19d9c1..ef543e0 100644 --- a/lib/features/core/providers/providers.dart +++ b/lib/features/core/providers/providers.dart @@ -60,7 +60,8 @@ class View extends _$View { data: { 'show_system_fields': !state!.showSystemFields, }, - ), serializer: (final ok) => state = ok, + ), + serializer: (final ok) => state = ok, ); } diff --git a/lib/features/sign_in/pages/sign_in.dart b/lib/features/sign_in/pages/sign_in.dart index 6531458..91c16f6 100644 --- a/lib/features/sign_in/pages/sign_in.dart +++ b/lib/features/sign_in/pages/sign_in.dart @@ -62,6 +62,7 @@ class SignInPage extends HookConsumerWidget { child: Column( children: [ TextField( + key: const ValueKey('email'), autofillHints: const [ AutofillHints.email, AutofillHints.username, @@ -72,6 +73,7 @@ class SignInPage extends HookConsumerWidget { ), ), TextField( + key: const ValueKey('password'), autofillHints: const [ AutofillHints.password, ], @@ -92,9 +94,10 @@ class SignInPage extends HookConsumerWidget { obscureText: !showPassword.value, ), TextField( + key: const ValueKey('endpoint'), onChanged: (final value) { EasyDebounce.debounce( - 'sign_in_password', + 'api_endpoint', const Duration(seconds: 1), () async { await api @@ -138,6 +141,7 @@ class SignInPage extends HookConsumerWidget { ), actions: [ TextButton( + key: const ValueKey('sign_in_button'), child: const Text('SIGN IN'), onPressed: () async { api.init(apiUrlController.text); diff --git a/lib/main.dart b/lib/main.dart index da55535..c233ca0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -30,7 +30,6 @@ void main() async { return stack; }; - // WidgetsFlutterBinding.ensureInitialized(); runApp( const ProviderScope( child: App(), diff --git a/scripts/run_android_emulator.sh b/scripts/run_android_emulator.sh new file mode 100755 index 0000000..a5b13f8 --- /dev/null +++ b/scripts/run_android_emulator.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +cd ~/Library/Android/sdk/emulator +./emulator -avd $(emulator -list-avds | head -n 1) & + diff --git a/test_driver/integration_test.dart b/test_driver/integration_test.dart deleted file mode 100644 index 6854dea..0000000 --- a/test_driver/integration_test.dart +++ /dev/null @@ -1,3 +0,0 @@ -import 'package:integration_test/integration_test_driver.dart'; - -Future main() => integrationDriver(); \ No newline at end of file