diff --git a/frontend/appflowy_flutter/assets/test/workspaces/markdowns/test1.md b/frontend/appflowy_flutter/assets/test/workspaces/markdowns/test1.md new file mode 100644 index 0000000000..47d854f6ef --- /dev/null +++ b/frontend/appflowy_flutter/assets/test/workspaces/markdowns/test1.md @@ -0,0 +1,22 @@ +# Welcome to AppFlowy! + +## Here are the basics + +- [ ] Click anywhere and just start typing. +- [ ] Highlight any text, and use the editing menu to _style_ **your** writing `however` you ~~like.~~ +- [ ] As soon as you type /a menu will pop up. Select different types of content blocks you can add. +- [ ] Type `/` followed by `/bullet` or `/num` to create a list. +- [x] Click `+ New Page `button at the bottom of your sidebar to add a new page. +- [ ] Click `+` next to any page title in the sidebar to quickly add a new subpage, `Document`, `Grid`, or `Kanban Board`. + +--- + +## Keyboard shortcuts, markdown, and code block + +1. Keyboard shortcuts [guide](https://appflowy.gitbook.io/docs/essential-documentation/shortcuts) +1. Markdown [reference](https://appflowy.gitbook.io/docs/essential-documentation/markdown) +1. Type `/code` to insert a code block + +## Have a questionâť“ + +> Click `?` at the bottom right for help and support. diff --git a/frontend/appflowy_flutter/assets/test/workspaces/markdowns/test2.md b/frontend/appflowy_flutter/assets/test/workspaces/markdowns/test2.md new file mode 100644 index 0000000000..83c831f0b0 --- /dev/null +++ b/frontend/appflowy_flutter/assets/test/workspaces/markdowns/test2.md @@ -0,0 +1 @@ +# test diff --git a/frontend/appflowy_flutter/assets/translations/en.json b/frontend/appflowy_flutter/assets/translations/en.json index de558f56a1..e408557310 100644 --- a/frontend/appflowy_flutter/assets/translations/en.json +++ b/frontend/appflowy_flutter/assets/translations/en.json @@ -51,6 +51,12 @@ "import": "Import", "moreOptions": "More options" }, + "importPanel": { + "textAndMarkdown": "Text & Markdown", + "documentFromV010": "Document from v0.1.0", + "databaseFromV010": "Database from v0.1.0", + "csv": "CSV" + }, "disclosureAction": { "rename": "Rename", "delete": "Delete", diff --git a/frontend/appflowy_flutter/integration_test/import_files_test.dart b/frontend/appflowy_flutter/integration_test/import_files_test.dart new file mode 100644 index 0000000000..5743e01f76 --- /dev/null +++ b/frontend/appflowy_flutter/integration_test/import_files_test.dart @@ -0,0 +1,60 @@ +import 'dart:io'; + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; + +import 'util/mock/mock_file_picker.dart'; +import 'util/util.dart'; +import 'package:path/path.dart' as p; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('import files', () { + const location = 'import_files'; + + setUp(() async { + await TestFolder.cleanTestLocation(location); + await TestFolder.setTestLocation(location); + }); + + tearDown(() async { + await TestFolder.cleanTestLocation(location); + }); + + tearDownAll(() async { + await TestFolder.cleanTestLocation(null); + }); + + testWidgets('import multiple markdown files', (tester) async { + await tester.initializeAppFlowy(); + await tester.tapGoButton(); + + // expect to see a readme page + tester.expectToSeePageName(readme); + + await tester.tapAddButton(); + await tester.tapImportButton(); + + final testFileNames = ['test1.md', 'test2.md']; + final fileLocation = await tester.currentFileLocation(); + for (final fileName in testFileNames) { + final str = await rootBundle.loadString( + p.join( + 'assets/test/workspaces/markdowns', + fileName, + ), + ); + File(p.join(fileLocation, fileName)).writeAsStringSync(str); + } + // mock get files + await mockPickFilePaths(testFileNames, name: location); + + await tester.tapTextAndMarkdownButton(); + + tester.expectToSeePageName('test1'); + tester.expectToSeePageName('test2'); + }); + }); +} diff --git a/frontend/appflowy_flutter/integration_test/runner.dart b/frontend/appflowy_flutter/integration_test/runner.dart index 6547e795fa..6ee18f424d 100644 --- a/frontend/appflowy_flutter/integration_test/runner.dart +++ b/frontend/appflowy_flutter/integration_test/runner.dart @@ -3,6 +3,8 @@ import 'package:integration_test/integration_test.dart'; import 'switch_folder_test.dart' as switch_folder_test; import 'document_test.dart' as document_test; import 'cover_image_test.dart' as cover_image_test; +import 'share_markdown_test.dart' as share_markdown_test; +import 'import_files_test.dart' as import_files_test; /// The main task runner for all integration tests in AppFlowy. /// @@ -16,6 +18,8 @@ void main() { switch_folder_test.main(); cover_image_test.main(); document_test.main(); + share_markdown_test.main(); + import_files_test.main(); // board_test.main(); // empty_document_test.main(); // smart_menu_test.main(); diff --git a/frontend/appflowy_flutter/integration_test/util/base.dart b/frontend/appflowy_flutter/integration_test/util/base.dart index be426a61c3..2cc483138c 100644 --- a/frontend/appflowy_flutter/integration_test/util/base.dart +++ b/frontend/appflowy_flutter/integration_test/util/base.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:appflowy/core/config/kv_keys.dart'; import 'package:appflowy/main.dart' as app; import 'package:appflowy/startup/tasks/prelude.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -91,7 +92,16 @@ extension AppFlowyTestBase on WidgetTester { String tr, { int milliseconds = 500, }) async { - final button = find.text(tr, findRichText: true); + Finder button = find.text( + tr, + findRichText: true, + skipOffstage: false, + ); + if (button.evaluate().isEmpty) { + button = find.byWidgetPredicate( + (widget) => widget is FlowyText && widget.title == tr, + ); + } await tapButton( button, milliseconds: milliseconds, diff --git a/frontend/appflowy_flutter/integration_test/util/common_operations.dart b/frontend/appflowy_flutter/integration_test/util/common_operations.dart index 585a40cd60..ba7055cc40 100644 --- a/frontend/appflowy_flutter/integration_test/util/common_operations.dart +++ b/frontend/appflowy_flutter/integration_test/util/common_operations.dart @@ -19,6 +19,10 @@ import 'base.dart'; const String readme = 'Read me'; extension CommonOperations on WidgetTester { + Future currentFileLocation() async { + return TestFolder.currentLocation(); + } + Future tapGoButton() async { final goButton = find.byType(GoButton); await tapButton(goButton); @@ -42,6 +46,14 @@ extension CommonOperations on WidgetTester { await tapButtonWithName(LocaleKeys.document_menuName.tr()); } + Future tapImportButton() async { + await tapButtonWithName(LocaleKeys.moreAction_import.tr()); + } + + Future tapTextAndMarkdownButton() async { + await tapButtonWithName(LocaleKeys.importPanel_textAndMarkdown.tr()); + } + Finder findPageName(String name) { return find.byWidgetPredicate( (widget) => widget is ViewSectionItem && widget.view.name == name, diff --git a/frontend/appflowy_flutter/integration_test/util/mock/mock_file_picker.dart b/frontend/appflowy_flutter/integration_test/util/mock/mock_file_picker.dart index 4ebb2d66a0..390d77d194 100644 --- a/frontend/appflowy_flutter/integration_test/util/mock/mock_file_picker.dart +++ b/frontend/appflowy_flutter/integration_test/util/mock/mock_file_picker.dart @@ -1,15 +1,19 @@ +import 'dart:io'; + import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/util/file_picker/file_picker_service.dart'; -import 'package:file_picker/src/file_picker.dart' as fp; +import 'package:file_picker/file_picker.dart' as fp; import 'package:path/path.dart' as p; import '../util.dart'; class MockFilePicker implements FilePickerService { MockFilePicker({ - required this.mockPath, + this.mockPath = '', + this.mockPaths = const [], }); final String mockPath; + final List mockPaths; @override Future getDirectoryPath({String? title}) { @@ -41,7 +45,14 @@ class MockFilePicker implements FilePickerService { bool withReadStream = false, bool lockParentWindow = false, }) { - throw UnimplementedError(); + final platformFiles = mockPaths + .map((e) => fp.PlatformFile(path: e, name: '', size: 0)) + .toList(); + return Future.value( + FilePickerResult( + platformFiles, + ), + ); } } @@ -67,3 +78,24 @@ Future mockSaveFilePath(String? name, String fileName) async { ); return path; } + +Future> mockPickFilePaths( + List fileNames, { + String? name, + String? customPath, +}) async { + late final Directory dir; + if (customPath != null) { + dir = Directory(customPath); + } else { + dir = await TestFolder.testLocation(name); + } + final paths = fileNames.map((e) => p.join(dir.path, e)).toList(); + getIt.unregister(); + getIt.registerFactory( + () => MockFilePicker( + mockPaths: paths, + ), + ); + return paths; +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/import/import_type.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/import/import_type.dart index 086eee1c86..a51892dd0e 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/import/import_type.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/import/import_type.dart @@ -1,3 +1,5 @@ +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/image.dart'; import 'package:flutter/material.dart'; @@ -11,13 +13,13 @@ enum ImportType { String toString() { switch (this) { case ImportType.historyDocument: - return 'Document from v0.1'; + return LocaleKeys.importPanel_documentFromV010.tr(); case ImportType.historyDatabase: - return 'Database from v0.1'; + return LocaleKeys.importPanel_databaseFromV010.tr(); case ImportType.markdownOrText: - return 'Text & Markdown'; + return LocaleKeys.importPanel_textAndMarkdown.tr(); case ImportType.databaseCSV: - return 'CSV'; + return LocaleKeys.importPanel_csv.tr(); } } diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml index 0f0f41ed5b..b05b57af95 100644 --- a/frontend/appflowy_flutter/pubspec.yaml +++ b/frontend/appflowy_flutter/pubspec.yaml @@ -181,4 +181,5 @@ flutter: # BEGIN: EXCLUDE_IN_RELEASE - assets/test/workspaces/ - assets/template/ + - assets/test/workspaces/markdowns/ # END: EXCLUDE_IN_RELEASE