import 'dart:developer'; import 'package:fluffychat/pages/chat_list/chat_list_body.dart'; import 'package:fluffychat/pages/homeserver_picker/homeserver_picker.dart'; import 'package:fluffychat/pages/settings_account/settings_account_view.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import '../users.dart'; import 'wait_for.dart'; extension DefaultFlowExtensions on WidgetTester { Future login() async { final tester = this; await tester.pumpAndSettle(); await tester.waitFor(find.text('Let\'s start')); expect(find.text('Let\'s start'), findsOneWidget); final input = find.byType(TextField); expect(input, findsOneWidget); // getting the placeholder in place await tester.tap(find.byIcon(Icons.search)); await tester.pumpAndSettle(); await tester.enterText(input, homeserver); await tester.pumpAndSettle(); await tester.testTextInput.receiveAction(TextInputAction.done); await tester.pumpAndSettle(); // in case registration is allowed // try { await Future.delayed(const Duration(milliseconds: 50)); await tester.scrollUntilVisible( find.text('Login'), 500, scrollable: find.descendant( of: find.byKey(const Key('ConnectPageListView')), matching: find.byType(Scrollable).first, ), ); await tester.pumpAndSettle(); await tester.tap(find.text('Login')); await tester.pumpAndSettle(); /*} catch (e) { log('Registration is not allowed. Proceeding with login...'); }*/ await tester.pumpAndSettle(); await Future.delayed(const Duration(milliseconds: 50)); final inputs = find.byType(TextField); await tester.enterText(inputs.first, Users.user1.name); await tester.enterText(inputs.last, Users.user1.password); await tester.pumpAndSettle(); await tester.testTextInput.receiveAction(TextInputAction.done); try { // pumpAndSettle does not work in here as setState is called // asynchronously await tester.waitFor( find.byType(LinearProgressIndicator), timeout: const Duration(milliseconds: 1500), skipPumpAndSettle: true, ); } catch (_) { // in case the input action does not work on the desired platform if (find.text('Login').evaluate().isNotEmpty) { await tester.tap(find.text('Login')); } } try { await tester.pumpAndSettle(); } catch (_) { // may fail because of ongoing animation below dialog } await tester.waitFor( find.byType(ChatListViewBody), skipPumpAndSettle: true, ); } /// ensure PushProvider check passes Future acceptPushWarning() async { final tester = this; final matcher = find.maybeUppercaseText('Do not show again'); try { await tester.waitFor(matcher, timeout: const Duration(seconds: 5)); // the FCM push error dialog to be handled... await tester.tap(matcher); await tester.pumpAndSettle(); } catch (_) {} } Future ensureLoggedOut() async { final tester = this; await tester.pumpAndSettle(); if (find.byType(ChatListViewBody).evaluate().isNotEmpty) { await tester.tap(find.byTooltip('Show menu')); await tester.pumpAndSettle(); await tester.tap(find.text('Settings')); await tester.pumpAndSettle(); await tester.scrollUntilVisible( find.text('Account'), 500, scrollable: find.descendant( of: find.byKey(const Key('SettingsListViewContent')), matching: find.byType(Scrollable), ), ); await tester.pumpAndSettle(); await tester.tap(find.text('Account')); await tester.pumpAndSettle(); await tester.scrollUntilVisible( find.text('Logout'), 500, scrollable: find.descendant( of: find.byType(SettingsAccountView), matching: find.byType(Scrollable), ), ); await tester.pumpAndSettle(); await tester.tap(find.text('Logout')); await tester.pumpAndSettle(); await tester.tap(find.maybeUppercaseText('Yes')); await tester.pumpAndSettle(); } } Future ensureAppStartedHomescreen({ Duration timeout = const Duration(seconds: 20), }) async { final tester = this; await tester.pumpAndSettle(); final homeserverPickerFinder = find.byType(HomeserverPicker); final chatListFinder = find.byType(ChatListViewBody); final end = DateTime.now().add(timeout); log( 'Waiting for HomeserverPicker or ChatListViewBody...', name: 'Test Runner', ); do { if (DateTime.now().isAfter(end)) { throw Exception( 'Timed out waiting for HomeserverPicker or ChatListViewBody'); } await pumpAndSettle(); await Future.delayed(const Duration(milliseconds: 100)); } while (homeserverPickerFinder.evaluate().isEmpty && chatListFinder.evaluate().isEmpty); if (homeserverPickerFinder.evaluate().isNotEmpty) { log( 'Found HomeserverPicker, performing login.', name: 'Test Runner', ); await tester.login(); } else { log( 'Found ChatListViewBody, skipping login.', name: 'Test Runner', ); } await tester.acceptPushWarning(); } }