Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/flutter_build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,5 @@ runs:

- uses: actions/upload-artifact@v4
with:
name: ${{ github.run_id }}-${{ matrix.os }}
name: ${{ github.run_id }}-${{ inputs.os }}
path: appflowy_flutter.tar.gz
48 changes: 38 additions & 10 deletions .github/actions/flutter_integration_test/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ name: Flutter Integration Test
description: Run integration tests for AppFlowy

inputs:
os:
description: "The OS to run the tests on"
required: true
test_path:
description: "The path to the integration test file"
required: true
Expand Down Expand Up @@ -49,20 +52,39 @@ runs:
- name: Install prerequisites
working-directory: frontend
run: |
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 keybinder-3.0 libnotify-dev network-manager
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 keybinder-3.0 libnotify-dev network-manager
elif [ "$RUNNER_OS" == "Windows" ]; then
vcpkg integrate install
elif [ "$RUNNER_OS" == "macOS" ]; then
echo 'do nothing'
fi
shell: bash

- name: Enable Flutter Desktop
run: |
flutter config --enable-linux-desktop
if [ "$RUNNER_OS" == "Linux" ]; then
flutter config --enable-linux-desktop
elif [ "$RUNNER_OS" == "Windows" ]; then
flutter config --enable-windows-desktop
elif [ "$RUNNER_OS" == "macOS" ]; then
flutter config --enable-macos-desktop
fi
shell: bash

- uses: actions/download-artifact@v4
with:
name: ${{ github.run_id }}-ubuntu-latest
name: ${{ github.run_id }}-${{ inputs.os }}

- name: Configure Windows long paths
if: runner.os == 'Windows'
shell: pwsh
run: |
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
git config --system core.longpaths true

- name: Uncompressed appflowy_flutter
run: tar -xf appflowy_flutter.tar.gz
Expand All @@ -71,8 +93,14 @@ runs:
- name: Run Flutter integration tests
working-directory: frontend/appflowy_flutter
run: |
export DISPLAY=:99
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &
sudo apt-get install network-manager
flutter test ${{ inputs.test_path }} -d Linux --coverage
if [ "$RUNNER_OS" == "Linux" ]; then
export DISPLAY=:99
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &
sudo apt-get install network-manager
flutter test ${{ inputs.test_path }} -d Linux --coverage
elif [ "$RUNNER_OS" == "Windows" ]; then
flutter test ${{ inputs.test_path }} -d Windows --coverage
elif [ "$RUNNER_OS" == "macOS" ]; then
flutter test ${{ inputs.test_path }} -d macOS --coverage
fi
shell: bash
8 changes: 5 additions & 3 deletions .github/workflows/flutter_ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ jobs:
os: [macos-latest]
include:
- os: macos-latest
flutter_profile: development-mac-x86_64
target: x86_64-apple-darwin
flutter_profile: development-mac-arm64
target: aarch64-apple-darwin
runs-on: ${{ matrix.os }}

steps:
Expand Down Expand Up @@ -339,7 +339,7 @@ jobs:
flutter test integration_test/desktop/cloud/cloud_runner.dart -d Linux --coverage
shell: bash

integration_test:
linux_integration_test:
needs: [prepare-linux]
if: github.event.pull_request.draft != true
strategy:
Expand All @@ -358,8 +358,10 @@ jobs:
- name: Flutter Integration Test ${{ matrix.test_number }}
uses: ./.github/actions/flutter_integration_test
with:
os: ${{ matrix.os }}
test_path: integration_test/desktop_runner_${{ matrix.test_number }}.dart
flutter_version: ${{ env.FLUTTER_VERSION }}
rust_toolchain: ${{ env.RUST_TOOLCHAIN }}
cargo_make_version: ${{ env.CARGO_MAKE_VERSION }}
rust_target: ${{ matrix.target }}

116 changes: 116 additions & 0 deletions .github/workflows/windows_flutter_ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
name: Windows Tests (Flutter)

