editor_test_operations.dart 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import 'dart:ui';
  2. import 'package:appflowy/generated/locale_keys.g.dart';
  3. import 'package:appflowy/plugins/document/presentation/editor_plugins/header/cover_editor.dart';
  4. import 'package:appflowy/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart';
  5. import 'package:appflowy/plugins/document/presentation/editor_plugins/header/emoji_icon_widget.dart';
  6. import 'package:appflowy/plugins/document/presentation/editor_plugins/header/emoji_popover.dart';
  7. import 'package:appflowy_editor/appflowy_editor.dart' hide Log;
  8. import 'package:easy_localization/easy_localization.dart';
  9. import 'package:flutter/services.dart';
  10. import 'package:flutter_test/flutter_test.dart';
  11. import 'ime.dart';
  12. import 'util.dart';
  13. extension EditorWidgetTester on WidgetTester {
  14. EditorOperations get editor => EditorOperations(this);
  15. }
  16. class EditorOperations {
  17. const EditorOperations(this.tester);
  18. final WidgetTester tester;
  19. EditorState getCurrentEditorState() {
  20. return tester
  21. .widget<AppFlowyEditor>(find.byType(AppFlowyEditor))
  22. .editorState;
  23. }
  24. /// Tap the line of editor at [index]
  25. Future<void> tapLineOfEditorAt(int index) async {
  26. final textBlocks = find.byType(TextBlockComponentWidget);
  27. await tester.tapAt(tester.getTopRight(textBlocks.at(index)));
  28. }
  29. /// Hover on cover plugin button above the document
  30. Future<void> hoverOnCoverToolbar() async {
  31. final coverToolbar = find.byType(DocumentHeaderToolbar);
  32. await tester.startGesture(
  33. tester.getBottomLeft(coverToolbar).translate(5, -5),
  34. kind: PointerDeviceKind.mouse,
  35. );
  36. await tester.pumpAndSettle();
  37. }
  38. /// Taps on the 'Add Icon' button in the cover toolbar
  39. Future<void> tapAddIconButton() async {
  40. await tester.tapButtonWithName(
  41. LocaleKeys.document_plugins_cover_addIcon.tr(),
  42. );
  43. expect(find.byType(EmojiPopover), findsOneWidget);
  44. }
  45. /// Taps the 'Remove Icon' button in the cover toolbar and the icon popover
  46. Future<void> tapRemoveIconButton({bool isInPicker = false}) async {
  47. Finder button =
  48. find.text(LocaleKeys.document_plugins_cover_removeIcon.tr());
  49. if (isInPicker) {
  50. button = find.descendant(of: find.byType(EmojiPopover), matching: button);
  51. }
  52. await tester.tapButton(button);
  53. }
  54. /// Requires that the document must already have an icon. This opens the icon
  55. /// picker
  56. Future<void> tapOnIconWidget() async {
  57. final iconWidget = find.byType(EmojiIconWidget);
  58. await tester.tapButton(iconWidget);
  59. }
  60. Future<void> tapOnAddCover() async {
  61. await tester.tapButtonWithName(
  62. LocaleKeys.document_plugins_cover_addCover.tr(),
  63. );
  64. }
  65. Future<void> tapOnChangeCover() async {
  66. await tester.tapButtonWithName(
  67. LocaleKeys.document_plugins_cover_changeCover.tr(),
  68. );
  69. }
  70. Future<void> switchSolidColorBackground() async {
  71. final findPurpleButton = find.byWidgetPredicate(
  72. (widget) => widget is ColorItem && widget.option.colorHex == "ffe8e0ff",
  73. );
  74. await tester.tapButton(findPurpleButton);
  75. }
  76. Future<void> tapOnRemoveCover() async {
  77. await tester.tapButton(find.byType(DeleteCoverButton));
  78. }
  79. /// A cover must be present in the document to function properly since this
  80. /// catches all cover types collectively
  81. Future<void> hoverOnCover() async {
  82. final cover = find.byType(DocumentCover);
  83. await tester.startGesture(
  84. tester.getCenter(cover),
  85. kind: PointerDeviceKind.mouse,
  86. );
  87. await tester.pumpAndSettle();
  88. }
  89. Future<void> dismissCoverPicker() async {
  90. await tester.sendKeyEvent(LogicalKeyboardKey.escape);
  91. await tester.pumpAndSettle();
  92. }
  93. /// trigger the slash command (selection menu)
  94. Future<void> showSlashMenu() async {
  95. await tester.ime.insertCharacter('/');
  96. }
  97. /// Tap the slash menu item with [name]
  98. ///
  99. /// Must call [showSlashMenu] first.
  100. Future<void> tapSlashMenuItemWithName(String name) async {
  101. final slashMenuItem = find.text(name, findRichText: true);
  102. await tester.tapButton(slashMenuItem);
  103. }
  104. }