Merge branch 'main' into workspace-invite

This commit is contained in:
Zack Fu Zi Xiang 2024-03-05 19:07:14 +08:00
commit 6901f9ceec
No known key found for this signature in database
190 changed files with 2791 additions and 1181 deletions

126
.github/workflows/android_ci.yaml vendored Normal file
View File

@ -0,0 +1,126 @@
# name: Android CI
# on:
# push:
# branches:
# - "main"
# paths:
# - ".github/workflows/mobile_ci.yaml"
# - "frontend/**"
# - "!frontend/appflowy_tauri/**"
# pull_request:
# branches:
# - "main"
# paths:
# - ".github/workflows/mobile_ci.yaml"
# - "frontend/**"
# - "!frontend/appflowy_tauri/**"
# env:
# CARGO_TERM_COLOR: always
# FLUTTER_VERSION: "3.19.0"
# RUST_TOOLCHAIN: "1.75"
# CARGO_MAKE_VERSION: "0.36.6"
# concurrency:
# group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
# cancel-in-progress: true
# jobs:
# build:
# if: github.event.pull_request.draft != true
# strategy:
# fail-fast: true
# matrix:
# os: [macos-14]
# runs-on: ${{ matrix.os }}
# steps:
# - name: Check storage space
# run: df -h
# # the following step is required to avoid running out of space
# - name: Maximize build space
# if: matrix.os == 'ubuntu-latest'
# run: |
# sudo rm -rf /usr/share/dotnet
# sudo rm -rf /opt/ghc
# sudo rm -rf "/usr/local/share/boost"
# sudo rm -rf "$AGENT_TOOLSDIRECTORY"
# sudo docker image prune --all --force
# sudo rm -rf /opt/hostedtoolcache/codeQL
# sudo rm -rf ${GITHUB_WORKSPACE}/.git
# sudo rm -rf $ANDROID_HOME/ndk
# - name: Check storage space
# run: df -h
# - name: Checkout source code
# uses: actions/checkout@v4
# - uses: actions/setup-java@v4
# with:
# distribution: temurin
# java-version: 11
# - name: Install Rust toolchain
# id: rust_toolchain
# uses: actions-rs/toolchain@v1
# with:
# toolchain: ${{ env.RUST_TOOLCHAIN }}
# override: true
# profile: minimal
# - name: Install flutter
# id: flutter
# uses: subosito/flutter-action@v2
# with:
# channel: "stable"
# flutter-version: ${{ env.FLUTTER_VERSION }}
# - uses: gradle/gradle-build-action@v3
# with:
# gradle-version: 7.4.2
# - uses: davidB/rust-cargo-make@v1
# with:
# version: "0.36.6"
# - name: Install prerequisites
# working-directory: frontend
# run: |
# rustup target install aarch64-linux-android
# rustup target install x86_64-linux-android
# cargo install --force duckscript_cli
# cargo install cargo-ndk
# if [ "$RUNNER_OS" == "Linux" ]; then
# sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub
# sudo wget -qO /etc/apt/sources.list.d/dart_stable.list https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list
# sudo apt-get update
# sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
# sudo apt-get install keybinder-3.0 libnotify-dev
# sudo apt-get install gcc-multilib
# elif [ "$RUNNER_OS" == "Windows" ]; then
# vcpkg integrate install
# elif [ "$RUNNER_OS" == "macOS" ]; then
# echo 'do nothing'
# fi
# cargo make appflowy-flutter-deps-tools
# shell: bash
# - name: Build AppFlowy
# working-directory: frontend
# run: |
# cargo make --profile development-android appflowy-android-dev-ci
# - name: Run integration tests
# # https://github.com/ReactiveCircus/android-emulator-runner
# uses: reactivecircus/android-emulator-runner@v2
# with:
# api-level: 32
# arch: arm64-v8a
# disk-size: 2048M
# working-directory: frontend/appflowy_flutter
# script: flutter test integration_test/runner.dart

91
.github/workflows/ios_ci.yaml vendored Normal file
View File

@ -0,0 +1,91 @@
name: iOS CI
on:
push:
branches:
- "main"
paths:
- ".github/workflows/mobile_ci.yaml"
- "frontend/**"
- "!frontend/appflowy_tauri/**"
pull_request:
branches:
- "main"
paths:
- ".github/workflows/mobile_ci.yaml"
- "frontend/**"
- "!frontend/appflowy_tauri/**"
env:
FLUTTER_VERSION: "3.19.0"
RUST_TOOLCHAIN: "1.75"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build:
if: github.event.pull_request.draft != true
strategy:
fail-fast: true
matrix:
os: [macos-14]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout source code
uses: actions/checkout@v2
- name: Install Rust toolchain
id: rust_toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_TOOLCHAIN }}
target: aarch64-apple-ios-sim
override: true
profile: minimal
- name: Install flutter
id: flutter
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- uses: Swatinem/rust-cache@v2
with:
prefix-key: ${{ matrix.os }}
workspaces: |
frontend/rust-lib
- uses: davidB/rust-cargo-make@v1
with:
version: "0.36.6"
- name: Install prerequisites
working-directory: frontend
run: |
rustup target install aarch64-apple-ios-sim
cargo install --force duckscript_cli
cargo install cargo-lipo
cargo make appflowy-flutter-deps-tools
shell: bash
- name: Build AppFlowy
working-directory: frontend
run: |
cargo make --profile development-ios-arm64-sim appflowy-core-dev-ios
cargo make --profile development-ios-arm64-sim code_generation
- uses: futureware-tech/simulator-action@v3
id: simulator-action
with:
model: 'iPhone 15'
shutdown_after_job: false
- name: Run integration tests
working-directory: frontend/appflowy_flutter
run: flutter test integration_test/runner.dart -d ${{ steps.simulator-action.outputs.udid }}

