base.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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. }
  82. Future<void> tapButtonWithName(
  83. String tr, {
  84. int milliseconds = 500,
  85. }) async {
  86. Finder button = find.text(
  87. tr,
  88. findRichText: true,
  89. skipOffstage: false,
  90. );
  91. if (button.evaluate().isEmpty) {
  92. button = find.byWidgetPredicate(
  93. (widget) => widget is FlowyText && widget.text == tr,
  94. );
  95. }
  96. await tapButton(
  97. button,
  98. milliseconds: milliseconds,
  99. );
  100. return;
  101. }
  102. Future<void> tapButtonWithTooltip(
  103. String tr, {
  104. int milliseconds = 500,
  105. }) async {
  106. final button = find.byTooltip(tr);
  107. await tapButton(
  108. button,
  109. milliseconds: milliseconds,
  110. );
  111. return;
  112. }
  113. Future<void> doubleTapAt(
  114. Offset location, {
  115. int? pointer,
  116. int buttons = kPrimaryButton,
  117. int milliseconds = 500,
  118. }) async {
  119. await tapAt(location, pointer: pointer, buttons: buttons);
  120. await pump(kDoubleTapMinTime);
  121. await tapAt(location, pointer: pointer, buttons: buttons);
  122. await pumpAndSettle(Duration(milliseconds: milliseconds));
  123. }
  124. Future<void> doubleTapButton(
  125. Finder finder, {
  126. int? pointer,
  127. int buttons = kPrimaryButton,
  128. bool warnIfMissed = true,
  129. int milliseconds = 500,
  130. }) async {
  131. await tap(
  132. finder,
  133. pointer: pointer,
  134. buttons: buttons,
  135. warnIfMissed: warnIfMissed,
  136. );
  137. await pump(kDoubleTapMinTime);
  138. await tap(
  139. finder,
  140. buttons: buttons,
  141. pointer: pointer,
  142. warnIfMissed: warnIfMissed,
  143. );
  144. await pumpAndSettle(Duration(milliseconds: milliseconds));
  145. }
  146. Future<void> wait(int milliseconds) async {
  147. await pumpAndSettle(Duration(milliseconds: milliseconds));
  148. return;
  149. }
  150. }
  151. extension AppFlowyFinderTestBase on CommonFinders {
  152. Finder findTextInFlowyText(String text) {
  153. return find.byWidgetPredicate(
  154. (widget) => widget is FlowyText && widget.text == text,
  155. );
  156. }
  157. }