on:
push:
branches:
- "main"
- "release/*"
paths:
- ".github/workflows/flutter_ci.yaml"
- ".github/actions/flutter_build/**"
- "frontend/rust-lib/**"
- "frontend/appflowy_flutter/**"
- "frontend/resources/**"

pull_request:
branches:
- "main"
- "release/*"
paths:
- ".github/workflows/flutter_ci.yaml"
- ".github/actions/flutter_build/**"
- "frontend/rust-lib/**"
- "frontend/appflowy_flutter/**"
- "frontend/resources/**"

env:
CARGO_TERM_COLOR: always
FLUTTER_VERSION: "3.27.4"
RUST_TOOLCHAIN: "1.81.0"
CARGO_MAKE_VERSION: "0.37.18"
CLOUD_VERSION: 0.6.54-amd64

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
windows_tests:
strategy:
fail-fast: false
matrix:
os: [windows-latest]
include:
- os: windows-latest
flutter_profile: development-windows-x86
target: x86_64-pc-windows-msvc

runs-on: ${{ matrix.os }}

steps:
- name: Checkout source code
uses: actions/checkout@v4

- name: Install Rust toolchain
id: rust_toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_TOOLCHAIN }}
target: ${{ matrix.target }}
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
cache-all-crates: true

- uses: taiki-e/install-action@v2
with:
tool: cargo-make@${{ env.CARGO_MAKE_VERSION }}, duckscript_cli

- name: Install prerequisites
working-directory: frontend
shell: bash
run: |
vcpkg integrate install
vcpkg update
cargo make appflowy-flutter-deps-tools

- name: Build AppFlowy
working-directory: frontend
run: cargo make --profile ${{ matrix.flutter_profile }} appflowy-core-dev
shell: bash

- name: Run code generation
working-directory: frontend
run: cargo make code_generation
shell: bash

- name: Flutter Analyzer
working-directory: frontend/appflowy_flutter
run: flutter analyze .
shell: bash

- name: Run Flutter unit tests
env:
DISABLE_EVENT_LOG: true
DISABLE_CI_TEST_LOG: "true"
working-directory: frontend
run: cargo make dart_unit_test_no_build
shell: bash

- name: Run Flutter integration tests
working-directory: frontend/appflowy_flutter
run: flutter test integration_test/runner.dart -d Windows --coverage
shell: bash
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,9 @@ void main() {
await tester.tapButton(menu);

final convertToLinkButton = find.text(
LocaleKeys.document_plugins_linkPreview_linkPreviewMenu_toUrl.tr(),
);
LocaleKeys.document_plugins_linkPreview_linkPreviewMenu_toUrl
.tr(),
);
expect(convertToLinkButton, findsOneWidget);
await tester.tapButton(convertToLinkButton);
},
Expand Down Expand Up @@ -384,7 +385,6 @@ void main() {
expect(node.attributes[LinkPreviewBlockKeys.url], url);
});


await tester.simulateKeyEvent(
LogicalKeyboardKey.keyZ,
isControlPressed:
Expand Down Expand Up @@ -483,16 +483,6 @@ void main() {
});
});

testWidgets('paste image url without extension', (tester) async {
const plainText =
'https://images.unsplash.com/photo-1469474968028-56623f02e42e?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&dl=david-marcu-78A265wPiO4-unsplash.jpg&w=640';
await tester.pasteContent(plainText: plainText, (editorState) {
final node = editorState.getNodeAtPath([0])!;
expect(node.type, ImageBlockKeys.type);
expect(node.attributes[ImageBlockKeys.url], isNotEmpty);
});
});

