base.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. import 'dart:io';
  2. import 'package:appflowy/startup/entry_point.dart';
  3. import 'package:appflowy/startup/startup.dart';
  4. import 'package:appflowy/workspace/application/settings/prelude.dart';
  5. import 'package:flowy_infra/uuid.dart';
  6. import 'package:flowy_infra_ui/flowy_infra_ui.dart';
  7. import 'package:flutter/gestures.dart';
  8. import 'package:flutter/material.dart';
  9. import 'package:flutter/services.dart';
  10. import 'package:flutter_test/flutter_test.dart';
  11. import 'package:path_provider/path_provider.dart';
  12. import 'package:path/path.dart' as p;
  13. class FlowyTestContext {
  14. FlowyTestContext({
  15. required this.applicationDataDirectory,
  16. });
  17. final String applicationDataDirectory;
  18. }
  19. extension AppFlowyTestBase on WidgetTester {
  20. Future<FlowyTestContext> initializeAppFlowy({
  21. // use to append after the application data directory
  22. String? pathExtension,
  23. Size windowsSize = const Size(1600, 1200),
  24. }) async {
  25. binding.setSurfaceSize(windowsSize);
  26. mockHotKeyManagerHandlers();
  27. final directory = await mockApplicationDataStorage(
  28. pathExtension: pathExtension,
  29. );
  30. WidgetsFlutterBinding.ensureInitialized();
  31. await FlowyRunner.run(
  32. FlowyApp(),
  33. IntegrationMode.integrationTest,
  34. );
  35. await wait(3000);
  36. await pumpAndSettle(const Duration(seconds: 2));
  37. return FlowyTestContext(
  38. applicationDataDirectory: directory,
  39. );
  40. }
  41. void mockHotKeyManagerHandlers() {
  42. TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
  43. .setMockMethodCallHandler(const MethodChannel('hotkey_manager'),
  44. (MethodCall methodCall) async {
  45. if (methodCall.method == 'unregisterAll') {
  46. // do nothing
  47. }
  48. return;
  49. });
  50. }
  51. Future<String> mockApplicationDataStorage({
  52. // use to append after the application data directory
  53. String? pathExtension,
  54. }) async {
  55. final dir = await getTemporaryDirectory();
  56. // Use a random uuid to avoid conflict.
  57. String path = p.join(dir.path, 'appflowy_integration_test', uuid());
  58. if (pathExtension != null && pathExtension.isNotEmpty) {
  59. path = '$path/$pathExtension';
  60. }
  61. final directory = Directory(path);
  62. if (!directory.existsSync()) {
  63. await directory.create(recursive: true);
  64. }
  65. MockApplicationDataStorage.initialPath = directory.path;
  66. return directory.path;
  67. }
  68. Future<void> tapButton(
  69. Finder finder, {
  70. int? pointer,
  71. int buttons = kPrimaryButton,
  72. bool warnIfMissed = false,
  73. int milliseconds = 500,
  74. }) async {
  75. await tap(
  76. finder,
  77. buttons: buttons,
  78. warnIfMissed: warnIfMissed,
  79. );
  80. await pumpAndSettle(Duration(milliseconds: milliseconds));
  81. return;
  82. }
  83. Future<void> tapButtonWithName(
  84. String tr, {
  85. int milliseconds = 500,
  86. }) async {
  87. Finder button = find.text(
  88. tr,
  89. findRichText: true,
  90. skipOffstage: false,
  91. );
  92. if (button.evaluate().isEmpty) {
  93. button = find.byWidgetPredicate(
  94. (widget) => widget is FlowyText && widget.text == tr,
  95. );
  96. }
  97. await tapButton(
  98. button,
  99. milliseconds: milliseconds,
  100. );
  101. return;
  102. }
  103. Future<void> tapButtonWithTooltip(
  104. String tr, {
  105. int milliseconds = 500,
  106. }) async {
  107. final button = find.byTooltip(tr);
  108. await tapButton(
  109. button,
  110. milliseconds: milliseconds,
  111. );
  112. return;
  113. }
  114. Future<void> doubleTapAt(
  115. Offset location, {
  116. int? pointer,
  117. int buttons = kPrimaryButton,
  118. int milliseconds = 500,
  119. }) async {
  120. await tapAt(location, pointer: pointer, buttons: buttons);
  121. await pump(kDoubleTapMinTime);
  122. await tapAt(location, pointer: pointer, buttons: buttons);
  123. await pumpAndSettle(Duration(milliseconds: milliseconds));
  124. }
  125. Future<void> doubleTapButton(
  126. Finder finder, {
  127. int? pointer,
  128. int buttons = kPrimaryButton,
  129. bool warnIfMissed = true,
  130. int milliseconds = 500,
  131. }) async {
  132. await tap(
  133. finder,
  134. pointer: pointer,
  135. buttons: buttons,
  136. warnIfMissed: warnIfMissed,
  137. );
  138. await pump(kDoubleTapMinTime);
  139. await tap(
  140. finder,
  141. buttons: buttons,
  142. pointer: pointer,
  143. warnIfMissed: warnIfMissed,
  144. );
  145. await pumpAndSettle(Duration(milliseconds: milliseconds));
  146. }
  147. Future<void> wait(int milliseconds) async {
  148. await pumpAndSettle(Duration(milliseconds: milliseconds));
  149. return;
  150. }
  151. }
  152. extension AppFlowyFinderTestBase on CommonFinders {
  153. Finder findTextInFlowyText(String text) {
  154. return find.byWidgetPredicate(
  155. (widget) => widget is FlowyText && widget.text == text,
  156. );
  157. }
  158. }