View File

@ -1,117 +0,0 @@
name: Mobile-CI
on:
push:
branches:
- "main"
paths:
- ".github/workflows/mobile_ci.yaml"
- "frontend/**"
- "!frontend/appflowy_tauri/**"
pull_request:
branches:
- "main"
paths:
- ".github/workflows/mobile_ci.yaml"
- "frontend/**"
- "!frontend/appflowy_tauri/**"
env:
FLUTTER_VERSION: "3.19.0"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build:
if: github.event.pull_request.draft != true
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
include:
- os: ubuntu-latest
target: aarch64-linux-android
runs-on: ${{ matrix.os }}
steps:
- name: Check storage space
run: df -h
- name: Maximize build space
uses: easimon/maximize-build-space@master
with:
root-reserve-mb: 2048
swap-size-mb: 1024
remove-dotnet: 'true'
# the following step is required to avoid running out of space
- name: Maximize build space
if: matrix.os == 'ubuntu-latest'
run: |
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
sudo rm -rf "/usr/local/share/boost"
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
sudo docker image prune --all --force
sudo rm -rf /opt/hostedtoolcache/codeQL
sudo rm -rf ${GITHUB_WORKSPACE}/.git
sudo rm -rf $ANDROID_HOME/ndk
- name: Check storage space
run: df -h
- name: Checkout source code
uses: actions/checkout@v4
- name: Install flutter
id: flutter
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version: ${{ env.FLUTTER_VERSION }}
- uses: nttld/setup-ndk@v1
id: setup-ndk
with:
ndk-version: "r24"
add-to-path: true
- uses: gradle/gradle-build-action@v3
with:
gradle-version: 7.6.3
- uses: davidB/rust-cargo-make@v1
with:
version: "0.36.6"
- name: Install prerequisites
working-directory: frontend
run: |
rustup target install aarch64-linux-android
rustup target install x86_64-linux-android
cargo install --force duckscript_cli
cargo install cargo-ndk
if [ "$RUNNER_OS" == "Linux" ]; then
sudo wget -qO /etc/apt/trusted.gpg.d/dart_linux_signing_key.asc https://dl-ssl.google.com/linux/linux_signing_key.pub
sudo wget -qO /etc/apt/sources.list.d/dart_stable.list https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list
sudo apt-get update
sudo apt-get install -y dart curl build-essential libssl-dev clang cmake ninja-build pkg-config libgtk-3-dev
sudo apt-get install keybinder-3.0 libnotify-dev
sudo apt-get install gcc-multilib
elif [ "$RUNNER_OS" == "Windows" ]; then
vcpkg integrate install
elif [ "$RUNNER_OS" == "macOS" ]; then
echo 'do nothing'
fi
cargo make appflowy-flutter-deps-tools
shell: bash
- name: Build AppFlowy
working-directory: frontend
env:
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
run: |
cargo make --profile development-android appflowy-android-dev-ci

View File

