mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: enable codecov action (#2741)
* chore: enable codecov action * test: fix integration test * test: fix switch_folder_test
This commit is contained in:
parent
c7f73551c7
commit
d5887b0a12
9
.github/workflows/flutter_ci.yaml
vendored
9
.github/workflows/flutter_ci.yaml
vendored
@ -68,7 +68,7 @@ jobs:
|
||||
with:
|
||||
prefix-key: ${{ matrix.os }}
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
frontend/rust-lib
|
||||
|
||||
- uses: davidB/rust-cargo-make@v1
|
||||
with:
|
||||
@ -118,3 +118,10 @@ jobs:
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make dart_unit_test
|
||||
|
||||
- uses: codecov/codecov-action@v3
|
||||
with:
|
||||
name: appflowy
|
||||
flags: appflowy_flutter_unit_test
|
||||
fail_ci_if_error: true
|
||||
verbose: true
|
13
.github/workflows/integration_test.yml
vendored
13
.github/workflows/integration_test.yml
vendored
@ -116,10 +116,9 @@ jobs:
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
# - uses: codecov/codecov-action@v3
|
||||
# with:
|
||||
# name: appflowy
|
||||
# flags: appflowy
|
||||
# env_vars: ${{ matrix.os }}
|
||||
# fail_ci_if_error: true
|
||||
# verbose: true
|
||||
- uses: codecov/codecov-action@v3
|
||||
with:
|
||||
name: appflowy
|
||||
flags: appflowy_flutter_integrateion_test
|
||||
fail_ci_if_error: true
|
||||
verbose: true
|
||||
|
2
frontend/appflowy_flutter/.gitignore
vendored
2
frontend/appflowy_flutter/.gitignore
vendored
@ -70,3 +70,5 @@ windows/flutter/dart_ffi/
|
||||
**/.vscode/
|
||||
|
||||
*.env
|
||||
|
||||
coverage/
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -35,9 +35,7 @@ void main() {
|
||||
setUpAll(() async => await service.setUpAll());
|
||||
setUp(() async => await service.setUp());
|
||||
|
||||
testWidgets(
|
||||
'integration test unzips the proper workspace and loads it correctly.',
|
||||
(tester) async {
|
||||
testWidgets('open the board with data structure in v0.2.0', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
expect(find.byType(AppFlowyBoard), findsOneWidget);
|
||||
});
|
||||
|
@ -1,54 +1,35 @@
|
||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import 'util/util.dart';
|
||||
|
||||
/// Integration tests for an empty board. The [TestWorkspaceService] will load
|
||||
/// a workspace from an empty board `assets/test/workspaces/board.zip` for all
|
||||
/// tests.
|
||||
///
|
||||
/// To create another integration test with a preconfigured workspace.
|
||||
/// Use the following steps.
|
||||
/// 1. Create a new workspace from the AppFlowy launch screen.
|
||||
/// 2. Modify the workspace until it is suitable as the starting point for
|
||||
/// the integration test you need to land.
|
||||
/// 3. Use a zip utility program to zip the workspace folder that you created.
|
||||
/// 4. Add the zip file under `assets/test/workspaces/`
|
||||
/// 5. Add a new enumeration to [TestWorkspace] in `integration_test/utils/data.dart`.
|
||||
/// For example, if you added a workspace called `empty_calendar.zip`,
|
||||
/// then [TestWorkspace] should have the following value:
|
||||
/// ```dart
|
||||
/// enum TestWorkspace {
|
||||
/// board('board'),
|
||||
/// empty_calendar('empty_calendar');
|
||||
///
|
||||
/// /* code */
|
||||
/// }
|
||||
/// ```
|
||||
/// 6. Double check that the .zip file that you added is included as an asset in
|
||||
/// the pubspec.yaml file under appflowy_flutter.
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
const service = TestWorkspaceService(TestWorkspace.coverImage);
|
||||
|
||||
group('cover image', () {
|
||||
setUpAll(() async => await service.setUpAll());
|
||||
setUp(() async => await service.setUp());
|
||||
const location = 'cover_image';
|
||||
|
||||
setUp(() async {
|
||||
await TestFolder.cleanTestLocation(location);
|
||||
await TestFolder.setTestLocation(location);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
await TestFolder.cleanTestLocation(location);
|
||||
});
|
||||
|
||||
tearDownAll(() async {
|
||||
await TestFolder.cleanTestLocation(null);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'hovering on cover image will display change and delete cover image buttons',
|
||||
(tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
expect(find.byType(Image), findsOneWidget);
|
||||
|
||||
final TestPointer pointer = TestPointer(1, PointerDeviceKind.mouse);
|
||||
final imageFinder = find.byType(Image);
|
||||
final Offset offset = tester.getCenter(imageFinder);
|
||||
|
||||
pointer.hover(offset);
|
||||
expect(find.byType(RoundedTextButton), findsOneWidget);
|
||||
await tester.tapGoButton();
|
||||
await tester.hoverOnCoverPluginAddButton();
|
||||
await tester.expectToSeePluginAddCoverAndIconButton();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import 'board_test.dart' as board_test;
|
||||
import 'switch_folder_test.dart' as switch_folder_test;
|
||||
import 'empty_document_test.dart' as empty_document_test;
|
||||
import 'open_ai_smart_menu_test.dart' as smart_menu_test;
|
||||
import 'document_test.dart' as document_test;
|
||||
import 'cover_image_test.dart' as cover_image_test;
|
||||
|
||||
/// The main task runner for all integration tests in AppFlowy.
|
||||
///
|
||||
@ -16,8 +14,9 @@ import 'document_test.dart' as document_test;
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
switch_folder_test.main();
|
||||
board_test.main();
|
||||
empty_document_test.main();
|
||||
smart_menu_test.main();
|
||||
cover_image_test.main();
|
||||
document_test.main();
|
||||
// board_test.main();
|
||||
// empty_document_test.main();
|
||||
// smart_menu_test.main();
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import 'package:appflowy/user/presentation/folder/folder_widget.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text_field.dart';
|
||||
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
@ -25,60 +24,12 @@ void main() {
|
||||
await TestFolder.cleanTestLocation(null);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'customize folder name and path when launching app in first time',
|
||||
(tester) async {
|
||||
const folderName = 'appflowy';
|
||||
await TestFolder.cleanTestLocation(folderName);
|
||||
|
||||
await tester.initializeAppFlowy();
|
||||
|
||||
// Click create button
|
||||
await tester.tapCreateButton();
|
||||
|
||||
// Set directory
|
||||
final cfw = find.byType(CreateFolderWidget);
|
||||
expect(cfw, findsOneWidget);
|
||||
final state = tester.state(cfw) as CreateFolderWidgetState;
|
||||
final dir = await TestFolder.testLocation(null);
|
||||
state.directory = dir.path;
|
||||
|
||||
// input folder name
|
||||
final ftf = find.byType(FlowyTextField);
|
||||
expect(ftf, findsOneWidget);
|
||||
await tester.enterText(ftf, 'appflowy');
|
||||
|
||||
// Click create button again
|
||||
await tester.tapCreateButton();
|
||||
|
||||
tester.expectToSeeWelcomePage();
|
||||
|
||||
await TestFolder.cleanTestLocation(folderName);
|
||||
});
|
||||
|
||||
testWidgets('open a new folder when launching app in first time',
|
||||
(tester) async {
|
||||
const folderName = 'appflowy';
|
||||
await TestFolder.cleanTestLocation(folderName);
|
||||
await TestFolder.setTestLocation(folderName);
|
||||
|
||||
await tester.initializeAppFlowy();
|
||||
|
||||
// tap open button
|
||||
await mockGetDirectoryPath(folderName);
|
||||
await tester.tapOpenFolderButton();
|
||||
|
||||
await tester.wait(1000);
|
||||
tester.expectToSeeWelcomePage();
|
||||
|
||||
await TestFolder.cleanTestLocation(folderName);
|
||||
});
|
||||
|
||||
testWidgets('switch to B from A, then switch to A again', (tester) async {
|
||||
const String userA = 'userA';
|
||||
const String userB = 'userB';
|
||||
|
||||
await TestFolder.cleanTestLocation(userA);
|
||||
await TestFolder.cleanTestLocation(userB);
|
||||
await TestFolder.setTestLocation(userA);
|
||||
|
||||
await tester.initializeAppFlowy();
|
||||
@ -88,6 +39,7 @@ void main() {
|
||||
|
||||
// switch to user B
|
||||
{
|
||||
// set user name to userA
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
await tester.enterUserName(userA);
|
||||
@ -100,14 +52,15 @@ void main() {
|
||||
await tester.tapCustomLocationButton();
|
||||
await tester.pumpAndSettle();
|
||||
tester.expectToSeeWelcomePage();
|
||||
|
||||
// set user name to userB
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
await tester.enterUserName(userB);
|
||||
}
|
||||
|
||||
// switch to the userA
|
||||
{
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
await tester.enterUserName(userB);
|
||||
|
||||
await tester.openSettingsPage(SettingsPage.files);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
@ -117,7 +70,7 @@ void main() {
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
tester.expectToSeeWelcomePage();
|
||||
expect(find.textContaining(userA), findsOneWidget);
|
||||
tester.expectToSeeUserName(userA);
|
||||
}
|
||||
|
||||
// switch to the userB again
|
||||
@ -132,7 +85,7 @@ void main() {
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
tester.expectToSeeWelcomePage();
|
||||
expect(find.textContaining(userB), findsOneWidget);
|
||||
tester.expectToSeeUserName(userB);
|
||||
}
|
||||
|
||||
await TestFolder.cleanTestLocation(userA);
|
||||
|
@ -7,6 +7,7 @@ import 'package:appflowy/user/presentation/skip_log_in_screen.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/app/header/add_button.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/app/section/item.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@ -15,7 +16,7 @@ import 'base.dart';
|
||||
|
||||
const String readme = 'Read me';
|
||||
|
||||
extension AppFlowyLaunch on WidgetTester {
|
||||
extension CommonOperations on WidgetTester {
|
||||
Future<void> tapGoButton() async {
|
||||
final goButton = find.byType(GoButton);
|
||||
await tapButton(goButton);
|
||||
@ -27,7 +28,7 @@ extension AppFlowyLaunch on WidgetTester {
|
||||
|
||||
void expectToSeeWelcomePage() {
|
||||
expect(find.byType(HomeStack), findsOneWidget);
|
||||
expect(find.textContaining('Read me'), findsNWidgets(2));
|
||||
expect(find.textContaining('Read me'), findsOneWidget);
|
||||
}
|
||||
|
||||
Future<void> tapAddButton() async {
|
||||
@ -122,4 +123,36 @@ extension AppFlowyLaunch on WidgetTester {
|
||||
);
|
||||
expect(exportSuccess, findsOneWidget);
|
||||
}
|
||||
|
||||
Future<void> hoverOnCoverPluginAddButton() async {
|
||||
final editor = find.byWidgetPredicate(
|
||||
(widget) => widget is AppFlowyEditor,
|
||||
);
|
||||
|
||||
final gesture = await createGesture(kind: PointerDeviceKind.mouse);
|
||||
await gesture.addPointer(location: Offset.zero);
|
||||
addTearDown(gesture.removePointer);
|
||||
await pump();
|
||||
final topLeft = getTopLeft(editor).translate(20, 20);
|
||||
await gesture.moveTo(topLeft);
|
||||
await pumpAndSettle();
|
||||
}
|
||||
|
||||
Future<void> expectToSeePluginAddCoverAndIconButton() async {
|
||||
final addCover = find.textContaining(
|
||||
LocaleKeys.document_plugins_cover_addCover.tr(),
|
||||
);
|
||||
final addIcon = find.textContaining(
|
||||
LocaleKeys.document_plugins_cover_addIcon.tr(),
|
||||
);
|
||||
expect(addCover, findsOneWidget);
|
||||
expect(addIcon, findsOneWidget);
|
||||
}
|
||||
|
||||
void expectToSeeUserName(String name) {
|
||||
final userName = find.byWidgetPredicate(
|
||||
(widget) => widget is FlowyText && widget.title == name,
|
||||
);
|
||||
expect(userName, findsOneWidget);
|
||||
}
|
||||
}
|
@ -49,9 +49,11 @@ class TestWorkspaceService {
|
||||
|
||||
/// Instructs the application to read workspace data from the workspace found under this [TestWorkspace]'s path.
|
||||
Future<void> setUpAll() async {
|
||||
final root = await workspace.root;
|
||||
final path = root.path;
|
||||
SharedPreferences.setMockInitialValues(
|
||||
{
|
||||
KVKeys.pathLocation: await workspace.root.then((value) => value.path),
|
||||
KVKeys.pathLocation: path,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -1,33 +1,13 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/settings_dialog.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_menu_element.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'base.dart';
|
||||
|
||||
enum SettingsPage {
|
||||
appearance,
|
||||
language,
|
||||
files,
|
||||
user,
|
||||
}
|
||||
|
||||
extension on SettingsPage {
|
||||
String get name {
|
||||
switch (this) {
|
||||
case SettingsPage.appearance:
|
||||
return LocaleKeys.settings_menu_appearance.tr();
|
||||
case SettingsPage.language:
|
||||
return LocaleKeys.settings_menu_language.tr();
|
||||
case SettingsPage.files:
|
||||
return LocaleKeys.settings_menu_files.tr();
|
||||
case SettingsPage.user:
|
||||
return LocaleKeys.settings_menu_user.tr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension AppFlowySettings on WidgetTester {
|
||||
/// Open settings page
|
||||
Future<void> openSettings() async {
|
||||
@ -41,7 +21,9 @@ extension AppFlowySettings on WidgetTester {
|
||||
|
||||
/// Open the page that insides the settings page
|
||||
Future<void> openSettingsPage(SettingsPage page) async {
|
||||
final button = find.text(page.name, findRichText: true);
|
||||
final button = find.byWidgetPredicate(
|
||||
(widget) => widget is SettingsMenuElement && widget.page == page,
|
||||
);
|
||||
expect(button, findsOneWidget);
|
||||
await tapButton(button);
|
||||
return;
|
||||
@ -50,7 +32,7 @@ extension AppFlowySettings on WidgetTester {
|
||||
/// Restore the AppFlowy data storage location
|
||||
Future<void> restoreLocation() async {
|
||||
final button =
|
||||
find.byTooltip(LocaleKeys.settings_files_restoreLocation.tr());
|
||||
find.byTooltip(LocaleKeys.settings_files_recoverLocationTooltips.tr());
|
||||
expect(button, findsOneWidget);
|
||||
await tapButton(button);
|
||||
return;
|
||||
@ -64,8 +46,9 @@ extension AppFlowySettings on WidgetTester {
|
||||
}
|
||||
|
||||
Future<void> tapCustomLocationButton() async {
|
||||
final button =
|
||||
find.byTooltip(LocaleKeys.settings_files_customizeLocation.tr());
|
||||
final button = find.byTooltip(
|
||||
LocaleKeys.settings_files_changeLocationTooltips.tr(),
|
||||
);
|
||||
expect(button, findsOneWidget);
|
||||
await tapButton(button);
|
||||
return;
|
||||
|
@ -1,4 +1,4 @@
|
||||
export 'base.dart';
|
||||
export 'launch.dart';
|
||||
export 'common_operations.dart';
|
||||
export 'settings.dart';
|
||||
export 'data.dart';
|
||||
|
@ -70,8 +70,10 @@ class SettingsFileLocationCustomizerState
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
_ChangeStoragePathButton(
|
||||
usingPath: path,
|
||||
Flexible(
|
||||
child: _ChangeStoragePathButton(
|
||||
usingPath: path,
|
||||
),
|
||||
),
|
||||
const HSpace(10),
|
||||
_OpenStorageButton(
|
||||
|
@ -33,7 +33,7 @@ dependencies = ["inner_build_test_backend"]
|
||||
description = "Run flutter unit tests"
|
||||
script = '''
|
||||
cd appflowy_flutter
|
||||
flutter test --dart-define=RUST_LOG=${RUST_LOG} -j, --concurrency=1
|
||||
flutter test --dart-define=RUST_LOG=${RUST_LOG} -j, --concurrency=1 --coverage --verbose
|
||||
'''
|
||||
|
||||
[tasks.rust_unit_test]
|
||||
|
Loading…
Reference in New Issue
Block a user