mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Tests for toolbar (#1006)
* fix: fix linux build * Merge pull request #599 from AppFlowy-IO/refactor/grid_decode_cell_data Refactor/grid decode cell data * test: 🧪 tests for toolbar widget * fix: removed multiText & replaced with single line * refactor: cleaned up code & removed unused imports * fix: fix some tests about the toolbar service Co-authored-by: Nathan.fooo <86001920+appflowy@users.noreply.github.com> Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
This commit is contained in:
parent
f4cf5d0808
commit
1f9686dc66
@ -49,6 +49,7 @@ class StyleKey {
|
||||
StyleKey.strikethrough,
|
||||
StyleKey.backgroundColor,
|
||||
StyleKey.href,
|
||||
StyleKey.code,
|
||||
];
|
||||
|
||||
static List<String> globalStyleKeys = [
|
||||
@ -58,7 +59,6 @@ class StyleKey {
|
||||
StyleKey.bulletedList,
|
||||
StyleKey.numberList,
|
||||
StyleKey.quote,
|
||||
StyleKey.code,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,9 @@ class EditorWidgetTester {
|
||||
home: Scaffold(
|
||||
body: AppFlowyEditor(
|
||||
editorState: _editorState,
|
||||
editorStyle: const EditorStyle(
|
||||
padding: EdgeInsets.symmetric(vertical: 30),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -0,0 +1,331 @@
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor/src/extensions/text_node_extensions.dart';
|
||||
import 'package:appflowy_editor/src/render/rich_text/rich_text_style.dart';
|
||||
import 'package:appflowy_editor/src/render/toolbar/toolbar_item_widget.dart';
|
||||
import 'package:appflowy_editor/src/render/toolbar/toolbar_widget.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import '../../infra/test_editor.dart';
|
||||
|
||||
void main() async {
|
||||
setUpAll(() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
});
|
||||
|
||||
const singleLineText = "One Line Of Text";
|
||||
|
||||
group('toolbar, heading', (() {
|
||||
testWidgets('Select Text, Click toolbar and set style for h1 heading',
|
||||
(tester) async {
|
||||
final editor = tester.editor..insertTextNode(singleLineText);
|
||||
await editor.startTesting();
|
||||
|
||||
final h1 = Selection(
|
||||
start: Position(path: [0], offset: 0),
|
||||
end: Position(path: [0], offset: singleLineText.length));
|
||||
|
||||
await editor.updateSelection(h1);
|
||||
|
||||
expect(find.byType(ToolbarWidget), findsOneWidget);
|
||||
|
||||
final h1Button = find.byWidgetPredicate((widget) {
|
||||
if (widget is ToolbarItemWidget) {
|
||||
return widget.item.id == 'appflowy.toolbar.h1';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
expect(h1Button, findsOneWidget);
|
||||
await tester.tap(h1Button);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final node = editor.nodeAtPath([0]) as TextNode;
|
||||
expect(node.attributes.heading, 'h1');
|
||||
});
|
||||
|
||||
testWidgets('Select Text, Click toolbar and set style for h2 heading',
|
||||
(tester) async {
|
||||
final editor = tester.editor..insertTextNode(singleLineText);
|
||||
await editor.startTesting();
|
||||
|
||||
final h2 = Selection(
|
||||
start: Position(path: [0], offset: 0),
|
||||
end: Position(path: [0], offset: singleLineText.length));
|
||||
|
||||
await editor.updateSelection(h2);
|
||||
expect(find.byType(ToolbarWidget), findsOneWidget);
|
||||
|
||||
final h2Button = find.byWidgetPredicate((widget) {
|
||||
if (widget is ToolbarItemWidget) {
|
||||
return widget.item.id == 'appflowy.toolbar.h2';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
expect(h2Button, findsOneWidget);
|
||||
await tester.tap(h2Button);
|
||||
await tester.pumpAndSettle();
|
||||
final node = editor.nodeAtPath([0]) as TextNode;
|
||||
expect(node.attributes.heading, 'h2');
|
||||
});
|
||||
|
||||
testWidgets('Select Text, Click toolbar and set style for h3 heading',
|
||||
(tester) async {
|
||||
final editor = tester.editor..insertTextNode(singleLineText);
|
||||
await editor.startTesting();
|
||||
|
||||
final h3 = Selection(
|
||||
start: Position(path: [0], offset: 0),
|
||||
end: Position(path: [0], offset: singleLineText.length));
|
||||
|
||||
await editor.updateSelection(h3);
|
||||
expect(find.byType(ToolbarWidget), findsOneWidget);
|
||||
|
||||
final h3Button = find.byWidgetPredicate((widget) {
|
||||
if (widget is ToolbarItemWidget) {
|
||||
return widget.item.id == 'appflowy.toolbar.h3';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
expect(h3Button, findsOneWidget);
|
||||
await tester.tap(h3Button);
|
||||
await tester.pumpAndSettle();
|
||||
final node = editor.nodeAtPath([0]) as TextNode;
|
||||
expect(node.attributes.heading, 'h3');
|
||||
});
|
||||
}));
|
||||
|
||||
group('toolbar, underline', (() {
|
||||
testWidgets('Select text, click toolbar and set style for underline',
|
||||
(tester) async {
|
||||
final editor = tester.editor..insertTextNode(singleLineText);
|
||||
await editor.startTesting();
|
||||
|
||||
final underline = Selection(
|
||||
start: Position(path: [0], offset: 0),
|
||||
end: Position(path: [0], offset: singleLineText.length));
|
||||
|
||||
await editor.updateSelection(underline);
|
||||
expect(find.byType(ToolbarWidget), findsOneWidget);
|
||||
final underlineButton = find.byWidgetPredicate((widget) {
|
||||
if (widget is ToolbarItemWidget) {
|
||||
return widget.item.id == 'appflowy.toolbar.underline';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
expect(underlineButton, findsOneWidget);
|
||||
await tester.tap(underlineButton);
|
||||
await tester.pumpAndSettle();
|
||||
final node = editor.nodeAtPath([0]) as TextNode;
|
||||
// expect(node.attributes.underline, true);
|
||||
expect(node.allSatisfyUnderlineInSelection(underline), true);
|
||||
});
|
||||
}));
|
||||
|
||||
group('toolbar, bold', (() {
|
||||
testWidgets('Select Text, Click Toolbar and set style for bold',
|
||||
(tester) async {
|
||||
final editor = tester.editor..insertTextNode(singleLineText);
|
||||
await editor.startTesting();
|
||||
|
||||
final bold = Selection(
|
||||
start: Position(path: [0], offset: 0),
|
||||
end: Position(path: [0], offset: singleLineText.length));
|
||||
|
||||
await editor.updateSelection(bold);
|
||||
expect(find.byType(ToolbarWidget), findsOneWidget);
|
||||
final boldButton = find.byWidgetPredicate((widget) {
|
||||
if (widget is ToolbarItemWidget) {
|
||||
return widget.item.id == 'appflowy.toolbar.bold';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
expect(boldButton, findsOneWidget);
|
||||
await tester.tap(boldButton);
|
||||
await tester.pumpAndSettle();
|
||||
final node = editor.nodeAtPath([0]) as TextNode;
|
||||
expect(node.allSatisfyBoldInSelection(bold), true);
|
||||
});
|
||||
}));
|
||||
|
||||
group('toolbar, italic', (() {
|
||||
testWidgets('Select Text, Click Toolbar and set style for italic',
|
||||
(tester) async {
|
||||
final editor = tester.editor..insertTextNode(singleLineText);
|
||||
await editor.startTesting();
|
||||
|
||||
final italic = Selection(
|
||||
start: Position(path: [0], offset: 0),
|
||||
end: Position(path: [0], offset: singleLineText.length));
|
||||
|
||||
await editor.updateSelection(italic);
|
||||
expect(find.byType(ToolbarWidget), findsOneWidget);
|
||||
final italicButton = find.byWidgetPredicate((widget) {
|
||||
if (widget is ToolbarItemWidget) {
|
||||
return widget.item.id == 'appflowy.toolbar.italic';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
expect(italicButton, findsOneWidget);
|
||||
await tester.tap(italicButton);
|
||||
await tester.pumpAndSettle();
|
||||
final node = editor.nodeAtPath([0]) as TextNode;
|
||||
expect(node.allSatisfyItalicInSelection(italic), true);
|
||||
});
|
||||
}));
|
||||
|
||||
group('toolbar, strikethrough', (() {
|
||||
testWidgets('Select Text, Click Toolbar and set style for strikethrough',
|
||||
(tester) async {
|
||||
final editor = tester.editor..insertTextNode(singleLineText);
|
||||
await editor.startTesting();
|
||||
|
||||
final strikeThrough = Selection(
|
||||
start: Position(path: [0], offset: 0),
|
||||
end: Position(path: [0], offset: singleLineText.length));
|
||||
|
||||
await editor.updateSelection(strikeThrough);
|
||||
|
||||
expect(find.byType(ToolbarWidget), findsOneWidget);
|
||||
final strikeThroughButton = find.byWidgetPredicate((widget) {
|
||||
if (widget is ToolbarItemWidget) {
|
||||
return widget.item.id == 'appflowy.toolbar.strikethrough';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
expect(strikeThroughButton, findsOneWidget);
|
||||
await tester.tap(strikeThroughButton);
|
||||
await tester.pumpAndSettle();
|
||||
final node = editor.nodeAtPath([0]) as TextNode;
|
||||
expect(node.allSatisfyStrikethroughInSelection(strikeThrough), true);
|
||||
});
|
||||
}));
|
||||
|
||||
group('toolbar, code', (() {
|
||||
testWidgets('Select Text, Click Toolbar and set style for code',
|
||||
(tester) async {
|
||||
final editor = tester.editor..insertTextNode(singleLineText);
|
||||
await editor.startTesting();
|
||||
|
||||
final code = Selection(
|
||||
start: Position(path: [0], offset: 0),
|
||||
end: Position(path: [0], offset: singleLineText.length));
|
||||
|
||||
await editor.updateSelection(code);
|
||||
expect(find.byType(ToolbarWidget), findsOneWidget);
|
||||
final codeButton = find.byWidgetPredicate((widget) {
|
||||
if (widget is ToolbarItemWidget) {
|
||||
return widget.item.id == 'appflowy.toolbar.code';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
expect(codeButton, findsOneWidget);
|
||||
await tester.tap(codeButton);
|
||||
await tester.pumpAndSettle();
|
||||
final node = editor.nodeAtPath([0]) as TextNode;
|
||||
expect(
|
||||
node.allSatisfyInSelection(
|
||||
code,
|
||||
StyleKey.code,
|
||||
(value) {
|
||||
return value == true;
|
||||
},
|
||||
),
|
||||
true,
|
||||
);
|
||||
});
|
||||
}));
|
||||
|
||||
group('toolbar, quote', (() {
|
||||
testWidgets('Select Text, Click Toolbar and set style for quote',
|
||||
(tester) async {
|
||||
final editor = tester.editor..insertTextNode(singleLineText);
|
||||
await editor.startTesting();
|
||||
|
||||
final quote = Selection(
|
||||
start: Position(path: [0], offset: 0),
|
||||
end: Position(path: [0], offset: singleLineText.length));
|
||||
|
||||
await editor.updateSelection(quote);
|
||||
expect(find.byType(ToolbarWidget), findsOneWidget);
|
||||
final quoteButton = find.byWidgetPredicate((widget) {
|
||||
if (widget is ToolbarItemWidget) {
|
||||
return widget.item.id == 'appflowy.toolbar.quote';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
expect(quoteButton, findsOneWidget);
|
||||
await tester.tap(quoteButton);
|
||||
await tester.pumpAndSettle();
|
||||
final node = editor.nodeAtPath([0]) as TextNode;
|
||||
expect(node.subtype, 'quote');
|
||||
});
|
||||
}));
|
||||
|
||||
group('toolbar, bullet list', (() {
|
||||
testWidgets('Select Text, Click Toolbar and set style for bullet',
|
||||
(tester) async {
|
||||
final editor = tester.editor..insertTextNode(singleLineText);
|
||||
await editor.startTesting();
|
||||
|
||||
final bulletList = Selection(
|
||||
start: Position(path: [0], offset: 0),
|
||||
end: Position(path: [0], offset: singleLineText.length));
|
||||
|
||||
await editor.updateSelection(bulletList);
|
||||
expect(find.byType(ToolbarWidget), findsOneWidget);
|
||||
final bulletListButton = find.byWidgetPredicate((widget) {
|
||||
if (widget is ToolbarItemWidget) {
|
||||
return widget.item.id == 'appflowy.toolbar.bulleted_list';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
expect(bulletListButton, findsOneWidget);
|
||||
await tester.tap(bulletListButton);
|
||||
await tester.pumpAndSettle();
|
||||
final node = editor.nodeAtPath([0]) as TextNode;
|
||||
expect(node.subtype, 'bulleted-list');
|
||||
});
|
||||
}));
|
||||
|
||||
group('toolbar, highlight', (() {
|
||||
testWidgets('Select Text, Click Toolbar and set style for highlighted text',
|
||||
(tester) async {
|
||||
// FIXME: Use a const value instead of the magic string.
|
||||
const blue = '0x6000BCF0';
|
||||
final editor = tester.editor..insertTextNode(singleLineText);
|
||||
await editor.startTesting();
|
||||
|
||||
final node = editor.nodeAtPath([0]) as TextNode;
|
||||
final selection = Selection(
|
||||
start: Position(path: [0], offset: 0),
|
||||
end: Position(path: [0], offset: singleLineText.length));
|
||||
|
||||
await editor.updateSelection(selection);
|
||||
expect(find.byType(ToolbarWidget), findsOneWidget);
|
||||
final highlightButton = find.byWidgetPredicate((widget) {
|
||||
if (widget is ToolbarItemWidget) {
|
||||
return widget.item.id == 'appflowy.toolbar.highlight';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
expect(highlightButton, findsOneWidget);
|
||||
await tester.tap(highlightButton);
|
||||
await tester.pumpAndSettle();
|
||||
expect(
|
||||
node.allSatisfyInSelection(
|
||||
selection,
|
||||
StyleKey.backgroundColor,
|
||||
(value) {
|
||||
return value == blue;
|
||||
},
|
||||
),
|
||||
true,
|
||||
);
|
||||
});
|
||||
}));
|
||||
}
|
@ -40,7 +40,11 @@ void main() async {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.pageDown,
|
||||
);
|
||||
currentOffsetY += onePageHeight!;
|
||||
if (i == page) {
|
||||
currentOffsetY = scrollService.maxScrollExtent;
|
||||
} else {
|
||||
currentOffsetY += onePageHeight!;
|
||||
}
|
||||
final dy = scrollService.dy;
|
||||
expect(dy, currentOffsetY);
|
||||
}
|
||||
@ -58,7 +62,11 @@ void main() async {
|
||||
await editor.pressLogicKey(
|
||||
LogicalKeyboardKey.pageUp,
|
||||
);
|
||||
currentOffsetY -= onePageHeight!;
|
||||
if (i == 1) {
|
||||
currentOffsetY = scrollService.minScrollExtent;
|
||||
} else {
|
||||
currentOffsetY -= onePageHeight!;
|
||||
}
|
||||
final dy = editor.editorState.service.scrollService?.dy;
|
||||
expect(dy, currentOffsetY);
|
||||
}
|
||||
|
@ -83,6 +83,8 @@ void main() async {
|
||||
key = 'highlight';
|
||||
} else if (styleKey == StyleKey.href) {
|
||||
key = 'link';
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
final itemWidget = _itemWidgetForId(tester, 'appflowy.toolbar.$key');
|
||||
expect(itemWidget.isHighlight, expectedValue);
|
||||
|
Loading…
x
Reference in New Issue
Block a user