@ -16,9 +16,9 @@ import 'package:flowy_infra/uuid.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:path/path.dart' as p;
import 'package:integration_test/integration_test.dart';
import '../util/dir.dart';
import '../util/mock/mock_file_picker.dart';
import '../util/util.dart';
import '../shared/dir.dart';
import '../shared/mock/mock_file_picker.dart';
import '../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -11,10 +11,11 @@ import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_v
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/uuid.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:path/path.dart' as p;
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;
import '../shared/mock/mock_file_picker.dart';
import '../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
@ -47,13 +48,13 @@ void main() {
tester.expectToSeeGoogleLoginButton();
});
testWidgets('sign in as annoymous', (tester) async {
testWidgets('sign in as anonymous', (tester) async {
await tester.initializeAppFlowy(
cloudType: AuthenticatorType.appflowyCloudSelfHost,
);
await tester.tapSignInAsGuest();
// should not see the sync setting page when sign in as annoymous
// should not see the sync setting page when sign in as anonymous
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.user);
tester.expectToSeeGoogleLoginButton();

View File

@ -1,8 +1,9 @@
import 'empty_test.dart' as preset_af_cloud_env_test;
import 'anon_user_continue_test.dart' as anon_user_continue_test;
import 'appflowy_cloud_auth_test.dart' as appflowy_cloud_auth_test;
import 'collaborative_workspace_test.dart' as collaboration_workspace_test;
import 'empty_test.dart' as preset_af_cloud_env_test;
// import 'document_sync_test.dart' as document_sync_test;
import 'user_setting_sync_test.dart' as user_sync_test;
import 'anon_user_continue_test.dart' as anon_user_continue_test;
Future<void> main() async {
preset_af_cloud_env_test.main();
@ -14,4 +15,6 @@ Future<void> main() async {
user_sync_test.main();
anon_user_continue_test.main();
collaboration_workspace_test.main();
}

View File

@ -0,0 +1,115 @@
// ignore_for_file: unused_import
import 'dart:io';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/shared/feature_flags.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/auth/af_cloud_mock_auth_service.dart';
import 'package:appflowy/user/application/auth/auth_service.dart';
import 'package:appflowy/workspace/application/settings/prelude.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_actions.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart';
import 'package:appflowy/workspace/presentation/widgets/user_avatar.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/uuid.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:path/path.dart' as p;
import '../shared/database_test_op.dart';
import '../shared/dir.dart';
import '../shared/emoji.dart';
import '../shared/mock/mock_file_picker.dart';
import '../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
final email = '${uuid()}@appflowy.io';
group('collaborative workspace', () {
// only run the test when the feature flag is on
if (!FeatureFlag.collaborativeWorkspace.isOn) {
return;
}
// combine the create and delete workspace test to reduce the time
testWidgets('create a new workspace, open it and then delete it',
(tester) async {
await tester.initializeAppFlowy(
cloudType: AuthenticatorType.appflowyCloudSelfHost,
email: email,
);
await tester.tapGoogleLoginInButton();
await tester.expectToSeeHomePageWithGetStartedPage();
const name = 'AppFlowy.IO';
await tester.createCollaborativeWorkspace(name);
// see the success message
var success = find.text(LocaleKeys.workspace_createSuccess.tr());
expect(success, findsOneWidget);
await tester.pumpUntilNotFound(success);
// check the create result
await tester.openCollaborativeWorkspaceMenu();
var items = find.byType(WorkspaceMenuItem);
expect(items, findsNWidgets(2));
expect(
tester.widget<WorkspaceMenuItem>(items.last).workspace.name,
name,
);
// open the newly created workspace
await tester.tapButton(items.last);
success = find.text(LocaleKeys.workspace_openSuccess.tr());
expect(success, findsOneWidget);
await tester.pumpUntilNotFound(success);
await tester.closeCollaborativeWorkspaceMenu();
// delete the newly created workspace
await tester.openCollaborativeWorkspaceMenu();
final secondWorkspace = find.byType(WorkspaceMenuItem).last;
await tester.hoverOnWidget(
secondWorkspace,
onHover: () async {
// click the more button
final moreButton = find.byType(WorkspaceMoreActionList);
expect(moreButton, findsOneWidget);
await tester.tapButton(moreButton);
// click the delete button
final deleteButton = find.text(LocaleKeys.button_delete.tr());
expect(deleteButton, findsOneWidget);
await tester.tapButton(deleteButton);
// see the delete confirm dialog
final confirm =
find.text(LocaleKeys.workspace_deleteWorkspaceHintText.tr());
expect(confirm, findsOneWidget);
await tester.tapButton(find.text(LocaleKeys.button_ok.tr()));
// delete success
success = find.text(LocaleKeys.workspace_createSuccess.tr());
expect(success, findsOneWidget);
await tester.pumpUntilNotFound(success);
},
);
// check the result
await tester.openCollaborativeWorkspaceMenu();
items = find.byType(WorkspaceMenuItem);
expect(items, findsOneWidget);
expect(
tester.widget<WorkspaceMenuItem>(items.last).workspace.name != name,
true,
);
await tester.closeCollaborativeWorkspaceMenu();
});
});
}

View File

@ -16,9 +16,9 @@ import 'package:flowy_infra/uuid.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:path/path.dart' as p;
import 'package:integration_test/integration_test.dart';
import '../util/dir.dart';
import '../util/mock/mock_file_picker.dart';
import '../util/util.dart';
import '../shared/dir.dart';
import '../shared/mock/mock_file_picker.dart';
import '../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -2,7 +2,7 @@ import 'package:appflowy/env/cloud_env.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../shared/util.dart';
// This test is meaningless, just for preventing the CI from failing.
void main() {

View File

@ -6,7 +6,8 @@ import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_v
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
@ -35,11 +36,11 @@ void main() {
tester.expectToSeeGoogleLoginButton();
});
testWidgets('sign in as annoymous', (tester) async {
testWidgets('sign in as anonymous', (tester) async {
await tester.initializeAppFlowy(cloudType: AuthenticatorType.supabase);
await tester.tapSignInAsGuest();
// should not see the sync setting page when sign in as annoymous
// should not see the sync setting page when sign in as anonymous
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.user);
tester.expectToSeeGoogleLoginButton();

View File

@ -18,11 +18,11 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:path/path.dart' as p;
import 'package:integration_test/integration_test.dart';
import '../util/database_test_op.dart';
import '../util/dir.dart';
import '../util/emoji.dart';
import '../util/mock/mock_file_picker.dart';
import '../util/util.dart';
import '../shared/database_test_op.dart';
import '../shared/dir.dart';
import '../shared/emoji.dart';
import '../shared/mock/mock_file_picker.dart';
import '../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
const defaultFirstCardName = 'Card 1';
const defaultLastCardName = 'Card 3';

View File

@ -6,7 +6,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:appflowy_board/appflowy_board.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -7,8 +7,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/database_test_op.dart';
import '../util/util.dart';
import '../../shared/database_test_op.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -7,8 +7,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../util/database_test_op.dart';
import '../../shared/util.dart';
import '../../shared/database_test_op.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -5,8 +5,8 @@ import 'package:flowy_infra_ui/style_widget/icon_button.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/database_test_op.dart';
import '../util/util.dart';
import '../../shared/database_test_op.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -4,8 +4,8 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:intl/intl.dart';
import '../util/database_test_op.dart';
import '../util/util.dart';
import '../../shared/database_test_op.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -4,8 +4,8 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pbenum.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/database_test_op.dart';
import '../util/util.dart';
import '../../shared/database_test_op.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -8,8 +8,8 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:intl/intl.dart';
import '../util/database_test_op.dart';
import '../util/util.dart';
import '../../shared/database_test_op.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -4,7 +4,7 @@ import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/database_test_op.dart';
import '../../shared/database_test_op.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -5,8 +5,8 @@ import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/database_test_op.dart';
import '../util/util.dart';
import '../../shared/database_test_op.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -7,9 +7,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/database_test_op.dart';
import '../util/emoji.dart';
import '../util/util.dart';
import '../../shared/database_test_op.dart';
import '../../shared/emoji.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -2,8 +2,8 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/database_test_op.dart';
import '../util/util.dart';
import '../../shared/database_test_op.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -3,8 +3,8 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/database_test_op.dart';
import '../util/util.dart';
import '../../shared/database_test_op.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -2,7 +2,7 @@ import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/database_test_op.dart';
import '../../shared/database_test_op.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -2,7 +2,7 @@ import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/database_test_op.dart';
import '../../shared/database_test_op.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -3,8 +3,8 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/database_test_op.dart';
import '../util/util.dart';
import '../../shared/database_test_op.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -5,8 +5,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/keyboard.dart';
import '../util/util.dart';
import '../../shared/keyboard.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -7,7 +7,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -8,7 +8,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -4,7 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -1,14 +1,13 @@
import 'package:flutter/services.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_page_block.dart';
import 'package:appflowy/plugins/inline_actions/widgets/inline_actions_handler.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
import 'package:flowy_infra/uuid.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/keyboard.dart';
import '../util/util.dart';
import '../../shared/keyboard.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -1,7 +1,7 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -2,7 +2,7 @@ import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -7,8 +7,8 @@ import 'package:flutter_emoji_mart/flutter_emoji_mart.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/emoji.dart';
import '../util/util.dart';
import '../../shared/emoji.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -1,9 +1,9 @@
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/database/widgets/cell/editable_cell_skeleton/text.dart';
import 'package:appflowy/plugins/inline_actions/widgets/inline_actions_handler.dart';
import 'package:appflowy/plugins/database/board/presentation/board_page.dart';
import 'package:appflowy/plugins/database/calendar/presentation/calendar_page.dart';
import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart';
import 'package:appflowy/plugins/database/widgets/cell/editable_cell_skeleton/text.dart';
import 'package:appflowy/plugins/inline_actions/widgets/inline_actions_handler.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
@ -12,7 +12,7 @@ import 'package:flowy_infra/uuid.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -22,8 +22,8 @@ import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
import 'package:run_with_network_images/run_with_network_images.dart';
import '../util/mock/mock_file_picker.dart';
import '../util/util.dart';
import '../../shared/mock/mock_file_picker.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -5,7 +5,7 @@ import 'package:flowy_infra_ui/widget/error_page.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -5,7 +5,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -7,7 +7,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
const String heading1 = "Heading 1";
const String heading2 = "Heading 2";

View File

@ -7,7 +7,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -5,7 +5,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -4,8 +4,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/database_test_op.dart';
import '../util/util.dart';
import '../../shared/database_test_op.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -1,5 +1,3 @@
import 'package:flutter/services.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_block.dart';
import 'package:appflowy/user/application/user_settings_service.dart';
@ -11,14 +9,15 @@ import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:calendar_view/calendar_view.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/style_widget/text_field.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/base.dart';
import '../util/common_operations.dart';
import '../util/editor_test_operations.dart';
import '../util/expectation.dart';
import '../util/keyboard.dart';
import '../../shared/base.dart';
import '../../shared/common_operations.dart';
import '../../shared/editor_test_operations.dart';
import '../../shared/expectation.dart';
import '../../shared/keyboard.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -1,10 +1,11 @@
import 'dart:ui';
import 'package:appflowy/workspace/presentation/settings/widgets/settings_language_view.dart';
import 'package:integration_test/integration_test.dart';
import 'package:flutter_test/flutter_test.dart';
import '../util/util.dart';
import 'package:appflowy/workspace/application/settings/prelude.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/settings_language_view.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -6,9 +6,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/base.dart';
import '../util/common_operations.dart';
import '../util/keyboard.dart';
import '../../shared/keyboard.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -6,7 +6,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -6,9 +6,9 @@ import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/base.dart';
import '../util/common_operations.dart';
import '../util/expectation.dart';
import '../../shared/base.dart';
import '../../shared/common_operations.dart';
import '../../shared/expectation.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -2,9 +2,9 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/base.dart';
import '../util/common_operations.dart';
import '../util/expectation.dart';
import '../../shared/base.dart';
import '../../shared/common_operations.dart';
import '../../shared/expectation.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -12,7 +12,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -5,7 +5,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -1,7 +1,8 @@
import 'package:appflowy_board/appflowy_board.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'util/util.dart';
import '../../shared/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

View File

@ -1,4 +1,5 @@
import 'dart:io';
import 'package:appflowy/workspace/presentation/settings/widgets/emoji_picker/emoji_picker.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/editor/editor_component/service/editor.dart';
@ -6,8 +7,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'util/keyboard.dart';
import 'util/util.dart';
import '../../shared/keyboard.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
@ -17,7 +18,7 @@ void main() {
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
final Finder editor = find.byType(AppFlowyEditor);
await tester.tap(editor);
await tester.pumpAndSettle();

View File

@ -3,8 +3,9 @@ import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'util/keyboard.dart';
import 'util/util.dart';
import '../../shared/keyboard.dart';
import '../../shared/util.dart';
/// Integration tests for an empty document. The [TestWorkspaceService] will load a workspace from an empty document `assets/test/workspaces/empty_document.zip` for all tests.
///

View File

@ -1,7 +1,7 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'util/util.dart';
import '../../shared/util.dart';
// This test is meaningless, just for preventing the CI from failing.
void main() {

View File

@ -1,4 +1,5 @@
import 'dart:io';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/application/settings/prelude.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar.dart';
@ -8,8 +9,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'util/keyboard.dart';
import 'util/util.dart';
import '../../shared/keyboard.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -3,11 +3,11 @@ 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;
import '../../shared/mock/mock_file_picker.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -2,7 +2,7 @@ import 'package:appflowy/workspace/presentation/settings/widgets/settings_langua
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'util/util.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -7,8 +7,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'util/mock/mock_openai_repository.dart';
import 'util/util.dart';
import '../../shared/mock/mock_openai_repository.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -5,8 +5,8 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:path/path.dart' as p;
import 'util/mock/mock_file_picker.dart';
import 'util/util.dart';
import '../../shared/mock/mock_file_picker.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -7,8 +7,8 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:path/path.dart' as p;
import 'util/mock/mock_file_picker.dart';
import 'util/util.dart';
import '../../shared/mock/mock_file_picker.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

View File

@ -8,10 +8,10 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'util/base.dart';
import 'util/common_operations.dart';
import 'util/expectation.dart';
import 'util/keyboard.dart';
import '../../shared/base.dart';
import '../../shared/common_operations.dart';
import '../../shared/expectation.dart';
import '../../shared/keyboard.dart';
const _documentName = 'First Doc';
const _documentTwoName = 'Second Doc';

View File

@ -0,0 +1,68 @@
import 'desktop/uncategorized/appearance_settings_test.dart' as appearance_test_runner;
import 'desktop/board/board_test_runner.dart' as board_test_runner;
import 'desktop/database/database_calendar_test.dart' as database_calendar_test;
import 'desktop/database/database_cell_test.dart' as database_cell_test;
import 'desktop/database/database_field_settings_test.dart'
as database_field_settings_test;
import 'desktop/database/database_field_test.dart' as database_field_test;
import 'desktop/database/database_filter_test.dart' as database_filter_test;
import 'desktop/database/database_row_page_test.dart' as database_row_page_test;
import 'desktop/database/database_row_test.dart' as database_row_test;
import 'desktop/database/database_setting_test.dart' as database_setting_test;
import 'desktop/database/database_share_test.dart' as database_share_test;
import 'desktop/database/database_sort_test.dart' as database_sort_test;
import 'desktop/database/database_view_test.dart' as database_view_test;
import 'desktop/document/document_test_runner.dart' as document_test_runner;
import 'desktop/uncategorized/emoji_shortcut_test.dart' as emoji_shortcut_test;
import 'desktop/uncategorized/empty_test.dart' as first_test;
import 'desktop/uncategorized/hotkeys_test.dart' as hotkeys_test;
import 'desktop/uncategorized/import_files_test.dart' as import_files_test;
import 'desktop/settings/settings_runner.dart' as settings_test_runner;
import 'desktop/uncategorized/share_markdown_test.dart' as share_markdown_test;
import 'desktop/sidebar/sidebar_test_runner.dart' as sidebar_test_runner;
import 'desktop/uncategorized/switch_folder_test.dart' as switch_folder_test;
import 'desktop/uncategorized/tabs_test.dart' as tabs_test;
Future<void> runIntegrationOnDesktop() async {
// This test must be run first, otherwise the CI will fail.
first_test.main();
switch_folder_test.main();
share_markdown_test.main();
import_files_test.main();
// Document integration tests
document_test_runner.startTesting();
// Sidebar integration tests
sidebar_test_runner.startTesting();
// Board integration test
board_test_runner.startTesting();
// Database integration tests
database_cell_test.main();
database_field_test.main();
database_field_settings_test.main();
database_share_test.main();
database_row_page_test.main();
database_row_test.main();
database_setting_test.main();
database_filter_test.main();
database_sort_test.main();
database_view_test.main();
database_calendar_test.main();
// Tabs
tabs_test.main();
// Others
hotkeys_test.main();
emoji_shortcut_test.main();
// Appearance integration test
appearance_test_runner.main();
// User settings
settings_test_runner.main();
}

View File

@ -0,0 +1,44 @@
// ignore_for_file: unused_import
import 'dart:io';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/home/home.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/auth/af_cloud_mock_auth_service.dart';
import 'package:appflowy/user/application/auth/auth_service.dart';
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
import 'package:appflowy/workspace/application/settings/prelude.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/uuid.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:path/path.dart' as p;
import '../../shared/dir.dart';
import '../../shared/mock/mock_file_picker.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('anonymous sign in on mobile', () {
testWidgets('anon user and then sign in', (tester) async {
await tester.initializeAppFlowy(
cloudType: AuthenticatorType.local,
);
// click the anonymousSignInButton
final anonymousSignInButton = find.byType(SignInAnonymousButton);
expect(anonymousSignInButton, findsOneWidget);
await tester.tapButton(anonymousSignInButton);
// expect to see the home page
expect(find.byType(MobileHomeScreen), findsOneWidget);
});
});
}

View File

@ -0,0 +1,5 @@
import 'mobile/sign_in/anonymous_sign_in_test.dart' as anonymous_sign_in_test;
Future<void> runIntegrationOnMobile() async {
anonymous_sign_in_test.main();
}

View File

@ -1,30 +1,9 @@
import 'dart:io';
import 'package:integration_test/integration_test.dart';
import 'appearance_settings_test.dart' as appearance_test_runner;
import 'board/board_test_runner.dart' as board_test_runner;
import 'database/database_calendar_test.dart' as database_calendar_test;
import 'database/database_cell_test.dart' as database_cell_test;
import 'database/database_field_settings_test.dart'
as database_field_settings_test;
import 'database/database_field_test.dart' as database_field_test;
import 'database/database_filter_test.dart' as database_filter_test;
import 'database/database_row_page_test.dart' as database_row_page_test;
import 'database/database_row_test.dart' as database_row_test;
import 'database/database_setting_test.dart' as database_setting_test;
import 'database/database_share_test.dart' as database_share_test;
import 'database/database_sort_test.dart' as database_sort_test;
import 'database/database_view_test.dart' as database_view_test;
import 'document/document_test_runner.dart' as document_test_runner;
import 'empty_test.dart' as first_test;
import 'hotkeys_test.dart' as hotkeys_test;
import 'import_files_test.dart' as import_files_test;
import 'settings/settings_runner.dart' as settings_test_runner;
import 'share_markdown_test.dart' as share_markdown_test;
import 'sidebar/sidebar_test_runner.dart' as sidebar_test_runner;
import 'switch_folder_test.dart' as switch_folder_test;
import 'tabs_test.dart' as tabs_test;
import 'emoji_shortcut_test.dart' as emoji_shortcut_test;
// import 'auth/supabase_auth_test.dart' as supabase_auth_test_runner;
import 'desktop_runner.dart';
import 'mobile_runner.dart';
/// The main task runner for all integration tests in AppFlowy.
///
@ -35,50 +14,11 @@ import 'emoji_shortcut_test.dart' as emoji_shortcut_test;
/// as the test target.
Future<void> main() async {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
// This test must be run first, otherwise the CI will fail.
first_test.main();
switch_folder_test.main();
share_markdown_test.main();
import_files_test.main();
// Document integration tests
document_test_runner.startTesting();
// Sidebar integration tests
sidebar_test_runner.startTesting();
// Board integration test
board_test_runner.startTesting();
// Database integration tests
database_cell_test.main();
database_field_test.main();
database_field_settings_test.main();
database_share_test.main();
database_row_page_test.main();
database_row_test.main();
database_setting_test.main();
database_filter_test.main();
database_sort_test.main();
database_view_test.main();
database_calendar_test.main();
// Tabs
tabs_test.main();
// Others
hotkeys_test.main();
emoji_shortcut_test.main();
// Appearance integration test
appearance_test_runner.main();
// User settings
settings_test_runner.main();
// board_test.main();
// empty_document_test.main();
// smart_menu_test.main();
if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
await runIntegrationOnDesktop();
} else if (Platform.isIOS || Platform.isAndroid) {
await runIntegrationOnMobile();
} else {
throw Exception('Unsupported platform');
}
}

View File

@ -37,9 +37,10 @@ extension AppFlowyTestBase on WidgetTester {
AuthenticatorType? cloudType,
String? email,
}) async {
// view.physicalSize = windowsSize;
await binding.setSurfaceSize(windowSize);
// addTearDown(() => binding.setSurfaceSize(null));
if (Platform.isLinux || Platform.isWindows || Platform.isMacOS) {
// Set the window size
await binding.setSurfaceSize(windowSize);
}
mockHotKeyManagerHandlers();
final applicationDataDirectory = dataDirectory ??
@ -118,7 +119,7 @@ extension AppFlowyTestBase on WidgetTester {
Future<void> waitUntilSignInPageShow() async {
if (isAuthEnabled) {
final finder = find.byType(SignInAnonymousButton);
await pumpUntilFound(finder);
await pumpUntilFound(finder, timeout: const Duration(seconds: 30));
expect(finder, findsOneWidget);
} else {
final finder = find.byType(GoButton);
@ -134,8 +135,9 @@ extension AppFlowyTestBase on WidgetTester {
Future<void> pumpUntilFound(
Finder finder, {
Duration timeout = const Duration(seconds: 10),
Duration pumpInterval =
const Duration(milliseconds: 50), // Interval between pumps
Duration pumpInterval = const Duration(
milliseconds: 50,
), // Interval between pumps
}) async {
bool timerDone = false;
final timer = Timer(timeout, () => timerDone = true);
@ -148,6 +150,24 @@ extension AppFlowyTestBase on WidgetTester {
timer.cancel();
}
Future<void> pumpUntilNotFound(
Finder finder, {
Duration timeout = const Duration(seconds: 10),
Duration pumpInterval = const Duration(
milliseconds: 50,
), // Interval between pumps
}) async {
bool timerDone = false;
final timer = Timer(timeout, () => timerDone = true);
while (!timerDone) {
await pump(pumpInterval); // Pump with an interval
if (!any(finder)) {
break;
}
}
timer.cancel();
}
Future<void> tapButton(
Finder finder, {
int? pointer,

View File

@ -6,10 +6,13 @@ import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/base/emoji_picker_button.dart';
import 'package:appflowy/plugins/document/presentation/share/share_button.dart';
import 'package:appflowy/shared/feature_flags.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/presentation/screens/screens.dart';
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_new_page_button.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_workspace.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/draggable_view_item.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/view_action_type.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/view_add_button.dart';
@ -518,6 +521,51 @@ extension CommonOperations on WidgetTester {
await pumpAndSettle();
}
}
Future<void> openCollaborativeWorkspaceMenu() async {
if (!FeatureFlag.collaborativeWorkspace.isOn) {
throw UnsupportedError('Collaborative workspace is not enabled');
}
final workspace = find.byType(SidebarWorkspace);
expect(workspace, findsOneWidget);
// click it
await tapButton(workspace);
}
Future<void> closeCollaborativeWorkspaceMenu() async {
if (!FeatureFlag.collaborativeWorkspace.isOn) {
throw UnsupportedError('Collaborative workspace is not enabled');
}
await tapAt(Offset.zero);
await pumpAndSettle();
}
Future<void> createCollaborativeWorkspace(String name) async {
if (!FeatureFlag.collaborativeWorkspace.isOn) {
throw UnsupportedError('Collaborative workspace is not enabled');
}
await openCollaborativeWorkspaceMenu();
// expect to see the workspace list, and there should be only one workspace
final workspacesMenu = find.byType(WorkspacesMenu);
expect(workspacesMenu, findsOneWidget);
// click the create button
final createButton = find.byKey(createWorkspaceButtonKey);
expect(createButton, findsOneWidget);
await tapButton(createButton);
// see the create workspace dialog
final createWorkspaceDialog = find.byType(CreateWorkspaceDialog);
expect(createWorkspaceDialog, findsOneWidget);
// input the workspace name
await enterText(find.byType(TextField), name);
await pumpAndSettle();
await tapButtonWithName(LocaleKeys.button_ok.tr());
}
}
extension ViewLayoutPBTest on ViewLayoutPB {

View File

@ -3,7 +3,7 @@ import 'dart:typed_data';
import 'package:appflowy_backend/protobuf/flowy-notification/protobuf.dart';
import 'package:appflowy_result/appflowy_result.dart';
class NotificationParser<T, E> {
class NotificationParser<T, E extends Object> {
NotificationParser({
this.id,
required this.callback,

View File

@ -20,6 +20,7 @@ class OptionColorList extends StatelessWidget {
crossAxisCount: 6,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero,
children: SelectOptionColorPB.values.map(
(colorPB) {
final color = colorPB.toColor(context);

View File

@ -65,7 +65,7 @@ Future<T?> showMobileBottomSheet<T>(
backgroundColor ??= Theme.of(context).brightness == Brightness.light
? const Color(0xFFF7F8FB)
: const Color(0xFF626364);
: const Color(0xFF23262B);
return showModalBottomSheet<T>(
context: context,

View File

@ -39,7 +39,7 @@ Future<T?> showTransitionMobileBottomSheet<T>(
backgroundColor ??= Theme.of(context).brightness == Brightness.light
? const Color(0xFFF7F8FB)
: const Color(0xFF626364);
: const Color(0xFF23262B);
return Navigator.of(
context,

View File

@ -55,7 +55,7 @@ class _MobileDateCellEditScreenState extends State<MobileDateCellEditScreen> {
minChildSize: 0.4,
snapSizes: const [0.4, 0.7, 1.0],
builder: (_, controller) => Material(
color: Theme.of(context).colorScheme.secondaryContainer,
color: Colors.transparent,
child: ListView(
controller: controller,
children: [

View File

@ -47,7 +47,9 @@ Future<FieldType?> showFieldTypeGridBottomSheet(
.map(
(fieldType) => TypeOptionMenuItemValue(
value: fieldType,
backgroundColor: fieldType.mobileIconBackgroundColor,
backgroundColor: Theme.of(context).brightness == Brightness.light
? fieldType.mobileIconBackgroundColor
: fieldType.mobileIconBackgroundColorDark,
text: fieldType.i18n,
icon: fieldType.svgData,
onTap: (context, fieldType) =>
@ -121,7 +123,6 @@ void showQuickEditField(
) {
showMobileBottomSheet(
context,
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
showDragHandle: true,
builder: (context) {
return SingleChildScrollView(

View File

@ -208,7 +208,9 @@ class _MobileFieldEditorState extends State<MobileFieldEditor> {
Widget build(BuildContext context) {
final option = _buildOption();
return Container(
color: Theme.of(context).colorScheme.secondaryContainer,
color: Theme.of(context).brightness == Brightness.light
? const Color(0xFFF7F8FB)
: const Color(0xFF23262B),
height: MediaQuery.of(context).size.height,
child: SingleChildScrollView(
child: Column(
@ -259,6 +261,7 @@ class _MobileFieldEditorState extends State<MobileFieldEditor> {
],
..._buildOptionActions(),
const _Divider(),
VSpace(MediaQuery.viewPaddingOf(context).bottom == 0 ? 28.0 : 16.0),
],
),
),
@ -351,7 +354,7 @@ class _MobileFieldEditorState extends State<MobileFieldEditor> {
}
return [
if (widget.actions.contains(FieldOptionAction.hide))
if (widget.actions.contains(FieldOptionAction.hide) && !widget.isPrimary)
FlowyOptionTile.text(
text: LocaleKeys.grid_field_hide.tr(),
leftIcon: const FlowySvg(FlowySvgs.m_field_hide_s),

View File

@ -3,7 +3,7 @@ import 'package:appflowy/mobile/application/mobile_router.dart';
import 'package:appflowy/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder.dart';
import 'package:appflowy/mobile/presentation/widgets/flowy_mobile_state_container.dart';
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
import 'package:appflowy/workspace/application/menu/menu_bloc.dart';
import 'package:appflowy/workspace/application/menu/sidebar_root_views_bloc.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
import 'package:easy_localization/easy_localization.dart';
@ -27,10 +27,13 @@ class MobileFavoritePageFolder extends StatelessWidget {
return MultiBlocProvider(
providers: [
BlocProvider(
create: (_) => MenuBloc(
user: userProfile,
workspaceId: workspaceSetting.workspaceId,
)..add(const MenuEvent.initial()),
create: (_) => SidebarRootViewsBloc()
..add(
SidebarRootViewsEvent.initial(
userProfile,
workspaceSetting.workspaceId,
),
),
),
BlocProvider(
create: (_) => FavoriteBloc()..add(const FavoriteEvent.initial()),
@ -38,11 +41,11 @@ class MobileFavoritePageFolder extends StatelessWidget {
],
child: MultiBlocListener(
listeners: [
BlocListener<MenuBloc, MenuState>(
BlocListener<SidebarRootViewsBloc, SidebarRootViewState>(
listenWhen: (p, c) =>
p.lastCreatedView?.id != c.lastCreatedView?.id,
p.lastCreatedRootView?.id != c.lastCreatedRootView?.id,
listener: (context, state) =>
context.pushView(state.lastCreatedView!),
context.pushView(state.lastCreatedRootView!),
),
],
child: Builder(

View File

@ -1,7 +1,7 @@
import 'package:appflowy/mobile/application/mobile_router.dart';
import 'package:appflowy/mobile/presentation/home/personal_folder/mobile_home_personal_folder.dart';
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
import 'package:appflowy/workspace/application/menu/menu_bloc.dart';
import 'package:appflowy/workspace/application/menu/sidebar_root_views_bloc.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
@ -26,10 +26,13 @@ class MobileFolders extends StatelessWidget {
return MultiBlocProvider(
providers: [
BlocProvider(
create: (_) => MenuBloc(
user: user,
workspaceId: workspaceSetting.workspaceId,
)..add(const MenuEvent.initial()),
create: (_) => SidebarRootViewsBloc()
..add(
SidebarRootViewsEvent.initial(
user,
workspaceSetting.workspaceId,
),
),
),
BlocProvider(
create: (_) => FavoriteBloc()..add(const FavoriteEvent.initial()),
@ -37,16 +40,16 @@ class MobileFolders extends StatelessWidget {
],
child: MultiBlocListener(
listeners: [
BlocListener<MenuBloc, MenuState>(
BlocListener<SidebarRootViewsBloc, SidebarRootViewState>(
listenWhen: (p, c) =>
p.lastCreatedView?.id != c.lastCreatedView?.id,
p.lastCreatedRootView?.id != c.lastCreatedRootView?.id,
listener: (context, state) =>
context.pushView(state.lastCreatedView!),
context.pushView(state.lastCreatedRootView!),
),
],
child: Builder(
builder: (context) {
final menuState = context.watch<MenuBloc>().state;
final menuState = context.watch<SidebarRootViewsBloc>().state;
return SlidableAutoCloseBehavior(
child: Column(
children: [

Some files were not shown because too many files have changed in this diff Show More