| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 | import 'dart:async';import 'dart:io';import 'package:appflowy/startup/entry_point.dart';import 'package:appflowy/startup/startup.dart';import 'package:appflowy/user/presentation/presentation.dart';import 'package:appflowy/workspace/application/settings/prelude.dart';import 'package:flowy_infra/uuid.dart';import 'package:flowy_infra_ui/flowy_infra_ui.dart';import 'package:flutter/gestures.dart';import 'package:flutter/material.dart';import 'package:flutter/services.dart';import 'package:flutter_test/flutter_test.dart';import 'package:path/path.dart' as p;import 'package:path_provider/path_provider.dart';class FlowyTestContext {  FlowyTestContext({    required this.applicationDataDirectory,  });  final String applicationDataDirectory;}extension AppFlowyTestBase on WidgetTester {  Future<FlowyTestContext> initializeAppFlowy({    // use to append after the application data directory    String? pathExtension,    Size windowsSize = const Size(1600, 1200),  }) async {    binding.setSurfaceSize(windowsSize);    mockHotKeyManagerHandlers();    final directory = await mockApplicationDataStorage(      pathExtension: pathExtension,    );    WidgetsFlutterBinding.ensureInitialized();    await FlowyRunner.run(      FlowyApp(),      IntegrationMode.integrationTest,    );    await waitUntilSignInPageShow();    return FlowyTestContext(      applicationDataDirectory: directory,    );  }  void mockHotKeyManagerHandlers() {    TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger        .setMockMethodCallHandler(const MethodChannel('hotkey_manager'),            (MethodCall methodCall) async {      if (methodCall.method == 'unregisterAll') {        // do nothing      }      return;    });  }  Future<String> mockApplicationDataStorage({    // use to append after the application data directory    String? pathExtension,  }) async {    final dir = await getTemporaryDirectory();    // Use a random uuid to avoid conflict.    String path = p.join(dir.path, 'appflowy_integration_test', uuid());    if (pathExtension != null && pathExtension.isNotEmpty) {      path = '$path/$pathExtension';    }    final directory = Directory(path);    if (!directory.existsSync()) {      await directory.create(recursive: true);    }    MockApplicationDataStorage.initialPath = directory.path;    return directory.path;  }  Future<void> waitUntilSignInPageShow() async {    final finder = find.byType(GoButton);    await pumpUntilFound(finder);    expect(finder, findsOneWidget);  }  Future<void> pumpUntilFound(    Finder finder, {    Duration timeout = const Duration(seconds: 10),  }) async {    bool timerDone = false;    final timer = Timer(timeout, () => timerDone = true);    while (timerDone != true) {      await pump();      if (any(finder)) {        timerDone = true;      }    }    timer.cancel();  }  Future<void> tapButton(    Finder finder, {    int? pointer,    int buttons = kPrimaryButton,    bool warnIfMissed = false,    int milliseconds = 500,  }) async {    await tap(      finder,      buttons: buttons,      warnIfMissed: warnIfMissed,    );    await pumpAndSettle(Duration(milliseconds: milliseconds));  }  Future<void> tapButtonWithName(    String tr, {    int milliseconds = 500,  }) async {    Finder button = find.text(      tr,      findRichText: true,      skipOffstage: false,    );    if (button.evaluate().isEmpty) {      button = find.byWidgetPredicate(        (widget) => widget is FlowyText && widget.text == tr,      );    }    await tapButton(      button,      milliseconds: milliseconds,    );    return;  }  Future<void> tapButtonWithTooltip(    String tr, {    int milliseconds = 500,  }) async {    final button = find.byTooltip(tr);    await tapButton(      button,      milliseconds: milliseconds,    );    return;  }  Future<void> doubleTapAt(    Offset location, {    int? pointer,    int buttons = kPrimaryButton,    int milliseconds = 500,  }) async {    await tapAt(location, pointer: pointer, buttons: buttons);    await pump(kDoubleTapMinTime);    await tapAt(location, pointer: pointer, buttons: buttons);    await pumpAndSettle(Duration(milliseconds: milliseconds));  }  Future<void> doubleTapButton(    Finder finder, {    int? pointer,    int buttons = kPrimaryButton,    bool warnIfMissed = true,    int milliseconds = 500,  }) async {    await tap(      finder,      pointer: pointer,      buttons: buttons,      warnIfMissed: warnIfMissed,    );    await pump(kDoubleTapMinTime);    await tap(      finder,      buttons: buttons,      pointer: pointer,      warnIfMissed: warnIfMissed,    );    await pumpAndSettle(Duration(milliseconds: milliseconds));  }  Future<void> wait(int milliseconds) async {    await pumpAndSettle(Duration(milliseconds: milliseconds));    return;  }}extension AppFlowyFinderTestBase on CommonFinders {  Finder findTextInFlowyText(String text) {    return find.byWidgetPredicate(      (widget) => widget is FlowyText && widget.text == text,    );  }}
 |