const testMarkdownText = '''
# I'm h1
## I'm h2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ void main() {
await tester.initializeAppFlowy();

await tester.tapAnonymousSignInButton();
final finder = find.text(gettingStarted, findRichText: true);
await tester.pumpUntilFound(finder, timeout: const Duration(seconds: 2));

// create a new document
const pageName = 'Test Document';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/clipboard_service.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/desktop_toolbar/link/link_hover_menu.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/link_embed/link_embed_block_component.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/link_embed/link_embed_menu.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/link_preview/custom_link_preview_block_component.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/link_preview/link_preview_menu.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/link_preview/paste_as/paste_as_menu.dart';
Expand Down Expand Up @@ -397,7 +398,7 @@ void main() {

Future<void> hoverAndConvert(
WidgetTester tester,
PasteMenuType command,
LinkEmbedConvertCommand command,
) async {
final embed = find.byType(LinkEmbedBlockComponent);
expect(embed, findsOneWidget);
Expand Down Expand Up @@ -425,7 +426,7 @@ void main() {
final link = avaliableLink;
await preparePage(tester);
await pasteAsEmbed(tester, link);
await hoverAndConvert(tester, PasteMenuType.mention);
await hoverAndConvert(tester, LinkEmbedConvertCommand.toMention);
final node = tester.editor.getNodeAtPath([0]);
checkMention(node, link);
});
Expand All @@ -434,7 +435,7 @@ void main() {
final link = avaliableLink;
await preparePage(tester);
await pasteAsEmbed(tester, link);
await hoverAndConvert(tester, PasteMenuType.url);
await hoverAndConvert(tester, LinkEmbedConvertCommand.toURL);
final node = tester.editor.getNodeAtPath([0]);
checkUrl(node, link);
});
Expand All @@ -444,7 +445,7 @@ void main() {
final link = avaliableLink;
await preparePage(tester);
await pasteAsEmbed(tester, link);
await hoverAndConvert(tester, PasteMenuType.bookmark);
await hoverAndConvert(tester, LinkEmbedConvertCommand.toBookmark);
final node = tester.editor.getNodeAtPath([0]);
checkBookmark(node, link);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,10 @@ extension CommonOperations on WidgetTester {
} else {
// cloud version
final anonymousButton = find.byType(SignInAnonymousButtonV2);
await tapButton(anonymousButton);
await tapButton(anonymousButton, warnIfMissed: true);
}

if (Platform.isWindows) {
await pumpAndSettle(const Duration(milliseconds: 200));
}
await pumpAndSettle(const Duration(milliseconds: 200));
}

Future<void> tapContinousAnotherWay() async {
Expand Down
22 changes: 12 additions & 10 deletions frontend/appflowy_flutter/lib/core/helpers/url_launcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,18 @@ Future<bool> afLaunchUri(
}

// try to launch the uri directly
bool result;
try {
result = await launcher.launchUrl(
uri,
mode: mode,
webOnlyWindowName: webOnlyWindowName,
);
} on PlatformException catch (e) {
Log.error('Failed to open uri: $e');
return false;
bool result = await launcher.canLaunchUrl(uri);
if (result) {
try {
result = await launcher.launchUrl(
uri,
mode: mode,
webOnlyWindowName: webOnlyWindowName,
);
} on PlatformException catch (e) {
Log.error('Failed to open uri: $e');
return false;
}
}

// if the uri is not a valid url, try to launch it with http scheme
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class MobileViewPageMoreBottomSheet extends StatelessWidget {
break;
case MobileViewBottomSheetBodyAction.delete:
context.read<ViewBloc>().add(const ViewEvent.delete());
context.pop();
Navigator.of(context).pop();
break;
case MobileViewBottomSheetBodyAction.addToFavorites:
_addFavorite(context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ class MobileViewBottomSheetBody extends StatelessWidget {
),
_divider(),
..._buildPublishActions(context),
_divider(),

MobileQuickActionButton(
text: LocaleKeys.button_delete.tr(),
textColor: Theme.of(context).colorScheme.error,
Expand Down Expand Up @@ -236,6 +236,7 @@ class MobileViewBottomSheetBody extends StatelessWidget {
MobileViewBottomSheetBodyAction.unpublish,
),
),
_divider(),
];
} else {
return [
Expand All @@ -246,6 +247,7 @@ class MobileViewBottomSheetBody extends StatelessWidget {
MobileViewBottomSheetBodyAction.publish,
),
),
_divider(),
];
}
}
Expand Down
Loading
Loading