|
@@ -1,6 +1,10 @@
|
|
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
|
|
+import 'package:appflowy_editor/src/render/link_menu/link_menu.dart';
|
|
|
import 'package:appflowy_editor/src/render/rich_text/rich_text_style.dart';
|
|
|
import 'package:appflowy_editor/src/extensions/text_node_extensions.dart';
|
|
|
+import 'package:appflowy_editor/src/render/toolbar/toolbar_item.dart';
|
|
|
+import 'package:appflowy_editor/src/render/toolbar/toolbar_widget.dart';
|
|
|
+import 'package:flutter/material.dart';
|
|
|
import 'package:flutter/services.dart';
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
import '../../infra/test_editor.dart';
|
|
@@ -54,6 +58,10 @@ void main() async {
|
|
|
LogicalKeyboardKey.keyH,
|
|
|
);
|
|
|
});
|
|
|
+
|
|
|
+ testWidgets('Presses Command + K to trigger link menu', (tester) async {
|
|
|
+ await _testLinkMenuInSingleTextSelection(tester);
|
|
|
+ });
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -171,3 +179,74 @@ Future<void> _testUpdateTextStyleByCommandX(
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+Future<void> _testLinkMenuInSingleTextSelection(WidgetTester tester) async {
|
|
|
+ const link = 'appflowy.io';
|
|
|
+ const text = 'Welcome to Appflowy 😁';
|
|
|
+ final editor = tester.editor
|
|
|
+ ..insertTextNode(text)
|
|
|
+ ..insertTextNode(text)
|
|
|
+ ..insertTextNode(text);
|
|
|
+ await editor.startTesting();
|
|
|
+
|
|
|
+ final selection =
|
|
|
+ Selection.single(path: [1], startOffset: 0, endOffset: text.length);
|
|
|
+ await editor.updateSelection(selection);
|
|
|
+
|
|
|
+ // show toolbar
|
|
|
+ expect(find.byType(ToolbarWidget), findsOneWidget);
|
|
|
+
|
|
|
+ final item = defaultToolbarItems
|
|
|
+ .where((item) => item.id == 'appflowy.toolbar.link')
|
|
|
+ .first;
|
|
|
+ expect(find.byWidget(item.icon), findsOneWidget);
|
|
|
+
|
|
|
+ // trigger the link menu
|
|
|
+ await editor.pressLogicKey(LogicalKeyboardKey.keyK, isMetaPressed: true);
|
|
|
+
|
|
|
+ expect(find.byType(LinkMenu), findsOneWidget);
|
|
|
+
|
|
|
+ await tester.enterText(find.byType(TextField), link);
|
|
|
+ await tester.testTextInput.receiveAction(TextInputAction.done);
|
|
|
+ await tester.pumpAndSettle();
|
|
|
+
|
|
|
+ expect(find.byType(LinkMenu), findsNothing);
|
|
|
+
|
|
|
+ final node = editor.nodeAtPath([1]) as TextNode;
|
|
|
+ expect(
|
|
|
+ node.allSatisfyInSelection(
|
|
|
+ StyleKey.href,
|
|
|
+ selection,
|
|
|
+ (value) => value == link,
|
|
|
+ ),
|
|
|
+ true);
|
|
|
+
|
|
|
+ await editor.updateSelection(selection);
|
|
|
+ await editor.pressLogicKey(LogicalKeyboardKey.keyK, isMetaPressed: true);
|
|
|
+ expect(find.byType(LinkMenu), findsOneWidget);
|
|
|
+ expect(
|
|
|
+ find.text(link, findRichText: true, skipOffstage: false), findsOneWidget);
|
|
|
+
|
|
|
+ // Copy link
|
|
|
+ final copyLink = find.text('Copy link');
|
|
|
+ expect(copyLink, findsOneWidget);
|
|
|
+ await tester.tap(copyLink);
|
|
|
+ await tester.pumpAndSettle();
|
|
|
+ expect(find.byType(LinkMenu), findsNothing);
|
|
|
+
|
|
|
+ // Remove link
|
|
|
+ await editor.pressLogicKey(LogicalKeyboardKey.keyK, isMetaPressed: true);
|
|
|
+ final removeLink = find.text('Remove link');
|
|
|
+ expect(removeLink, findsOneWidget);
|
|
|
+ await tester.tap(removeLink);
|
|
|
+ await tester.pumpAndSettle();
|
|
|
+ expect(find.byType(LinkMenu), findsNothing);
|
|
|
+
|
|
|
+ expect(
|
|
|
+ node.allSatisfyInSelection(
|
|
|
+ StyleKey.href,
|
|
|
+ selection,
|
|
|
+ (value) => value == link,
|
|
|
+ ),
|
|
|
+ false);
|
|
|
+}
|