Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09f5317768 | ||
|
|
b2f0c4f109 | ||
|
|
da5b369aec | ||
|
|
a92f3d30c2 | ||
|
|
5c96a2c5cb | ||
|
|
31798959c7 | ||
|
|
5479d3ec6e | ||
|
|
5777830730 | ||
|
|
79ea485a27 | ||
|
|
f0d8eee8a0 | ||
|
|
83b18c4825 | ||
|
|
429892aefc | ||
|
|
d56de308e1 | ||
|
|
3171712380 | ||
|
|
47d321b8c2 | ||
|
|
9536cde789 | ||
|
|
3e32fac876 | ||
|
|
81594fa796 | ||
|
|
db6767f61e | ||
|
|
5ceb132b0b | ||
|
|
587de161f6 | ||
|
|
7ca3f215a3 | ||
|
|
2f386ff24d | ||
|
|
33dd21f4a5 | ||
|
|
65e7e2347a | ||
|
|
8ade3b5f73 | ||
|
|
0ace832374 | ||
|
|
382ce827c1 | ||
|
|
c97ece5e81 | ||
|
|
046e0bac36 | ||
|
|
58fb529eaa | ||
|
|
38fe61ff69 | ||
|
|
e8931c5bd2 | ||
|
|
a25c728866 | ||
|
|
e022ee88da | ||
|
|
dff3ea60bd | ||
|
|
419600ca11 | ||
|
|
4da624d2d3 | ||
|
|
acec664879 | ||
|
|
682f2a6a3b | ||
|
|
5a00361207 | ||
|
|
096a01ed44 | ||
|
|
1816b15b55 | ||
|
|
7576796e2f | ||
|
|
555649c535 | ||
|
|
440253f0d9 | ||
|
|
75e51fdeea | ||
|
|
723423d423 | ||
|
|
893d23d6a3 | ||
|
|
932a403b5d | ||
|
|
53dbef25ab | ||
|
|
129d56e494 | ||
|
|
3f9f53c7a1 | ||
|
|
419464c175 | ||
|
|
adc2ee755e | ||
|
|
c2c84a5812 | ||
|
|
0e7b3c7db2 | ||
|
|
dc8f632e3e | ||
|
|
3f4a409364 | ||
|
|
490cb48354 | ||
|
|
97575d4f6a | ||
|
|
e16e8693c8 | ||
|
|
60acf8c889 | ||
|
|
bf98a627b9 | ||
|
|
6e5b346f25 | ||
|
|
a1b183f330 | ||
|
|
b8e3de97a5 | ||
|
|
84559afefa | ||
|
|
de3e7ca9be | ||
|
|
701384cd74 | ||
|
|
477e43b5e6 | ||
|
|
755083509f | ||
|
|
91e00d3782 | ||
|
|
3f0b3478c1 | ||
|
|
b307312a71 | ||
|
|
c0642d3ff3 | ||
|
|
99ee60a60d | ||
|
|
27ff5f07ab | ||
|
|
e2e38f72bb | ||
|
|
c1006c18c3 | ||
|
|
4e99952b0e | ||
|
|
98876b149f | ||
|
|
370f8a6558 | ||
|
|
40b710d140 | ||
|
|
8c8be741b0 | ||
|
|
96af517c65 | ||
|
|
5f8ef3856a | ||
|
|
37f521ae57 | ||
|
|
ef9891abfe | ||
|
|
9201cd6347 | ||
|
|
73df51f35f | ||
|
|
b2fb631500 | ||
|
|
7a9cb03c8e | ||
|
|
d19fa5a34a | ||
|
|
822d62b562 | ||
|
|
cb617cd9d3 | ||
|
|
7375349626 | ||
|
|
fdc105a3e8 | ||
|
|
b557f89829 | ||
|
|
0f006fa60b | ||
|
|
452974ab99 | ||
|
|
a16196eee5 | ||
|
|
31a33fdbfd | ||
|
|
bb414c3fd6 | ||
|
|
8d01d54e7f | ||
|
|
6d4cfe7316 | ||
|
|
57e3a2ce68 | ||
|
|
ac34617e51 | ||
|
|
8776ac5c36 | ||
|
|
3e1b4d81c1 | ||
|
|
aecea10fd2 | ||
|
|
5a837a9482 | ||
|
|
1a34366a3f | ||
|
|
191a077a86 | ||
|
|
25d4b4f718 | ||
|
|
48cac4c5ac | ||
|
|
80e210b34a | ||
|
|
b57a870242 | ||
|
|
fd81d64a32 | ||
|
|
bf70be1841 | ||
|
|
af16299c83 | ||
|
|
bb865c8f33 | ||
|
|
0f48310e22 | ||
|
|
2c8fa1a2c3 | ||
|
|
3dcf435f7d | ||
|
|
9c3be7e488 | ||
|
|
c48001bd74 | ||
|
|
7afae69fe4 | ||
|
|
dd3f8b247a | ||
|
|
b4c8011881 | ||
|
|
f404882343 | ||
|
|
fb887bec10 | ||
|
|
4b5195d891 | ||
|
|
ddd4ba8287 | ||
|
|
05f3885346 | ||
|
|
70404816e7 | ||
|
|
14f789f50b | ||
|
|
574cca0a8b | ||
|
|
f9c1cadbe0 | ||
|
|
6bac0412eb | ||
|
|
2a65c193c2 | ||
|
|
cd245b5f0a | ||
|
|
677617dcf2 | ||
|
|
a180cfcdc2 | ||
|
|
0f13f86917 | ||
|
|
3d8ff062b5 | ||
|
|
780f08dd28 | ||
|
|
270d1c68b2 | ||
|
|
88d14e7bde | ||
|
|
90ebcb4cfc | ||
|
|
a1823fa4c0 | ||
|
|
f484675008 | ||
|
|
f5cb8b6d25 | ||
|
|
6e2caf3358 | ||
|
|
66aea29ab7 | ||
|
|
3b0d82287d | ||
|
|
b05897d3ab | ||
|
|
2ec6250ddd | ||
|
|
ff8eb0d479 | ||
|
|
c8e86f4f26 | ||
|
|
c0210a5778 | ||
|
|
5daf9d23f5 | ||
|
|
b087a9aeb3 | ||
|
|
107e3cea4f | ||
|
|
ba965caa8f | ||
|
|
2af93a9bcb | ||
|
|
f8962edfd7 | ||
|
|
b236afd0c3 | ||
|
|
8944edf75f | ||
|
|
6b05be2362 | ||
|
|
90146148b6 | ||
|
|
63464cbf2e | ||
|
|
1fadb15351 | ||
|
|
8732c3c28b | ||
|
|
f7233f6949 | ||
|
|
8c7ed808a7 | ||
|
|
b38fc43300 | ||
|
|
f4170755fa | ||
|
|
79585d0835 | ||
|
|
835563f81b | ||
|
|
37bc5b3fbf | ||
|
|
682bf19838 | ||
|
|
f4ca3ef782 | ||
|
|
f826d05f03 | ||
|
|
01f2b15f70 | ||
|
|
2d6856a23d | ||
|
|
2286a1c726 | ||
|
|
ef90c35175 | ||
|
|
af12beb1c3 | ||
|
|
0d68c42aab | ||
|
|
0cffe42d80 | ||
|
|
abd08e5e53 | ||
|
|
e250f780a4 | ||
|
|
980bebf86a | ||
|
|
26f8397624 | ||
|
|
d67e904f56 | ||
|
|
f36ca3777b | ||
|
|
74233d2606 | ||
|
|
faea0fa532 | ||
|
|
3454af1caa | ||
|
|
8d50ad2936 | ||
|
|
daedf95c95 | ||
|
|
95bfda9dc6 | ||
|
|
93664167e0 | ||
|
|
dfe3b0a929 | ||
|
|
e2028ac5a0 | ||
|
|
c9dc24a13c | ||
|
|
609557c357 | ||
|
|
93af6e69a1 | ||
|
|
b75947b630 | ||
|
|
b60d25a0e3 | ||
|
|
537fa52e77 | ||
|
|
d861ce6227 | ||
|
|
c3e5aa29fc | ||
|
|
4ca3ba8e08 | ||
|
|
f5cc6521fb | ||
|
|
cea1c17b76 | ||
|
|
2abb396467 | ||
|
|
236b5bfe90 | ||
|
|
fa3bc97698 | ||
|
|
c0796e8ae5 | ||
|
|
acd75befbc | ||
|
|
746f0817bc | ||
|
|
c0b667b4ea | ||
|
|
ef83688907 | ||
|
|
c06a0346d8 | ||
|
|
4a0c48f419 | ||
|
|
7802c75d7c | ||
|
|
f1831d07af | ||
|
|
6636731487 | ||
|
|
a4a2a4088b | ||
|
|
c500cd1287 | ||
|
|
6f173c2ada | ||
|
|
34fb1bcfa4 | ||
|
|
58aa73b5be | ||
|
|
334aedd6c6 | ||
|
|
a6c6aa819c | ||
|
|
15c9a67028 | ||
|
|
42cb032bca | ||
|
|
a3a5709b70 | ||
|
|
3a4247c304 | ||
|
|
8eaadccda0 | ||
|
|
2b6b10788d | ||
|
|
26f8bbf7c6 | ||
|
|
252699d249 | ||
|
|
b2e55c4e2e | ||
|
|
d5ee372131 | ||
|
|
39588a4731 | ||
|
|
211559ed6e | ||
|
|
a637517413 | ||
|
|
ddbe0fa698 | ||
|
|
ee61ef3f12 | ||
|
|
54bfc65664 | ||
|
|
c159a5e42b | ||
|
|
1311e2d379 | ||
|
|
e6aa57275a | ||
|
|
d690ca2751 | ||
|
|
3e0a003872 | ||
|
|
e81a2ff577 | ||
|
|
b356927e60 | ||
|
|
1894409dc3 | ||
|
|
f29f1bae32 | ||
|
|
45054e7639 | ||
|
|
3b51a6e6be | ||
|
|
747fe40648 | ||
|
|
60fc5bb2c8 | ||
|
|
9d71464f1a | ||
|
|
92ceb2cd7d | ||
|
|
0db21b91a3 | ||
|
|
88e9d63a13 | ||
|
|
3129fa6cc1 | ||
|
|
db5372c18e | ||
|
|
b781c9aa0f | ||
|
|
a9c6b80f4a | ||
|
|
271f781cce | ||
|
|
ef4bce25d8 | ||
|
|
95c4cb241a | ||
|
|
e20d938ce3 | ||
|
|
a515715543 | ||
|
|
fda70ff560 | ||
|
|
08938b8c70 | ||
|
|
250f29f325 | ||
|
|
d117cd6b5b | ||
|
|
ca93cb20ec | ||
|
|
8c1d0106dd | ||
|
|
5cbc8b1e18 | ||
|
|
274742e334 | ||
|
|
792f56db79 | ||
|
|
458d3f971b | ||
|
|
2ffd6bf7ea | ||
|
|
722691c922 | ||
|
|
9746852b5f | ||
|
|
5b030303a6 | ||
|
|
1e4f342fc3 | ||
|
|
4f0379bdd7 | ||
|
|
ce261c9128 | ||
|
|
20391bfec4 | ||
|
|
9d28360887 | ||
|
|
99f9cb2a09 | ||
|
|
247405ff51 | ||
|
|
d27e2179cc | ||
|
|
100cc19747 | ||
|
|
fa66a119ed | ||
|
|
a9787546b4 | ||
|
|
5cbe90c79f | ||
|
|
a143a030a9 | ||
|
|
caede19267 | ||
|
|
d410ffbaa8 | ||
|
|
0483e305e7 | ||
|
|
f6242f1cc7 | ||
|
|
18c7fff34b | ||
|
|
792573f46d | ||
|
|
e9d7d0b7b3 | ||
|
|
0b7ae734a1 | ||
|
|
c0aef8f4fe | ||
|
|
55c97b56a3 | ||
|
|
86a0569d84 | ||
|
|
5b3b0e54d9 | ||
|
|
f1e380c276 | ||
|
|
ea93f0e141 | ||
|
|
c1433ce38a | ||
|
|
831586293e | ||
|
|
5c5b6d02e8 | ||
|
|
8937856d36 | ||
|
|
63c22feb8f | ||
|
|
05a06980b9 | ||
|
|
7be29c04a2 | ||
|
|
5a9a1e60e6 | ||
|
|
4811e65efa | ||
|
|
72a23bfe82 | ||
|
|
ed78cb4efc | ||
|
|
d2cc799861 | ||
|
|
2e7a97c8a2 | ||
|
|
64cd7d41ca | ||
|
|
0e3ffa8fd5 | ||
|
|
be00980fdd | ||
|
|
7fbaf204ef | ||
|
|
acc03b8cc4 | ||
|
|
747abba87f | ||
|
|
e88fb533c8 | ||
|
|
3f896ad64f | ||
|
|
6591d5de52 | ||
|
|
a1abcd7626 | ||
|
|
18a355601a | ||
|
|
c2fdfb6e89 | ||
|
|
baa7c8d826 | ||
|
|
8105da1c2b | ||
|
|
827e41348b | ||
|
|
e239ba46aa | ||
|
|
2554ba81b5 | ||
|
|
84d171b1db | ||
|
|
38902ed599 | ||
|
|
2cdee386c2 | ||
|
|
90516b6adc | ||
|
|
c4acba8216 | ||
|
|
4404e0d727 | ||
|
|
48c6c635f7 | ||
|
|
332f40c915 | ||
|
|
2b32f0eff0 | ||
|
|
7d20ca5a77 | ||
|
|
0a0f2adf76 | ||
|
|
4852e5c8d4 | ||
|
|
65f1db776b | ||
|
|
38c3e700e9 | ||
|
|
15cb1b5f19 | ||
|
|
1bf1d03676 | ||
|
|
f612d9b701 | ||
|
|
595f1f6ef8 | ||
|
|
c8e9adb81d | ||
|
|
6d3a7545a6 | ||
|
|
6739af2be1 | ||
|
|
c41a7aaacf | ||
|
|
d200c409d6 | ||
|
|
cd28dee7bd | ||
|
|
7e82a08b54 | ||
|
|
f0bd50b246 | ||
|
|
e571eb9881 | ||
|
|
c4f4bcf457 | ||
|
|
9500abb363 | ||
|
|
690a3746fa | ||
|
|
cd82c13753 | ||
|
|
032a648204 | ||
|
|
f64ee912d0 | ||
|
|
307556b7dd | ||
|
|
dd8b9dd43e | ||
|
|
6e41359fc5 | ||
|
|
b1cc4e485b | ||
|
|
239bf2fa70 | ||
|
|
a6baabbafc | ||
|
|
a954b5ffd8 | ||
|
|
36b88c602c | ||
|
|
190fae196f | ||
|
|
347698f68f | ||
|
|
db2e23172a | ||
|
|
dcb070909c | ||
|
|
332a677d20 | ||
|
|
75d394fb6e | ||
|
|
875b9d6cfc | ||
|
|
e9326d49c0 | ||
|
|
4ee6e297c6 | ||
|
|
c4ebccafd4 | ||
|
|
94bdefbf01 | ||
|
|
ba482a30a3 | ||
|
|
76416cfdba | ||
|
|
2557e4f3cc | ||
|
|
79c912219d | ||
|
|
89370b4a55 | ||
|
|
ecbc2601c4 | ||
|
|
f3753435e6 | ||
|
|
1eeb812a1c | ||
|
|
6dba118413 | ||
|
|
ee7fc5d77d | ||
|
|
e7533c149f | ||
|
|
bdec917a35 | ||
|
|
76a3daecaf | ||
|
|
ed1952d6a9 | ||
|
|
5a87229fe9 | ||
|
|
eac878d563 | ||
|
|
de08c01c4c | ||
|
|
7937fd1f3a | ||
|
|
eef5c2bf66 | ||
|
|
9c769cd7e5 | ||
|
|
eac58dc212 | ||
|
|
d3241cdecb | ||
|
|
857f645131 | ||
|
|
2521611d6a | ||
|
|
5facb61e23 | ||
|
|
2f6a4f8c7b | ||
|
|
84b8b92582 | ||
|
|
827d7c381e | ||
|
|
b0bf99da34 | ||
|
|
ca50e56474 | ||
|
|
36cf653d64 | ||
|
|
8ccd1ec72c | ||
|
|
7ba3020ab3 | ||
|
|
50694bb589 | ||
|
|
206ccb2c43 | ||
|
|
d2ccec79e4 | ||
|
|
69469e9989 | ||
|
|
c821b8c4fe | ||
|
|
93786bad44 | ||
|
|
f5bfcdcb98 | ||
|
|
d57b61b213 | ||
|
|
43a3a1e4b2 | ||
|
|
65f3296508 | ||
|
|
5cede74c89 | ||
|
|
54fcc4ac5b | ||
|
|
2ca911950c | ||
|
|
462b67def9 | ||
|
|
30a28b12d1 | ||
|
|
0b3c904984 | ||
|
|
1e16168a3d | ||
|
|
f5db384fc2 | ||
|
|
ce58737ec5 | ||
|
|
ca7b186325 | ||
|
|
d05b633b9b | ||
|
|
1cde5a0df6 | ||
|
|
df8409178b | ||
|
|
121ed5a06e | ||
|
|
29e80a0f32 | ||
|
|
a49b009980 | ||
|
|
9b55f5bc7f | ||
|
|
0371a28a42 | ||
|
|
ce51491cf6 | ||
|
|
c033d56978 | ||
|
|
a4a21c7e94 | ||
|
|
851296fa0e | ||
|
|
c3b183504f | ||
|
|
363bb3e45e | ||
|
|
acc93a603d | ||
|
|
8045042e78 | ||
|
|
1401ba5960 | ||
|
|
0730a0caf4 | ||
|
|
13260e1db8 | ||
|
|
4fa08fda02 | ||
|
|
2042394501 | ||
|
|
bbeae74ebd | ||
|
|
3aad1c5bcd | ||
|
|
f760e3d12a | ||
|
|
890285bb7b | ||
|
|
366e28752c | ||
|
|
6ecc3c9076 | ||
|
|
f5a9f2bf4d | ||
|
|
d68c847d59 | ||
|
|
9a1ea138fc | ||
|
|
b466b425a5 | ||
|
|
15aefaa956 | ||
|
|
e7bdce0997 | ||
|
|
44e48712a6 | ||
|
|
7d512578b2 | ||
|
|
0783f94cd6 | ||
|
|
eef34caf27 | ||
|
|
5ef9d55dca | ||
|
|
781fbf1b30 | ||
|
|
60ba775bed | ||
|
|
d862455342 | ||
|
|
d26606d3d3 | ||
|
|
6cece56ca7 | ||
|
|
2b096e967d | ||
|
|
7884fd1913 | ||
|
|
3f9b598493 | ||
|
|
d5b9063f78 | ||
|
|
b80b222527 | ||
|
|
c175947818 | ||
|
|
b7b8713cd9 | ||
|
|
81e09ae72e | ||
|
|
4e6643eca8 | ||
|
|
7586930ef0 | ||
|
|
e9a4efb67d | ||
|
|
eff06a1f74 | ||
|
|
775955df5c | ||
|
|
8cf6ab32f0 | ||
|
|
177cca60c4 | ||
|
|
649545cdf3 | ||
|
|
2a421034d9 | ||
|
|
ef49cb6577 | ||
|
|
6338ca1417 | ||
|
|
acb3c795d0 | ||
|
|
4405b597cd | ||
|
|
a7ce21e941 | ||
|
|
05bdd052ab | ||
|
|
d86431dfbc | ||
|
|
4837d7f7fe | ||
|
|
d765806337 |
No files matched your search
@@ -0,0 +1,97 @@
|
||||
name: Flutter Integration Test
|
||||
description: Run integration tests for AppFlowy
|
||||
|
||||
inputs:
|
||||
os:
|
||||
description: "The operating system to run the tests on"
|
||||
required: true
|
||||
flutter_version:
|
||||
description: "The version of Flutter to use"
|
||||
required: true
|
||||
rust_toolchain:
|
||||
description: "The version of Rust to use"
|
||||
required: true
|
||||
cargo_make_version:
|
||||
description: "The version of cargo-make to use"
|
||||
required: true
|
||||
rust_target:
|
||||
description: "The target to build for"
|
||||
required: true
|
||||
flutter_profile:
|
||||
description: "The profile to build with"
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ inputs.rust_toolchain }}
|
||||
target: ${{ inputs.rust_target }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ inputs.flutter_version }}
|
||||
cache: true
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: ${{ inputs.os }}
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
cache-all-crates: true
|
||||
|
||||
- uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: cargo-make@${{ inputs.cargo_make_version }}, duckscript_cli
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
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
|
||||
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 ${{ inputs.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: Compress appflowy_flutter
|
||||
run: tar -czf appflowy_flutter.tar.gz frontend/appflowy_flutter
|
||||
shell: bash
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ github.run_id }}-${{ matrix.os }}
|
||||
path: appflowy_flutter.tar.gz
|
||||
@@ -0,0 +1,78 @@
|
||||
name: Flutter Integration Test
|
||||
description: Run integration tests for AppFlowy
|
||||
|
||||
inputs:
|
||||
test_path:
|
||||
description: "The path to the integration test file"
|
||||
required: true
|
||||
flutter_version:
|
||||
description: "The version of Flutter to use"
|
||||
required: true
|
||||
rust_toolchain:
|
||||
description: "The version of Rust to use"
|
||||
required: true
|
||||
cargo_make_version:
|
||||
description: "The version of cargo-make to use"
|
||||
required: true
|
||||
rust_target:
|
||||
description: "The target to build for"
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ inputs.RUST_TOOLCHAIN }}
|
||||
target: ${{ inputs.rust_target }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ inputs.flutter_version }}
|
||||
cache: true
|
||||
|
||||
- uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: cargo-make@${{ inputs.cargo_make_version }}
|
||||
|
||||
- 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
|
||||
shell: bash
|
||||
|
||||
- name: Enable Flutter Desktop
|
||||
run: |
|
||||
flutter config --enable-linux-desktop
|
||||
shell: bash
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ${{ github.run_id }}-ubuntu-latest
|
||||
|
||||
- name: Uncompressed appflowy_flutter
|
||||
run: tar -xf appflowy_flutter.tar.gz
|
||||
shell: bash
|
||||
|
||||
- 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
|
||||
shell: bash
|
||||
@@ -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
|
||||
@@ -0,0 +1,28 @@
|
||||
name: Build Bot
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
dispatch_slash_command:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# get build name from pubspec.yaml
|
||||
- name: Get build version
|
||||
working-directory: frontend/appflowy_flutter
|
||||
id: get_build_name
|
||||
run: |
|
||||
echo "fetching version from pubspec.yaml..."
|
||||
echo "build_name=$(grep 'version: ' pubspec.yaml | awk '{print $2}')" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: peter-evans/slash-command-dispatch@v4
|
||||
with:
|
||||
token: ${{ secrets.PAT }}
|
||||
commands: build
|
||||
static-args: |
|
||||
ref=refs/pull/${{ github.event.issue.number }}/head
|
||||
build_name=${{ steps.get_build_name.outputs.build_name }}
|
||||
@@ -0,0 +1,42 @@
|
||||
name: build
|
||||
|
||||
on:
|
||||
repository_dispatch:
|
||||
types: [build-command]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: notify appflowy_builder
|
||||
run: |
|
||||
platform=${{ github.event.client_payload.slash_command.args.unnamed.arg1 }}
|
||||
build_name=${{ github.event.client_payload.slash_command.args.named.build_name }}
|
||||
branch=${{ github.event.client_payload.slash_command.args.named.ref }}
|
||||
build_type=""
|
||||
arch=""
|
||||
|
||||
if [ "$platform" = "android" ]; then
|
||||
build_type="apk"
|
||||
elif [ "$platform" = "macos" ]; then
|
||||
arch="universal"
|
||||
fi
|
||||
|
||||
params=$(jq -n \
|
||||
--arg ref "main" \
|
||||
--arg repo "LucasXu0/AppFlowy" \
|
||||
--arg branch "$branch" \
|
||||
--arg build_name "$build_name" \
|
||||
--arg build_type "$build_type" \
|
||||
--arg arch "$arch" \
|
||||
'{ref: $ref, inputs: {repo: $repo, branch: $branch, build_name: $build_name, build_type: $build_type, arch: $arch}} | del(.inputs | .. | select(. == ""))')
|
||||
|
||||
echo "params: $params"
|
||||
|
||||
curl -L \
|
||||
-X POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "Authorization: Bearer ${{ secrets.TOKEN }}" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
https://api.github.com/repos/AppFlowy-IO/AppFlowy-Builder/actions/workflows/$platform.yaml/dispatches \
|
||||
-d "$params"
|
||||
@@ -5,8 +5,7 @@ jobs:
|
||||
commitlint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: wagoid/commitlint-github-action@v4
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
name: Deploy Web (Test)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- build/test
|
||||
- main
|
||||
env:
|
||||
NODE_VERSION: "18.16.0"
|
||||
PNPM_VERSION: "8.5.0"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.WEB_TEST_SSH_PRIVATE_KEY }}
|
||||
REMOTE_HOST: ${{ secrets.WEB_TEST_REMOTE_HOST }}
|
||||
REMOTE_USER: ${{ secrets.WEB_TEST_REMOTE_USER }}
|
||||
SSL_CERTIFICATE: ${{ secrets.WEB_TEST_SSL_CERTIFICATE }}
|
||||
SSL_CERTIFICATE_KEY: ${{ secrets.WEB_TEST_SSL_CERTIFICATE_KEY }}
|
||||
ENV_FILE: test.env
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
- name: setup pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
- name: Node_modules cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: frontend/appflowy_web_app/node_modules
|
||||
key: node-modules-${{ runner.os }}
|
||||
- name: install frontend dependencies
|
||||
working-directory: frontend/appflowy_web_app
|
||||
run: |
|
||||
pnpm install
|
||||
- name: copy env file
|
||||
working-directory: frontend/appflowy_web_app
|
||||
run: |
|
||||
cp ${{ env.ENV_FILE }} .env
|
||||
- name: test and lint
|
||||
working-directory: frontend/appflowy_web_app
|
||||
run: |
|
||||
pnpm run lint
|
||||
- name: build
|
||||
working-directory: frontend/appflowy_web_app
|
||||
run: |
|
||||
pnpm run build
|
||||
- name: generate SSL certificate
|
||||
run: |
|
||||
echo "${{ env.SSL_CERTIFICATE }}" > nginx-signed.crt
|
||||
echo "${{ env.SSL_CERTIFICATE_KEY }}" > nginx-signed.key
|
||||
- name: Deploy to EC2
|
||||
uses: easingthemes/ssh-deploy@main
|
||||
with:
|
||||
SSH_PRIVATE_KEY: ${{ env.SSH_PRIVATE_KEY }}
|
||||
ARGS: "-rlgoDzvc -i"
|
||||
SOURCE: "frontend/appflowy_web_app/dist frontend/appflowy_web_app/Dockerfile frontend/appflowy_web_app/nginx.conf frontend/appflowy_web_app/.env nginx-signed.crt nginx-signed.key"
|
||||
REMOTE_HOST: ${{ env.REMOTE_HOST }}
|
||||
REMOTE_USER: ${{ env.REMOTE_USER }}
|
||||
EXCLUDE: "frontend/appflowy_web_app/dist/, frontend/appflowy_web_app/node_modules/"
|
||||
SCRIPT_AFTER: |
|
||||
docker build -t appflowy-web-app .
|
||||
docker rm -f appflowy-web-app || true
|
||||
docker run -d -p 80:80 -p 443:443 --name appflowy-web-app appflowy-web-app
|
||||
@@ -7,19 +7,13 @@ on:
|
||||
- release/*
|
||||
paths:
|
||||
- frontend/**
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- release/*
|
||||
paths:
|
||||
- frontend/**
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- unlocked
|
||||
- ready_for_review
|
||||
types: [opened, synchronize, reopened, unlocked, ready_for_review]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
@@ -31,7 +25,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Compose
|
||||
run: |
|
||||
docker-compose --version || {
|
||||
echo "Docker Compose not found, installing..."
|
||||
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
docker-compose --version
|
||||
}
|
||||
|
||||
- name: Build the app
|
||||
shell: bash
|
||||
@@ -45,4 +48,4 @@ jobs:
|
||||
else \
|
||||
echo "$line"; \
|
||||
fi; \
|
||||
done \
|
||||
done
|
||||
+142
-265
@@ -4,27 +4,29 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "develop"
|
||||
- "release/*"
|
||||
paths:
|
||||
- ".github/workflows/flutter_ci.yaml"
|
||||
- "frontend/**"
|
||||
- "!frontend/appflowy_tauri/**"
|
||||
- ".github/actions/flutter_build/**"
|
||||
- "frontend/rust-lib/**"
|
||||
- "frontend/appflowy_flutter/**"
|
||||
- "frontend/resources/**"
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- "main"
|
||||
- "develop"
|
||||
- "release/*"
|
||||
paths:
|
||||
- ".github/workflows/flutter_ci.yaml"
|
||||
- "frontend/**"
|
||||
- "!frontend/appflowy_tauri/**"
|
||||
- ".github/actions/flutter_build/**"
|
||||
- "frontend/rust-lib/**"
|
||||
- "frontend/appflowy_flutter/**"
|
||||
- "frontend/resources/**"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
FLUTTER_VERSION: "3.13.9"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
FLUTTER_VERSION: "3.19.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
CARGO_MAKE_VERSION: "0.36.6"
|
||||
|
||||
concurrency:
|
||||
@@ -32,28 +34,21 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
prepare-linux:
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
os: [ubuntu-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
flutter_profile: development-linux-x86_64
|
||||
target: x86_64-unknown-linux-gnu
|
||||
- os: macos-latest
|
||||
flutter_profile: development-mac-x86_64
|
||||
target: x86_64-apple-darwin
|
||||
- os: windows-latest
|
||||
flutter_profile: development-windows-x86
|
||||
target: x86_64-pc-windows-msvc
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
# 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
|
||||
@@ -61,74 +56,72 @@ jobs:
|
||||
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
|
||||
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
- name: Flutter build
|
||||
uses: ./.github/actions/flutter_build
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
target: ${{ matrix.target }}
|
||||
override: true
|
||||
profile: minimal
|
||||
os: ${{ matrix.os }}
|
||||
flutter_version: ${{ env.FLUTTER_VERSION }}
|
||||
rust_toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
cargo_make_version: ${{ env.CARGO_MAKE_VERSION }}
|
||||
rust_target: ${{ matrix.target }}
|
||||
flutter_profile: ${{ matrix.flutter_profile }}
|
||||
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
prepare-windows:
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: true
|
||||
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: Flutter build
|
||||
uses: ./.github/actions/flutter_build
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
os: ${{ matrix.os }}
|
||||
flutter_version: ${{ env.FLUTTER_VERSION }}
|
||||
rust_toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
cargo_make_version: ${{ env.CARGO_MAKE_VERSION }}
|
||||
rust_target: ${{ matrix.target }}
|
||||
flutter_profile: ${{ matrix.flutter_profile }}
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
prepare-macos:
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [macos-latest]
|
||||
include:
|
||||
- os: macos-latest
|
||||
flutter_profile: development-mac-x86_64
|
||||
target: x86_64-apple-darwin
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Flutter build
|
||||
uses: ./.github/actions/flutter_build
|
||||
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
|
||||
run: |
|
||||
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
|
||||
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 ${{ matrix.flutter_profile }} appflowy-core-dev
|
||||
|
||||
- name: Run code generation
|
||||
working-directory: frontend
|
||||
run: cargo make code_generation
|
||||
|
||||
- name: Flutter Analyzer
|
||||
working-directory: frontend/appflowy_flutter
|
||||
run: flutter analyze .
|
||||
|
||||
- name: Compress appflowy_flutter
|
||||
run: |
|
||||
tar -czf appflowy_flutter.tar.gz frontend/appflowy_flutter
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ github.run_id }}-${{ matrix.os }}
|
||||
path: appflowy_flutter.tar.gz
|
||||
os: ${{ matrix.os }}
|
||||
flutter_version: ${{ env.FLUTTER_VERSION }}
|
||||
rust_toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
cargo_make_version: ${{ env.CARGO_MAKE_VERSION }}
|
||||
rust_target: ${{ matrix.target }}
|
||||
flutter_profile: ${{ matrix.flutter_profile }}
|
||||
|
||||
unit_test:
|
||||
needs: [prepare]
|
||||
needs: [prepare-linux]
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -142,7 +135,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
@@ -159,6 +152,7 @@ jobs:
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
@@ -194,7 +188,7 @@ jobs:
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ${{ github.run_id }}-${{ matrix.os }}
|
||||
|
||||
@@ -217,113 +211,8 @@ jobs:
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
# disable coverage for now as it's not working
|
||||
# - name: Upload coverage to Codecov
|
||||
# uses: Wandalen/wretry.action@v1.0.36
|
||||
# with:
|
||||
# action: codecov/codecov-action@v3
|
||||
# with: |
|
||||
# name: appflowy
|
||||
# flags: appflowy_flutter_unit_test
|
||||
# fail_ci_if_error: true
|
||||
# verbose: true
|
||||
# os: ${{ matrix.os }}
|
||||
# token: ${{ secrets.CODECOV_TOKEN }}
|
||||
# attempt_limit: 20
|
||||
# attempt_delay: 10000
|
||||
|
||||
integration_test:
|
||||
needs: [prepare]
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
flutter_profile: development-linux-x86_64
|
||||
target: x86_64-unknown-linux-gnu
|
||||
- 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@v2
|
||||
|
||||
- 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 }}
|
||||
|
||||
- uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: cargo-make@${{ env.CARGO_MAKE_VERSION }}
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
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
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Enable Flutter Desktop
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
flutter config --enable-linux-desktop
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
flutter config --enable-macos-desktop
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
git config --system core.longpaths true
|
||||
flutter config --enable-windows-desktop
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{ github.run_id }}-${{ matrix.os }}
|
||||
|
||||
- name: Uncompressed appflowy_flutter
|
||||
run: tar -xf appflowy_flutter.tar.gz
|
||||
|
||||
- name: Run flutter pub get
|
||||
working-directory: frontend
|
||||
run: cargo make pub_get
|
||||
|
||||
- name: Run Flutter integration tests
|
||||
working-directory: frontend/appflowy_flutter
|
||||
run: |
|
||||
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 integration_test/runner.dart -d Linux --coverage
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
flutter test integration_test/runner.dart -d macOS --coverage
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
flutter test integration_test/runner.dart -d Windows --coverage
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
cloud_integration_test:
|
||||
needs: [prepare]
|
||||
# if: github.event_name != 'pull_request'
|
||||
needs: [prepare-linux]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -336,33 +225,30 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout appflowy cloud code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: AppFlowy-IO/AppFlowy-Cloud
|
||||
path: AppFlowy-Cloud
|
||||
depth: 1
|
||||
|
||||
|
||||
- name: Prepare appflowy cloud env
|
||||
working-directory: AppFlowy-Cloud
|
||||
run: |
|
||||
# log level
|
||||
cp dev.env .env
|
||||
cp deploy.env .env
|
||||
sed -i 's|RUST_LOG=.*|RUST_LOG=trace|' .env
|
||||
sed -i 's/GOTRUE_SMTP_USER=.*/GOTRUE_SMTP_USER=${{ secrets.INTEGRATION_TEST_GOTRUE_SMTP_USER }}/' .env
|
||||
sed -i 's/GOTRUE_SMTP_PASS=.*/GOTRUE_SMTP_PASS=${{ secrets.INTEGRATION_TEST_GOTRUE_SMTP_PASS }}/' .env
|
||||
sed -i 's/GOTRUE_SMTP_ADMIN_EMAIL=.*/GOTRUE_SMTP_ADMIN_EMAIL=${{ secrets.INTEGRATION_TEST_GOTRUE_SMTP_ADMIN_EMAIL }}/' .env
|
||||
sed -i 's/GOTRUE_EXTERNAL_GOOGLE_ENABLED=.*/GOTRUE_EXTERNAL_GOOGLE_ENABLED=true/' .env
|
||||
sed -i 's|API_EXTERNAL_URL=.*|API_EXTERNAL_URL=http://localhost|' .env
|
||||
cat .env
|
||||
|
||||
- name: Run Docker-Compose
|
||||
working-directory: AppFlowy-Cloud
|
||||
run: |
|
||||
docker compose down -v --remove-orphans
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
sleep 10
|
||||
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
@@ -370,6 +256,7 @@ jobs:
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- uses: taiki-e/install-action@v2
|
||||
with:
|
||||
@@ -389,7 +276,7 @@ jobs:
|
||||
flutter config --enable-linux-desktop
|
||||
shell: bash
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ${{ github.run_id }}-${{ matrix.os }}
|
||||
|
||||
@@ -398,12 +285,6 @@ jobs:
|
||||
tar -xf appflowy_flutter.tar.gz
|
||||
ls -al
|
||||
|
||||
- name: Enable localhost env
|
||||
working-directory: frontend/appflowy_flutter
|
||||
run: |
|
||||
echo 'APPFLOWY_CLOUD_URL=http://localhost' >> .env
|
||||
dart run build_runner clean && dart run build_runner build --delete-conflicting-outputs
|
||||
|
||||
- name: Run flutter pub get
|
||||
working-directory: frontend
|
||||
run: cargo make pub_get
|
||||
@@ -414,83 +295,79 @@ jobs:
|
||||
export DISPLAY=:99
|
||||
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &
|
||||
sudo apt-get install network-manager
|
||||
flutter test integration_test/cloud_runner.dart -d Linux --coverage
|
||||
docker ps -a
|
||||
flutter test integration_test/cloud/cloud_runner.dart -d Linux --coverage
|
||||
shell: bash
|
||||
|
||||
build:
|
||||
needs: [prepare]
|
||||
# split the integration tests into different machines to minimize the time
|
||||
integration_test_1:
|
||||
needs: [prepare-linux]
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
os: [ubuntu-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
flutter_profile: development-linux-x86_64
|
||||
target: x86_64-unknown-linux-gnu
|
||||
- os: macos-latest
|
||||
flutter_profile: development-mac-x86_64
|
||||
target: x86_64-apple-darwin
|
||||
- os: windows-latest
|
||||
flutter_profile: development-windows-x86
|
||||
target: x86_64-pc-windows-msvc
|
||||
target: 'x86_64-unknown-linux-gnu'
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
- name: Flutter Integration Test 1
|
||||
uses: ./.github/actions/flutter_integration_test
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
target: ${{ matrix.target }}
|
||||
override: true
|
||||
profile: minimal
|
||||
test_path: integration_test/desktop_runner_1.dart
|
||||
flutter_version: ${{ env.FLUTTER_VERSION }}
|
||||
rust_toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
cargo_make_version: ${{ env.CARGO_MAKE_VERSION }}
|
||||
rust_target: ${{ matrix.target }}
|
||||
|
||||
- name: Install flutter
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
integration_test_2:
|
||||
needs: [prepare-linux]
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: 'x86_64-unknown-linux-gnu'
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Flutter Integration Test 2
|
||||
uses: ./.github/actions/flutter_integration_test
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
test_path: integration_test/desktop_runner_2.dart
|
||||
flutter_version: ${{ env.FLUTTER_VERSION }}
|
||||
rust_toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
cargo_make_version: ${{ env.CARGO_MAKE_VERSION }}
|
||||
rust_target: ${{ matrix.target }}
|
||||
|
||||
- uses: taiki-e/install-action@v2
|
||||
integration_test_3:
|
||||
needs: [prepare-linux]
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: 'x86_64-unknown-linux-gnu'
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Flutter Integration Test 3
|
||||
uses: ./.github/actions/flutter_integration_test
|
||||
with:
|
||||
tool: cargo-make@${{ env.CARGO_MAKE_VERSION }}
|
||||
|
||||
- name: Install prerequisites
|
||||
working-directory: frontend
|
||||
run: |
|
||||
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
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Enable Flutter Desktop
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
flutter config --enable-linux-desktop
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
flutter config --enable-macos-desktop
|
||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||
git config --system core.longpaths true
|
||||
flutter config --enable-windows-desktop
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{ github.run_id }}-${{ matrix.os }}
|
||||
|
||||
- name: Uncompressed appflowy_flutter
|
||||
run: tar -xf appflowy_flutter.tar.gz
|
||||
|
||||
- name: Build flutter product
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo make --profile ${{ matrix.flutter_profile }} appflowy-make-product-dev
|
||||
test_path: integration_test/desktop_runner_3.dart
|
||||
flutter_version: ${{ env.FLUTTER_VERSION }}
|
||||
rust_toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
cargo_make_version: ${{ env.CARGO_MAKE_VERSION }}
|
||||
rust_target: ${{ matrix.target }}
|
||||
@@ -0,0 +1,92 @@
|
||||
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
|
||||
|
||||
# enable it again if the 12 mins timeout is fixed
|
||||
# - name: Run integration tests
|
||||
# working-directory: frontend/appflowy_flutter
|
||||
# run: flutter test integration_test/runner.dart -d ${{ steps.simulator-action.outputs.udid }}
|
||||
@@ -1,113 +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.13.9"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
|
||||
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:
|
||||
# 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"
|
||||
|
||||
- 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: ${{ 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: nttld/setup-ndk@v1
|
||||
id: setup-ndk
|
||||
with:
|
||||
ndk-version: "r24"
|
||||
add-to-path: 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-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
|
||||
@@ -6,8 +6,8 @@ on:
|
||||
- "*"
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.13.9"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
FLUTTER_VERSION: "3.19.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build release notes
|
||||
run: |
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
- { target: x86_64-pc-windows-msvc, os: windows-2019 }
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
@@ -138,7 +138,7 @@ jobs:
|
||||
- { target: x86_64-apple-darwin, os: macos-11, extra-build-args: "" }
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
@@ -238,7 +238,7 @@ jobs:
|
||||
}
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
@@ -263,7 +263,7 @@ jobs:
|
||||
working-directory: frontend
|
||||
run: |
|
||||
flutter config --enable-macos-desktop
|
||||
sh scripts/flutter_release_build/build_universal_package_for_macos.sh
|
||||
sh scripts/flutter_release_build/build_universal_package_for_macos.sh ${{ github.ref_name }}
|
||||
|
||||
- name: Codesign AppFlowy
|
||||
run: |
|
||||
@@ -327,6 +327,9 @@ jobs:
|
||||
LINUX_PACKAGE_DEB_NAME: AppFlowy-${{ github.ref_name }}-linux-x86_64.deb
|
||||
LINUX_PACKAGE_RPM_NAME: AppFlowy-${{ github.ref_name }}-linux-x86_64.rpm
|
||||
LINUX_PACKAGE_TMP_RPM_NAME: AppFlowy-${{ github.ref_name }}-2.x86_64.rpm
|
||||
LINUX_PACKAGE_TMP_APPIMAGE_NAME: AppFlowy-${{ github.ref_name }}-x86_64.AppImage
|
||||
LINUX_PACKAGE_APPIMAGE_NAME: AppFlowy-${{ github.ref_name }}-linux-x86_64.AppImage
|
||||
LINUX_PACKAGE_ZIP_NAME: AppFlowy-${{ github.ref_name }}-linux-x86_64.tar.gz
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -341,7 +344,7 @@ jobs:
|
||||
}
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
@@ -395,11 +398,16 @@ jobs:
|
||||
- name: Build Linux package (.rpm)
|
||||
working-directory: ${{ env.LINUX_APP_RELEASE_PATH }}
|
||||
run: |
|
||||
ls -a
|
||||
sudo alien -r ${{ env.LINUX_PACKAGE_DEB_NAME }}
|
||||
echo '------------'
|
||||
cp -r ${{ env.LINUX_PACKAGE_TMP_RPM_NAME }} ${{ env.LINUX_PACKAGE_RPM_NAME }}
|
||||
ls -a
|
||||
|
||||
- name: Build Linux package (.AppImage)
|
||||
working-directory: frontend
|
||||
continue-on-error: true
|
||||
run: |
|
||||
sh scripts/linux_distribution/appimage/build_appimage.sh ${{ github.ref_name }}
|
||||
cd ..
|
||||
cp -r frontend/${{ env.LINUX_PACKAGE_TMP_APPIMAGE_NAME }} ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_APPIMAGE_NAME }}
|
||||
|
||||
- name: Upload Asset
|
||||
id: upload-release-asset
|
||||
@@ -409,7 +417,7 @@ jobs:
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_ZIP_NAME }}
|
||||
asset_name: ${{ env.LINUX_ZIP_NAME }}
|
||||
asset_name: ${{ env.LINUX_PACKAGE_ZIP_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: Upload Debian package
|
||||
@@ -434,23 +442,34 @@ jobs:
|
||||
asset_name: ${{ env.LINUX_PACKAGE_RPM_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: Upload AppImage package
|
||||
id: upload-release-asset-install-package-appimage
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_APPIMAGE_NAME }}
|
||||
asset_name: ${{ env.LINUX_PACKAGE_APPIMAGE_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
build-for-docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./frontend/scripts/docker-buildfiles/Dockerfile
|
||||
|
||||
@@ -8,7 +8,6 @@ on:
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/rust-lib/**"
|
||||
- "shared-lib/**"
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
@@ -17,19 +16,33 @@ on:
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/rust-lib/**"
|
||||
- "shared-lib/**"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
|
||||
jobs:
|
||||
test-on-ubuntu:
|
||||
environment: SUPABASE_CI
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# - 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
|
||||
# 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
|
||||
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
@@ -48,34 +61,50 @@ jobs:
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: 'ubuntu-latest'
|
||||
prefix-key: "ubuntu-latest"
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
|
||||
- name: Create .env file in flowy-server
|
||||
working-directory: frontend/rust-lib/flowy-server
|
||||
run: |
|
||||
touch .env.ci
|
||||
echo SUPABASE_URL=${{ secrets.SUPABASE_URL }} >> .env.ci
|
||||
echo SUPABASE_ANON_KEY=${{ secrets.SUPABASE_ANON_KEY }} >> .env.ci
|
||||
echo SUPABASE_JWT_SECRET=${{ secrets.SUPABASE_JWT_SECRET }} >> .env.ci
|
||||
- name: Checkout appflowy cloud code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: AppFlowy-IO/AppFlowy-Cloud
|
||||
path: AppFlowy-Cloud
|
||||
|
||||
- name: Create .env file in event-integration
|
||||
working-directory: frontend/rust-lib/event-integration
|
||||
- name: Prepare appflowy cloud env
|
||||
working-directory: AppFlowy-Cloud
|
||||
run: |
|
||||
touch .env.ci
|
||||
echo SUPABASE_URL=${{ secrets.SUPABASE_URL }} >> .env.ci
|
||||
echo SUPABASE_ANON_KEY=${{ secrets.SUPABASE_ANON_KEY }} >> .env.ci
|
||||
echo SUPABASE_JWT_SECRET=${{ secrets.SUPABASE_JWT_SECRET }} >> .env.ci
|
||||
# log level
|
||||
cp deploy.env .env
|
||||
sed -i 's|RUST_LOG=.*|RUST_LOG=trace|' .env
|
||||
sed -i 's|API_EXTERNAL_URL=.*|API_EXTERNAL_URL=http://localhost|' .env
|
||||
|
||||
- name: Run Docker-Compose
|
||||
working-directory: AppFlowy-Cloud
|
||||
run: |
|
||||
docker pull appflowyinc/appflowy_cloud:latest
|
||||
docker compose up -d
|
||||
|
||||
- name: Run rust-lib tests
|
||||
working-directory: frontend/rust-lib
|
||||
run: RUST_LOG=info RUST_BACKTRACE=1 cargo test --no-default-features --features="rev-sqlite"
|
||||
env:
|
||||
RUST_LOG: info
|
||||
RUST_BACKTRACE: 1
|
||||
af_cloud_test_base_url: http://localhost
|
||||
af_cloud_test_ws_url: ws://localhost/ws/v1
|
||||
af_cloud_test_gotrue_url: http://localhost/gotrue
|
||||
run: |
|
||||
DISABLE_CI_TEST_LOG="true" cargo test --no-default-features --features="rev-sqlite,dart" -- --nocapture
|
||||
|
||||
- name: rustfmt rust-lib
|
||||
run: cargo fmt --all -- --check
|
||||
working-directory: frontend/rust-lib/
|
||||
|
||||
- name: clippy rust-lib
|
||||
run: cargo clippy --all
|
||||
working-directory: frontend/rust-lib
|
||||
run: cargo clippy --all-targets -- -D warnings
|
||||
working-directory: frontend/rust-lib
|
||||
|
||||
- name: Clean up Docker images
|
||||
run: |
|
||||
docker image prune -af
|
||||
docker volume prune -f
|
||||
@@ -7,19 +7,18 @@ on:
|
||||
- "release/*"
|
||||
paths:
|
||||
- "frontend/rust-lib/**"
|
||||
- "shared-lib/**"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
FLUTTER_VERSION: "3.13.9"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
FLUTTER_VERSION: "3.19.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
name: Tauri2-CI
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/tauri2_ci.yaml"
|
||||
- "frontend/rust-lib/**"
|
||||
- "frontend/appflowy_web_app/**"
|
||||
- "frontend/resources/**"
|
||||
|
||||
env:
|
||||
NODE_VERSION: "18.16.0"
|
||||
PNPM_VERSION: "8.5.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
tauri-build:
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ ubuntu-20.04 ]
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
env:
|
||||
CI: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Maximize build space (ubuntu only)
|
||||
if: matrix.platform == 'ubuntu-20.04'
|
||||
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: setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: setup pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Rust cache
|
||||
uses: swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: "./frontend/appflowy_web_app/src-tauri -> target"
|
||||
|
||||
- name: Node_modules cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: frontend/appflowy_web_app/node_modules
|
||||
key: node-modules-${{ runner.os }}
|
||||
|
||||
- name: install dependencies (windows only)
|
||||
if: matrix.platform == 'windows-latest'
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install --force duckscript_cli
|
||||
vcpkg integrate install
|
||||
|
||||
- name: install dependencies (ubuntu only)
|
||||
if: matrix.platform == 'ubuntu-20.04'
|
||||
working-directory: frontend
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
|
||||
|
||||
- name: install cargo-make
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install --force cargo-make
|
||||
cargo make appflowy-tauri-deps-tools
|
||||
|
||||
- name: install frontend dependencies
|
||||
working-directory: frontend/appflowy_web_app
|
||||
run: |
|
||||
mkdir dist
|
||||
pnpm install
|
||||
cd src-tauri && cargo build
|
||||
|
||||
- name: test and lint
|
||||
working-directory: frontend/appflowy_web_app
|
||||
run: |
|
||||
pnpm run lint:tauri
|
||||
|
||||
- uses: tauri-apps/tauri-action@v0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tauriScript: pnpm tauri
|
||||
projectPath: frontend/appflowy_web_app
|
||||
args: "--debug"
|
||||
@@ -5,11 +5,12 @@ on:
|
||||
- ".github/workflows/tauri_ci.yaml"
|
||||
- "frontend/rust-lib/**"
|
||||
- "frontend/appflowy_tauri/**"
|
||||
- "frontend/resources/**"
|
||||
|
||||
env:
|
||||
NODE_VERSION: "18.16.0"
|
||||
PNPM_VERSION: "8.5.0"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
@@ -21,36 +22,36 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# platform: [macos-latest, ubuntu-latest, windows-latest]
|
||||
platform: [ubuntu-latest]
|
||||
platform: [ubuntu-20.04]
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
env:
|
||||
CI: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Maximize build space (ubuntu only)
|
||||
if: matrix.platform == 'ubuntu-20.04'
|
||||
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: setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Cache Rust Dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
- name: setup pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
key: rust-dependencies-${{ runner.os }}
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
frontend/appflowy_tauri/src-tauri
|
||||
|
||||
- name: Cache Node.js dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: npm-${{ runner.os }}
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: frontend/appflowy_tauri/node_modules
|
||||
key: node-modules-${{ runner.os }}
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
@@ -60,51 +61,54 @@ jobs:
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Rust cache
|
||||
uses: swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: "./frontend/appflowy_tauri/src-tauri -> target"
|
||||
|
||||
- name: Node_modules cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: frontend/appflowy_tauri/node_modules
|
||||
key: node-modules-${{ runner.os }}
|
||||
|
||||
- name: install dependencies (windows only)
|
||||
if: matrix.platform == 'windows-latest'
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
vcpkg integrate install
|
||||
cargo make appflowy-tauri-deps-tools
|
||||
npm install -g pnpm@${{ env.PNPM_VERSION }}
|
||||
|
||||
- name: install dependencies (ubuntu only)
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
if: matrix.platform == 'ubuntu-20.04'
|
||||
working-directory: frontend
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
|
||||
cargo install --force cargo-make
|
||||
cargo make appflowy-tauri-deps-tools
|
||||
npm install -g pnpm@${{ env.PNPM_VERSION }}
|
||||
|
||||
- name: install dependencies (macOS only)
|
||||
if: matrix.platform == 'macos-latest'
|
||||
- name: install cargo-make
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install --force cargo-make
|
||||
cargo make appflowy-tauri-deps-tools
|
||||
npm install -g pnpm@${{ env.PNPM_VERSION }}
|
||||
|
||||
- name: Build
|
||||
- name: install frontend dependencies
|
||||
working-directory: frontend/appflowy_tauri
|
||||
run: |
|
||||
mkdir dist
|
||||
pnpm install
|
||||
cargo make --cwd .. tauri_build
|
||||
|
||||
- name: frontend tests and linting
|
||||
working-directory: frontend/appflowy_tauri
|
||||
run: |
|
||||
pnpm test
|
||||
pnpm test:errors
|
||||
|
||||
- name: Check for uncommitted changes
|
||||
run: |
|
||||
diff_files=$(git status --porcelain)
|
||||
if [ -n "$diff_files" ]; then
|
||||
echo "There are uncommitted changes in the working tree. Please commit them before pushing."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: tauri-apps/tauri-action@v0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tauriScript: pnpm tauri
|
||||
projectPath: frontend/appflowy_tauri
|
||||
args: "--debug"
|
||||
@@ -0,0 +1,153 @@
|
||||
name: Publish Tauri Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
branch:
|
||||
description: 'The branch to release'
|
||||
required: true
|
||||
default: 'main'
|
||||
version:
|
||||
description: 'The version to release'
|
||||
required: true
|
||||
default: '0.0.0'
|
||||
env:
|
||||
NODE_VERSION: "18.16.0"
|
||||
PNPM_VERSION: "8.5.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
|
||||
jobs:
|
||||
|
||||
publish-tauri:
|
||||
permissions:
|
||||
contents: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
settings:
|
||||
- platform: windows-latest
|
||||
args: "--verbose"
|
||||
target: "windows-x86_64"
|
||||
- platform: macos-latest
|
||||
args: "--target x86_64-apple-darwin"
|
||||
target: "macos-x86_64"
|
||||
- platform: ubuntu-20.04
|
||||
args: "--target x86_64-unknown-linux-gnu"
|
||||
target: "linux-x86_64"
|
||||
|
||||
runs-on: ${{ matrix.settings.platform }}
|
||||
|
||||
env:
|
||||
CI: true
|
||||
PACKAGE_PREFIX: AppFlowy_Tauri-${{ github.event.inputs.version }}-${{ matrix.settings.target }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.inputs.branch }}
|
||||
|
||||
- name: Maximize build space (ubuntu only)
|
||||
if: matrix.settings.platform == 'ubuntu-20.04'
|
||||
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: setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: setup pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Rust cache
|
||||
uses: swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: "./frontend/appflowy_tauri/src-tauri -> target"
|
||||
|
||||
- name: install dependencies (windows only)
|
||||
if: matrix.settings.platform == 'windows-latest'
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install --force duckscript_cli
|
||||
vcpkg integrate install
|
||||
|
||||
- name: install dependencies (ubuntu only)
|
||||
if: matrix.settings.platform == 'ubuntu-20.04'
|
||||
working-directory: frontend
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
|
||||
|
||||
- name: install cargo-make
|
||||
working-directory: frontend
|
||||
run: |
|
||||
cargo install --force cargo-make
|
||||
cargo make appflowy-tauri-deps-tools
|
||||
|
||||
- name: install frontend dependencies
|
||||
working-directory: frontend/appflowy_tauri
|
||||
run: |
|
||||
mkdir dist
|
||||
pnpm install
|
||||
pnpm exec node scripts/update_version.cjs ${{ github.event.inputs.version }}
|
||||
cargo make --cwd .. tauri_build
|
||||
|
||||
- uses: tauri-apps/tauri-action@dev
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
APPLE_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
||||
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
|
||||
APPLE_SIGNING_IDENTITY: ${{ secrets.MACOS_TEAM_ID }}
|
||||
APPLE_ID: ${{ secrets.MACOS_NOTARY_USER }}
|
||||
APPLE_TEAM_ID: ${{ secrets.MACOS_TEAM_ID }}
|
||||
APPLE_PASSWORD: ${{ secrets.MACOS_NOTARY_PWD }}
|
||||
CI: true
|
||||
with:
|
||||
args: ${{ matrix.settings.args }}
|
||||
appVersion: ${{ github.event.inputs.version }}
|
||||
tauriScript: pnpm tauri
|
||||
projectPath: frontend/appflowy_tauri
|
||||
|
||||
- name: Upload EXE package(windows only)
|
||||
uses: actions/upload-artifact@v4
|
||||
if: matrix.settings.platform == 'windows-latest'
|
||||
with:
|
||||
name: ${{ env.PACKAGE_PREFIX }}.exe
|
||||
path: frontend/appflowy_tauri/src-tauri/target/release/bundle/nsis/AppFlowy_${{ github.event.inputs.version }}_x64-setup.exe
|
||||
|
||||
- name: Upload DMG package(macos only)
|
||||
uses: actions/upload-artifact@v4
|
||||
if: matrix.settings.platform == 'macos-latest'
|
||||
with:
|
||||
name: ${{ env.PACKAGE_PREFIX }}.dmg
|
||||
path: frontend/appflowy_tauri/src-tauri/target/x86_64-apple-darwin/release/bundle/dmg/AppFlowy_${{ github.event.inputs.version }}_x64.dmg
|
||||
|
||||
- name: Upload Deb package(ubuntu only)
|
||||
uses: actions/upload-artifact@v4
|
||||
if: matrix.settings.platform == 'ubuntu-20.04'
|
||||
with:
|
||||
name: ${{ env.PACKAGE_PREFIX }}.deb
|
||||
path: frontend/appflowy_tauri/src-tauri/target/x86_64-unknown-linux-gnu/release/bundle/deb/app-flowy_${{ github.event.inputs.version }}_amd64.deb
|
||||
|
||||
- name: Upload AppImage package(ubuntu only)
|
||||
uses: actions/upload-artifact@v4
|
||||
if: matrix.settings.platform == 'ubuntu-20.04'
|
||||
with:
|
||||
name: ${{ env.PACKAGE_PREFIX }}.AppImage
|
||||
path: frontend/appflowy_tauri/src-tauri/target/x86_64-unknown-linux-gnu/release/bundle/appimage/app-flowy_${{ github.event.inputs.version }}_amd64.AppImage
|
||||
@@ -0,0 +1,74 @@
|
||||
name: Web2-CI
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/web2_ci.yaml"
|
||||
- "frontend/appflowy_web_app/**"
|
||||
- "frontend/resources/**"
|
||||
env:
|
||||
NODE_VERSION: "18.16.0"
|
||||
PNPM_VERSION: "8.5.0"
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
web-build:
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ ubuntu-latest ]
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Maximize build space (ubuntu only)
|
||||
if: matrix.platform == '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: setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
- name: setup pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
- name: Node_modules cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: frontend/appflowy_web_app/node_modules
|
||||
key: node-modules-${{ runner.os }}
|
||||
|
||||
- name: install frontend dependencies
|
||||
working-directory: frontend/appflowy_web_app
|
||||
run: |
|
||||
pnpm install
|
||||
- name: test and lint
|
||||
working-directory: frontend/appflowy_web_app
|
||||
run: |
|
||||
pnpm run lint
|
||||
- name: build and analyze
|
||||
working-directory: frontend/appflowy_web_app
|
||||
run: |
|
||||
pnpm run analyze >> analyze-size.txt
|
||||
- name: Upload analyze-size.txt
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: analyze-size.txt
|
||||
path: frontend/appflowy_web_app/analyze-size.txt
|
||||
retention-days: 30
|
||||
- name: Upload stats.html
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: stats.html
|
||||
path: frontend/appflowy_web_app/dist/stats.html
|
||||
retention-days: 30
|
||||
@@ -0,0 +1,83 @@
|
||||
name: WEB-CI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
build:
|
||||
description: 'Build the web app'
|
||||
required: true
|
||||
default: 'true'
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
NODE_VERSION: "18.16.0"
|
||||
PNPM_VERSION: "8.5.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
CARGO_MAKE_VERSION: "0.36.6"
|
||||
|
||||
jobs:
|
||||
web-build:
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ ubuntu-latest ]
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Cache Rust Dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
key: rust-dependencies-${{ runner.os }}
|
||||
workspaces: |
|
||||
frontend/rust-lib
|
||||
frontend/appflowy_web/appflowy_wasm
|
||||
|
||||
# TODO: Can combine caching deps and node_modules in one
|
||||
# See Glob patterns: https://github.com/actions/toolkit/tree/main/packages/glob
|
||||
- name: Cache Node.js dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: npm-${{ runner.os }}
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: frontend/appflowy_web/node_modules
|
||||
key: node-modules-${{ runner.os }}
|
||||
|
||||
- name: Install Rust toolchain
|
||||
id: rust_toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
override: true
|
||||
profile: minimal
|
||||
|
||||
- name: Install wasm-pack
|
||||
run: cargo install wasm-pack
|
||||
|
||||
- uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: cargo-make@${{ env.CARGO_MAKE_VERSION }}
|
||||
|
||||
- name: install dependencies
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
working-directory: frontend
|
||||
run: |
|
||||
sudo apt-get update
|
||||
npm install -g pnpm@${{ env.PNPM_VERSION }}
|
||||
cargo make install_web_protobuf
|
||||
|
||||
- name: Build
|
||||
working-directory: frontend/appflowy_web
|
||||
run: |
|
||||
pnpm install
|
||||
pnpm run build_release_wasm
|
||||
+5
-6
@@ -21,11 +21,8 @@ node_modules
|
||||
|
||||
**/resources/proto
|
||||
|
||||
!frontend/.vscode/settings.json
|
||||
!frontend/.vscode/tasks.json
|
||||
!frontend/.vscode/launch.json
|
||||
!frontend/.vscode/extensions.json
|
||||
!frontend/.vscode/*.code-snippets
|
||||
# ignore settings.json
|
||||
frontend/.vscode/settings.json
|
||||
|
||||
# Commit the highest level pubspec.lock, but ignore the others
|
||||
pubspec.lock
|
||||
@@ -38,8 +35,10 @@ pubspec.lock
|
||||
|
||||
**/AppFlowy-Collab/
|
||||
|
||||
# ignore the deb filegit
|
||||
# ignore generated assets
|
||||
frontend/package
|
||||
frontend/*.deb
|
||||
|
||||
**/Cargo.toml.bak
|
||||
|
||||
**/.cargo/**
|
||||
+138
@@ -1,4 +1,142 @@
|
||||
# Release Notes
|
||||
## Version 0.5.4 - 04/08/2024
|
||||
### New Features
|
||||
- Introduced support for displaying a synchronization indicator within documents and databases to enhance user awareness of data sync status
|
||||
- Revamped the select option cell editor in database
|
||||
- Improved translations for Spanish, German, Kurdish, and Vietnamese
|
||||
- Supported Android 6 and newer versions
|
||||
### Bug Fixes
|
||||
- Resolved an issue where twelve-hour time formats were not being parsed correctly in databases
|
||||
- Fixed a bug affecting the user interface of the single select option filter
|
||||
- Fixed various minor UI issues
|
||||
|
||||
## Version 0.5.3 - 03/21/2024
|
||||
### New Features
|
||||
- Added build support for 32-bit Android devices
|
||||
- Introduced filters for KanBan boards for enhanced organization
|
||||
- Introduced the new "Relations" column type in Grids
|
||||
- Expanded language support with the addition of Greek
|
||||
- Enhanced toolbar design for Mobile devices
|
||||
- Introduced a command palette feature with initial support for page search
|
||||
### Bug Fixes
|
||||
- Rectified the issue of incomplete row data in Grids when adding new rows with active filters
|
||||
- Enhanced the logic governing the filtering of number and select/multi-select fields for improved accuracy
|
||||
- Implemented UI refinements on both Desktop and Mobile platforms, enriching the overall user experience of AppFlowy
|
||||
|
||||
## Version 0.5.2 - 03/13/2024
|
||||
### Bug Fixes
|
||||
- Import csv file.
|
||||
|
||||
## Version 0.5.1 - 03/11/2024
|
||||
### New Features
|
||||
- Introduced support for performing generic calculations on databases.
|
||||
- Implemented functionality for easily duplicating calendar events.
|
||||
- Added the ability to duplicate fields with cell data, facilitating smoother data management.
|
||||
- Now supports customizing font styles and colors prior to typing.
|
||||
- Enhanced the checklist user experience with the integration of keyboard shortcuts.
|
||||
- Improved the dark mode experience on mobile devices.
|
||||
### Bug Fixes
|
||||
- Fixed an issue with some pages failing to sync properly.
|
||||
- Fixed an issue where links without the http(s) scheme could not be opened, ensuring consistent link functionality.
|
||||
- Fixed an issue that prevented numbers from being inserted before heading blocks.
|
||||
- Fixed the inline page reference update mechanism to accurately reflect workspace changes.
|
||||
- Fixed an issue that made it difficult to resize images in certain cases.
|
||||
- Enhanced image loading reliability by clearing the image cache when images fail to load.
|
||||
- Resolved a problem preventing the launching of URLs on some Linux distributions.
|
||||
|
||||
## Version 0.5.0 - 02/26/2024
|
||||
### New Features
|
||||
- Added support for scaling text on mobile platforms for better readability.
|
||||
- Introduced a toggle for favorites directly from the documents' top bar.
|
||||
- Optimized the image upload process and added error messaging for failed uploads.
|
||||
- Implemented depth control for outline block components.
|
||||
- New checklist task creation is now more intuitive, with prompts appearing on hover over list items in the row detail page.
|
||||
- Enhanced sorting capabilities, allowing reordering and addition of multiple sorts.
|
||||
- Expanded sorting and filtering options to include more field types like checklist, creation time, and modification time.
|
||||
- Added support for field calculations within databases.
|
||||
### Bug Fixes
|
||||
- Fixed an issue where inserting an image from Unsplash in local mode was not possible.
|
||||
- Fixed undo/redo functionality in lists.
|
||||
- Fixed data loss issues when converting between block types.
|
||||
- Fixed a bug where newly created rows were not being automatically sorted.
|
||||
- Fixed issues related to deleting a sorting field or sort not removing existing sorts properly.
|
||||
### Notes
|
||||
- Windows 7, Windows 8, and iOS 11 are not yet supported due to the upgrade to Flutter 3.19.0.
|
||||
|
||||
## Version 0.4.9 - 02/17/2024
|
||||
### Bug Fixes
|
||||
- Resolved the issue that caused users to be redirected to the Sign In page
|
||||
|
||||
## Version 0.4.8 - 02/13/2024
|
||||
### Bug Fixes
|
||||
- Fixed a possible error when loading workspaces
|
||||
|
||||
## Version 0.4.6 - 02/03/2024
|
||||
### Bug Fixes
|
||||
- Fixed refresh token bug
|
||||
|
||||
## Version 0.4.5 - 02/01/2024
|
||||
### Bug Fixes
|
||||
- Fixed WebSocket connection issue
|
||||
|
||||
## Version 0.4.4 - 01/31/2024
|
||||
### New Features
|
||||
- Added functionality for uploading images to cloud storage.
|
||||
- Enabled anonymous sign-in option for mobile platform users.
|
||||
- Introduced the ability to customize cloud settings directly from the startup page.
|
||||
- Added support for inserting reminders on the mobile platform.
|
||||
- Overhauled the user interface on mobile devices, including improvements to the action bottom sheet, editor toolbar, database details page, and app bar.
|
||||
- Implemented a shortcut (F2 key) to rename the current view.
|
||||
|
||||
### Bug Fixes
|
||||
- Fixed an issue where the font family was not displaying correctly on the mobile platform.
|
||||
- Resolved a problem with the mobile row detail title not updating correctly.
|
||||
- Fixed issues related to deleting images and refactored the image actions menu for better usability.
|
||||
- Fixed other known issues.
|
||||
|
||||
# Release Notes
|
||||
## Version 0.4.3 - 01/16/2024
|
||||
### Bug Fixes
|
||||
- Fixed file name too long issue
|
||||
|
||||
## Version 0.4.2 - 01/15/2024
|
||||
AppFlowy for Android is available to download on GitHub.
|
||||
If you’ve been using our desktop app, it’s important to read [this guide](https://docs.appflowy.io/docs/guides/sync-desktop-and-mobile) before logging into the mobile app.
|
||||
### New Features
|
||||
- Enhanced RTL (Right-to-Left) support for mobile platforms.
|
||||
- Optimized selection gesture system on mobile.
|
||||
- Optimized the mobile toolbar menu.
|
||||
- Improved reference menu (‘@’ menu).
|
||||
- Updated privacy policy.
|
||||
- Improved the data import process for AppFlowy by implementing a progress indicator and compressing the data to enhance efficiency.
|
||||
- Enhanced the utilization of local disk space to optimize storage consumption.
|
||||
### Bug Fixes
|
||||
- Fixed sign-in cancellation issue on mobile.
|
||||
- Resolved keyboard close bug on Android.
|
||||
|
||||
|
||||
## Version 0.4.1 - 01/03/2024
|
||||
### Bug fixes
|
||||
- Fix import AppFlowy data folder
|
||||
|
||||
## Version 0.4.0 - 12/30/2023
|
||||
1. Added capability to import data from an AppFlowy data folder. For detailed information, please see [AppFlowy Data Storage Documentation](https://docs.appflowy.io/docs/appflowy/product/data-storage).
|
||||
2. Enhanced user interface and fixed various bugs.
|
||||
3. Improved the efficiency of data synchronization in AppFlowy Cloud
|
||||
|
||||
## Version 0.3.9.1 - 12/07/2023
|
||||
|
||||
### Bug fixes
|
||||
- Fix potential blank pages that may occur in an empty document
|
||||
|
||||
## Version 0.3.9 - 12/07/2023
|
||||
|
||||
### New Features
|
||||
- Support inserting a new field to the left or right of an existing one
|
||||
|
||||
### Bug fixes
|
||||
- Fix some emojis are shown in black/white
|
||||
- Fix unable to rename a subpage of subpage
|
||||
|
||||
## Version 0.3.8 - 11/13/2023
|
||||
|
||||
|
||||
@@ -31,15 +31,15 @@ You are in charge of your data and customizations.
|
||||
|
||||
## User Installation
|
||||
|
||||
* [Windows/Mac/Linux](https://appflowy.gitbook.io/docs/essential-documentation/install-appflowy/installation-methods/mac-windows-linux-packages)
|
||||
* [Docker](https://appflowy.gitbook.io/docs/essential-documentation/install-appflowy/installation-methods/installing-with-docker)
|
||||
* [Source](https://appflowy.gitbook.io/docs/essential-documentation/install-appflowy/installation-methods/from-source)
|
||||
- [Windows/Mac/Linux](https://docs.appflowy.io/docs/appflowy/install-appflowy/installation-methods/mac-windows-linux-packages)
|
||||
- [Docker](https://docs.appflowy.io/docs/appflowy/install-appflowy/installation-methods/installing-with-docker)
|
||||
- [Source](https://docs.appflowy.io/docs/documentation/appflowy/from-source)
|
||||
|
||||
## Built With
|
||||
|
||||
* [Flutter](https://flutter.dev/)
|
||||
- [Flutter](https://flutter.dev/)
|
||||
|
||||
* [Rust](https://www.rust-lang.org/)
|
||||
- [Rust](https://www.rust-lang.org/)
|
||||
|
||||
## Stay Up-to-Date
|
||||
|
||||
@@ -51,8 +51,8 @@ Please view the [documentation](https://docs.appflowy.io/docs/documentation/appf
|
||||
|
||||
## Roadmap
|
||||
|
||||
* [AppFlowy Roadmap ReadMe](https://appflowy.gitbook.io/docs/essential-documentation/roadmap)
|
||||
* [AppFlowy Public Roadmap](https://github.com/orgs/AppFlowy-IO/projects/5/views/12)
|
||||
- [AppFlowy Roadmap ReadMe](https://docs.appflowy.io/docs/appflowy/roadmap)
|
||||
- [AppFlowy Public Roadmap](https://github.com/orgs/AppFlowy-IO/projects/5/views/12)
|
||||
|
||||
If you'd like to propose a feature, submit a feature request [here](https://github.com/AppFlowy-IO/AppFlowy/issues/new?assignees=&labels=&template=feature_request.yaml&title=%5BFR%5D+) <br/>
|
||||
If you'd like to report a bug, submit a bug report [here](https://github.com/AppFlowy-IO/AppFlowy/issues/new?assignees=&labels=&template=bug_report.yaml&title=%5BBug%5D+)
|
||||
@@ -63,19 +63,17 @@ Please see the [changelog](https://www.appflowy.io/whatsnew) for more details ab
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions make the open-source community a fantastic place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. Please look at [Contributing to AppFlowy](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/contributing-to-appflowy) for details.
|
||||
Contributions make the open-source community a fantastic place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. Please look at [Contributing to AppFlowy](https://docs.appflowy.io/docs/documentation/software-contributions/contributing-to-appflowy) for details.
|
||||
|
||||
If your Pull Request is accepted as it fixes a bug, adds functionality, or makes AppFlowy's codebase significantly easier to use or understand, **Congratulations!** If your administrative and managerial work behind the scenes sustains the community, **Congratulations!** You are now an official contributor to AppFlowy. Get in touch with us ([link](https://tally.so/r/mKP5z3)) to receive the very special Contributor T-shirt!
|
||||
Proudly wear your T-shirt and show it to us by tagging [@appflowy](https://twitter.com/appflowy) on Twitter.
|
||||
|
||||
|
||||
## Translations 🌎🗺
|
||||
|
||||
[](https://inlang.com/editor/github.com/AppFlowy-IO/AppFlowy?ref=badge)
|
||||
|
||||
To add translations, you can manually edit the JSON translation files in `/frontend/resources/translations`, use the [inlang online editor](https://inlang.com/editor/github.com/AppFlowy-IO/AppFlowy), or run `npx inlang machine translate` to add missing translations.
|
||||
|
||||
|
||||
## Join the community to build AppFlowy together
|
||||
|
||||
<a href="https://github.com/AppFlowy-IO/AppFlowy/graphs/contributors">
|
||||
@@ -92,14 +90,14 @@ When a customer's evolving core needs are not satisfied, they either switch to a
|
||||
|
||||
All these restrictions necessitate our mission - to make it possible for anyone to create apps that suit their needs well.
|
||||
|
||||
* To individuals, we would like to offer Notion's functionality, data security, and cross-platform native experience.
|
||||
* To enterprises and hackers, AppFlowy is dedicated to offering building blocks and collaboration infra services to enable you to make apps on your own. Moreover, you have 100% control of your data. You can design and modify AppFlowy your way, with a single codebase written in Flutter and Rust supporting multiple platforms armed with long-term maintainability.
|
||||
- To individuals, we would like to offer Notion's functionality, data security, and cross-platform native experience.
|
||||
- To enterprises and hackers, AppFlowy is dedicated to offering building blocks and collaboration infra services to enable you to make apps on your own. Moreover, you have 100% control of your data. You can design and modify AppFlowy your way, with a single codebase written in Flutter and Rust supporting multiple platforms armed with long-term maintainability.
|
||||
|
||||
We decided to achieve this mission by upholding the three most fundamental values:
|
||||
|
||||
* Data privacy first
|
||||
* Reliable native experience
|
||||
* Community-driven extensibility
|
||||
- Data privacy first
|
||||
- Reliable native experience
|
||||
- Community-driven extensibility
|
||||
|
||||
We do not claim to outperform Notion in terms of functionality and design, at least for now. Besides, our priority doesn't lie in more functionality at the moment. Instead, we would like to cultivate a community to democratize the knowledge and wheels of making complex workplace management tools while enabling people and businesses to create beautiful things on their own by equipping them with a versatile toolbox of building blocks.
|
||||
|
||||
@@ -111,6 +109,6 @@ Distributed under the AGPLv3 License. See [`LICENSE.md`](https://github.com/AppF
|
||||
|
||||
Special thanks to these amazing projects which help power AppFlowy.IO:
|
||||
|
||||
* [flutter-quill](https://github.com/singerdmx/flutter-quill)
|
||||
* [cargo-make](https://github.com/sagiegurari/cargo-make)
|
||||
* [contrib.rocks](https://contrib.rocks)
|
||||
- [flutter-quill](https://github.com/singerdmx/flutter-quill)
|
||||
- [cargo-make](https://github.com/sagiegurari/cargo-make)
|
||||
- [contrib.rocks](https://contrib.rocks)
|
||||
Vendored
+7
-11
@@ -13,7 +13,10 @@
|
||||
"type": "dart",
|
||||
"env": {
|
||||
"RUST_LOG": "debug",
|
||||
"RUST_BACKTRACE": "1"
|
||||
},
|
||||
// uncomment the following line to testing performance.
|
||||
// "flutterMode": "profile",
|
||||
"cwd": "${workspaceRoot}/appflowy_flutter"
|
||||
},
|
||||
{
|
||||
@@ -66,16 +69,6 @@
|
||||
},
|
||||
"cwd": "${workspaceRoot}/appflowy_flutter"
|
||||
},
|
||||
{
|
||||
"name": "AF-iOS-Simulator: Build Dart only",
|
||||
"request": "launch",
|
||||
"program": "./lib/main.dart",
|
||||
"type": "dart",
|
||||
"env": {
|
||||
"RUST_LOG": "trace"
|
||||
},
|
||||
"cwd": "${workspaceRoot}/appflowy_flutter"
|
||||
},
|
||||
{
|
||||
"name": "AF-iOS-Simulator: Build All",
|
||||
"request": "launch",
|
||||
@@ -122,9 +115,12 @@
|
||||
},
|
||||
{
|
||||
"name": "AF-desktop: Debug Rust",
|
||||
"request": "attach",
|
||||
"type": "lldb",
|
||||
"request": "attach",
|
||||
"pid": "${command:pickMyProcess}"
|
||||
// To launch the application directly, use the following configuration:
|
||||
// "request": "launch",
|
||||
// "program": "[YOUR_APPLICATION_PATH]",
|
||||
},
|
||||
{
|
||||
// https://tauri.app/v1/guides/debugging/vs-code
|
||||
|
||||
Vendored
-36
@@ -1,36 +0,0 @@
|
||||
{
|
||||
"[dart]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnType": true,
|
||||
"editor.rulers": [80],
|
||||
"editor.selectionHighlight": false,
|
||||
"editor.suggest.snippetsPreventQuickSuggestions": false,
|
||||
"editor.suggestSelection": "first",
|
||||
"editor.tabCompletion": "onlySnippets",
|
||||
"editor.wordBasedSuggestions": false,
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.rulers": [80],
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.rulers": [80],
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"svgviewer.enableautopreview": true,
|
||||
"svgviewer.previewcolumn": "Active",
|
||||
"svgviewer.showzoominout": true,
|
||||
"editor.wordWrapColumn": 80,
|
||||
"editor.minimap.maxColumn": 140,
|
||||
"editor.wordWrap": "wordWrapColumn",
|
||||
"dart.lineLength": 80,
|
||||
"typescript.validate.enable": true,
|
||||
"javascript.validate.enable": true,
|
||||
"files.associations": {
|
||||
"*.log.*": "log"
|
||||
},
|
||||
"editor.formatOnSave": true,
|
||||
"files.eol": "\n",
|
||||
}
|
||||
Vendored
+60
-72
@@ -14,10 +14,10 @@
|
||||
"type": "shell",
|
||||
"dependsOrder": "sequence",
|
||||
"dependsOn": [
|
||||
"AF: Dart Clean",
|
||||
"AF: Flutter Clean",
|
||||
"AF: Build Appflowy Core",
|
||||
"AF: Flutter Pub Get",
|
||||
"AF: Flutter Package Get",
|
||||
"AF: Generate Language Files",
|
||||
"AF: Generate Freezed Files",
|
||||
"AF: Generate Svg Files"
|
||||
@@ -32,10 +32,10 @@
|
||||
"type": "shell",
|
||||
"dependsOrder": "sequence",
|
||||
"dependsOn": [
|
||||
"AF: Dart Clean",
|
||||
"AF: Flutter Clean",
|
||||
"AF: Build Appflowy Core For iOS",
|
||||
"AF: Flutter Pub Get",
|
||||
"AF: Flutter Package Get",
|
||||
"AF: Generate Language Files",
|
||||
"AF: Generate Freezed Files",
|
||||
"AF: Generate Svg Files"
|
||||
@@ -50,10 +50,10 @@
|
||||
"type": "shell",
|
||||
"dependsOrder": "sequence",
|
||||
"dependsOn": [
|
||||
"AF: Dart Clean",
|
||||
"AF: Flutter Clean",
|
||||
"AF: Build Appflowy Core For iOS Simulator",
|
||||
"AF: Flutter Pub Get",
|
||||
"AF: Flutter Package Get",
|
||||
"AF: Generate Language Files",
|
||||
"AF: Generate Freezed Files",
|
||||
"AF: Generate Svg Files"
|
||||
@@ -63,6 +63,41 @@
|
||||
"panel": "new"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Clean + Rebuild All (Android)",
|
||||
"type": "shell",
|
||||
"dependsOrder": "sequence",
|
||||
"dependsOn": [
|
||||
"AF: Dart Clean",
|
||||
"AF: Flutter Clean",
|
||||
"AF: Build Appflowy Core For Android",
|
||||
"AF: Flutter Pub Get",
|
||||
"AF: Generate Language Files",
|
||||
"AF: Generate Freezed Files",
|
||||
"AF: Generate Svg Files"
|
||||
],
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "new"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Build Appflowy Core",
|
||||
"type": "shell",
|
||||
"windows": {
|
||||
"command": "cargo make --profile development-windows-x86 appflowy-core-dev"
|
||||
},
|
||||
"linux": {
|
||||
"command": "cargo make --profile \"development-linux-$(uname -m)\" appflowy-core-dev"
|
||||
},
|
||||
"osx": {
|
||||
"command": "cargo make --profile \"development-mac-$(uname -m)\" appflowy-core-dev"
|
||||
},
|
||||
"group": "build",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Build Appflowy Core For iOS",
|
||||
"type": "shell",
|
||||
@@ -81,24 +116,6 @@
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Clean + Rebuild All (Android)",
|
||||
"type": "shell",
|
||||
"dependsOrder": "sequence",
|
||||
"dependsOn": [
|
||||
"AF: Flutter Clean",
|
||||
"AF: Build Appflowy Core For Android",
|
||||
"AF: Flutter Pub Get",
|
||||
"AF: Flutter Package Get",
|
||||
"AF: Generate Language Files",
|
||||
"AF: Generate Freezed Files",
|
||||
"AF: Generate Svg Files"
|
||||
],
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "new"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Build Appflowy Core For Android",
|
||||
"type": "shell",
|
||||
@@ -108,23 +125,6 @@
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Build Appflowy Core",
|
||||
"type": "shell",
|
||||
"windows": {
|
||||
"command": "cargo make --profile development-windows-x86 appflowy-core-dev"
|
||||
},
|
||||
"linux": {
|
||||
"command": "cargo make --profile \"development-linux-$(uname -m)\" appflowy-core-dev"
|
||||
},
|
||||
"osx": {
|
||||
"command": "cargo make --profile \"development-mac-$(uname -m)\" appflowy-core-dev"
|
||||
},
|
||||
"group": "build",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Code Gen",
|
||||
"type": "shell",
|
||||
@@ -132,7 +132,6 @@
|
||||
"dependsOn": [
|
||||
"AF: Flutter Clean",
|
||||
"AF: Flutter Pub Get",
|
||||
"AF: Flutter Package Get",
|
||||
"AF: Generate Language Files",
|
||||
"AF: Generate Freezed Files",
|
||||
"AF: Generate Svg Files"
|
||||
@@ -146,6 +145,15 @@
|
||||
"panel": "new"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Dart Clean",
|
||||
"type": "shell",
|
||||
"command": "cargo make flutter_clean",
|
||||
"group": "build",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Flutter Clean",
|
||||
"type": "shell",
|
||||
@@ -162,14 +170,6 @@
|
||||
"cwd": "${workspaceFolder}/appflowy_flutter"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Flutter Package Get",
|
||||
"type": "shell",
|
||||
"command": "flutter packages pub get",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/appflowy_flutter"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Generate Freezed Files",
|
||||
"type": "shell",
|
||||
@@ -233,34 +233,18 @@
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Flutter Clean",
|
||||
"type": "shell",
|
||||
"command": "cargo make flutter_clean",
|
||||
"group": "build",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: flutter build aar",
|
||||
"type": "flutter",
|
||||
"command": "flutter",
|
||||
"args": ["build", "aar"],
|
||||
"args": [
|
||||
"build",
|
||||
"aar"
|
||||
],
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"detail": "appflowy_flutter"
|
||||
},
|
||||
{
|
||||
"label": "AF: Tauri UI Dev",
|
||||
"type": "shell",
|
||||
"isBackground": true,
|
||||
"command": "yarn",
|
||||
"args": ["dev"],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/appflowy_tauri"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Tauri UI Build",
|
||||
"type": "shell",
|
||||
@@ -270,9 +254,10 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "AF: Tauri Dev",
|
||||
"label": "AF: Tauri UI Dev",
|
||||
"type": "shell",
|
||||
"command": "npm run tauri:dev",
|
||||
"isBackground": true,
|
||||
"command": "pnpm sync:i18n && pnpm run dev",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/appflowy_tauri"
|
||||
}
|
||||
@@ -289,7 +274,10 @@
|
||||
"label": "AF: Tauri Clean + Dev",
|
||||
"type": "shell",
|
||||
"dependsOrder": "sequence",
|
||||
"dependsOn": ["AF: Tauri Clean", "AF: Tauri UI Dev"],
|
||||
"dependsOn": [
|
||||
"AF: Tauri Clean",
|
||||
"AF: Tauri UI Dev"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
@@ -309,6 +297,6 @@
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/appflowy_flutter"
|
||||
}
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+10
-3
@@ -10,6 +10,7 @@ extend = [
|
||||
{ path = "scripts/makefile/flutter.toml" },
|
||||
{ path = "scripts/makefile/tool.toml" },
|
||||
{ path = "scripts/makefile/tauri.toml" },
|
||||
{ path = "scripts/makefile/web.toml" },
|
||||
]
|
||||
|
||||
[config]
|
||||
@@ -25,7 +26,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
||||
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
||||
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
||||
LIB_NAME = "dart_ffi"
|
||||
CURRENT_APP_VERSION = "0.3.9"
|
||||
APPFLOWY_VERSION = "0.5.4"
|
||||
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite"
|
||||
PRODUCT_NAME = "AppFlowy"
|
||||
MACOSX_DEPLOYMENT_TARGET = "11.0"
|
||||
@@ -48,6 +49,9 @@ LIB_EXT = "a"
|
||||
APP_ENVIRONMENT = "local"
|
||||
FLUTTER_FLOWY_SDK_PATH = "appflowy_flutter/packages/appflowy_backend"
|
||||
TAURI_BACKEND_SERVICE_PATH = "appflowy_tauri/src/services/backend"
|
||||
WEB_BACKEND_SERVICE_PATH = "appflowy_web/src/services/backend"
|
||||
WEB_LIB_PATH = "appflowy_web/wasm-libs/af-wasm"
|
||||
TAURI_APP_BACKEND_SERVICE_PATH = "appflowy_web_app/src/application/services/tauri-services/backend"
|
||||
# Test default config
|
||||
TEST_CRATE_TYPE = "cdylib"
|
||||
TEST_LIB_EXT = "dylib"
|
||||
@@ -127,6 +131,7 @@ FLUTTER_OUTPUT_DIR = "Release"
|
||||
PRODUCT_EXT = "exe"
|
||||
CRATE_TYPE = "cdylib"
|
||||
LIB_EXT = "dll"
|
||||
BUILD_ARCHS = "x64"
|
||||
APP_ENVIRONMENT = "production"
|
||||
|
||||
[env.development-linux-x86_64]
|
||||
@@ -201,6 +206,7 @@ TARGET_OS = "android"
|
||||
CRATE_TYPE = "cdylib"
|
||||
FLUTTER_OUTPUT_DIR = "Debug"
|
||||
LIB_EXT = "so"
|
||||
PRODUCT_EXT = "apk"
|
||||
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite,openssl_vendored"
|
||||
|
||||
[env.production-android]
|
||||
@@ -208,6 +214,7 @@ BUILD_FLAG = "release"
|
||||
TARGET_OS = "android"
|
||||
CRATE_TYPE = "cdylib"
|
||||
FLUTTER_OUTPUT_DIR = "Release"
|
||||
PRODUCT_EXT = "apk"
|
||||
LIB_EXT = "so"
|
||||
|
||||
[tasks.echo_env]
|
||||
@@ -220,8 +227,8 @@ script = ['''
|
||||
echo FEATURES: ${FLUTTER_DESKTOP_FEATURES}
|
||||
echo PRODUCT_EXT: ${PRODUCT_EXT}
|
||||
echo APP_ENVIRONMENT: ${APP_ENVIRONMENT}
|
||||
echo ${platforms}
|
||||
echo ${BUILD_ARCHS}
|
||||
echo BUILD_ARCHS: ${BUILD_ARCHS}
|
||||
echo BUILD_VERSION: ${BUILD_VERSION}
|
||||
''']
|
||||
script_runner = "@shell"
|
||||
|
||||
|
||||
@@ -30,10 +30,27 @@ linter:
|
||||
rules:
|
||||
- require_trailing_commas
|
||||
|
||||
- prefer_collection_literals
|
||||
- prefer_final_fields
|
||||
- prefer_final_in_for_each
|
||||
- prefer_final_locals
|
||||
|
||||
- sized_box_for_whitespace
|
||||
- use_decorated_box
|
||||
|
||||
- unnecessary_parenthesis
|
||||
- unnecessary_await_in_return
|
||||
- unnecessary_raw_strings
|
||||
|
||||
- avoid_unnecessary_containers
|
||||
- avoid_redundant_argument_values
|
||||
- avoid_unused_constructor_parameters
|
||||
|
||||
- always_declare_return_types
|
||||
|
||||
- sort_constructors_first
|
||||
- unawaited_futures
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
|
||||
|
||||
@@ -25,8 +25,14 @@ apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
def keystoreProperties = new Properties()
|
||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 33
|
||||
compileSdkVersion 34
|
||||
ndkVersion "24.0.8215888"
|
||||
|
||||
compileOptions {
|
||||
@@ -47,7 +53,7 @@ android {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "io.appflowy.appflowy"
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 31
|
||||
targetSdkVersion 33
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
multiDexEnabled true
|
||||
@@ -58,13 +64,18 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
|
||||
storePassword keystoreProperties['storePassword']
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
|
||||
// use release instead when publishing the application to google play.
|
||||
// signingConfig signingConfigs.release
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,4 +47,9 @@
|
||||
</application>
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.support.customtabs.action.CustomTabsService" />
|
||||
</intent>
|
||||
</queries>
|
||||
</manifest>
|
||||
@@ -2,12 +2,21 @@ cmake_minimum_required(VERSION 3.10.0)
|
||||
|
||||
project(AppFlowy)
|
||||
|
||||
message(CONFIGURE_LOG "NDK PATH: ${ANDROID_NDK}")
|
||||
message(CONFIGURE_LOG "Copying libc++_shared.so")
|
||||
|
||||
# arm64-v8a
|
||||
file(COPY
|
||||
${ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so
|
||||
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/jniLibs/arm64-v8a
|
||||
)
|
||||
|
||||
# armeabi-v7a
|
||||
file(COPY
|
||||
${ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so
|
||||
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/jniLibs/armeabi-v7a
|
||||
)
|
||||
|
||||
# x86_64
|
||||
file(COPY
|
||||
${ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/x86_64/libc++_shared.so
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int64_t init_sdk(char *data);
|
||||
int64_t init_sdk(int64_t port, char *data);
|
||||
|
||||
void async_event(int64_t port, const uint8_t *input, uintptr_t len);
|
||||
|
||||
@@ -13,6 +13,6 @@ int32_t set_stream_port(int64_t port);
|
||||
|
||||
void link_me_please(void);
|
||||
|
||||
void backend_log(int64_t level, const char *data);
|
||||
void rust_log(int64_t level, const char *data);
|
||||
|
||||
void set_env(const char *data);
|
||||
@@ -73,9 +73,9 @@
|
||||
"attributes": { "subtype": "checkbox", "checkbox": true },
|
||||
"delta": [
|
||||
{ "insert": "Click " },
|
||||
{ "insert": "+ New Page ", "attributes": { "code": true } },
|
||||
{ "insert": "+ New Page", "attributes": { "code": true } },
|
||||
{
|
||||
"insert": "button at the bottom of your sidebar to add a new page."
|
||||
"insert": " button at the bottom of your sidebar to add a new page."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# AppFlowy Test Markdown import with table
|
||||
|
||||
# Table
|
||||
|
||||
| S.No. | Column 2 |
|
||||
| --- | --- |
|
||||
| 1. | row 1 |
|
||||
| 2. | row 2 |
|
||||
| 3. | row 3 |
|
||||
| 4. | row 4 |
|
||||
| 5. | row 5 |
|
||||
@@ -0,0 +1 @@
|
||||
extensions:
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
SUPABASE_URL=
|
||||
SUPABASE_ANON_KEY=
|
||||
|
||||
APPFLOWY_CLOUD_URL=
|
||||
@@ -1,133 +0,0 @@
|
||||
// ignore_for_file: unused_import
|
||||
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.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/settings/widgets/setting_appflowy_cloud.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart';
|
||||
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';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('appflowy cloud auth', () {
|
||||
testWidgets('sign in', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloud,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
tester.expectToSeeHomePage();
|
||||
});
|
||||
|
||||
testWidgets('sign out', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloud,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
|
||||
// Open the setting page and sign out
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
await tester.tapButton(find.byType(SettingLogoutButton));
|
||||
|
||||
tester.expectToSeeText(LocaleKeys.button_ok.tr());
|
||||
await tester.tapButtonWithName(LocaleKeys.button_ok.tr());
|
||||
|
||||
// Go to the sign in page again
|
||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||
tester.expectToSeeGoogleLoginButton();
|
||||
});
|
||||
|
||||
testWidgets('sign in as annoymous', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloud,
|
||||
);
|
||||
await tester.tapSignInAsGuest();
|
||||
|
||||
// should not see the sync setting page when sign in as annoymous
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
tester.expectToSeeGoogleLoginButton();
|
||||
});
|
||||
|
||||
testWidgets('enable sync', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloud,
|
||||
);
|
||||
|
||||
await tester.tapGoogleLoginInButton();
|
||||
// Open the setting page and sign out
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.cloud);
|
||||
|
||||
// the switch should be on by default
|
||||
tester.assertAppFlowyCloudEnableSyncSwitchValue(true);
|
||||
await tester.toggleEnableSync(AppFlowyCloudEnableSync);
|
||||
|
||||
// the switch should be off
|
||||
tester.assertAppFlowyCloudEnableSyncSwitchValue(false);
|
||||
|
||||
// the switch should be on after toggling
|
||||
await tester.toggleEnableSync(AppFlowyCloudEnableSync);
|
||||
tester.assertAppFlowyCloudEnableSyncSwitchValue(true);
|
||||
});
|
||||
|
||||
// testWidgets('custom folder sign in', (tester) async {
|
||||
// const userA = 'UserA';
|
||||
// final userAEmail = "${uuid()}@appflowy.io";
|
||||
// final initialPath = p.join(userA, appFlowyDataFolder);
|
||||
// final context = await tester.initializeAppFlowy(
|
||||
// cloudType: AuthenticatorType.appflowyCloud,
|
||||
// pathExtension: initialPath,
|
||||
// );
|
||||
// getIt.registerFactory<AuthService>(
|
||||
// () => AppFlowyCloudMockAuthService(
|
||||
// email: userAEmail,
|
||||
// ),
|
||||
// );
|
||||
// // remove the last extension
|
||||
// final rootPath = context.applicationDataDirectory.replaceFirst(
|
||||
// initialPath,
|
||||
// '',
|
||||
// );
|
||||
// await tester.tapGoogleLoginInButton();
|
||||
|
||||
// // Open the setting page and sign out
|
||||
// await tester.openSettings();
|
||||
// await tester.openSettingsPage(SettingsPage.user);
|
||||
// await tester.enterUserName(userA);
|
||||
|
||||
// await tester.openSettingsPage(SettingsPage.files);
|
||||
// await tester.pumpAndSettle();
|
||||
|
||||
// // mock the file_picker result
|
||||
// await mockGetDirectoryPath(
|
||||
// p.join(rootPath, "random_folder"),
|
||||
// );
|
||||
|
||||
// // after selecting the folder, an annoymous user should be signed in
|
||||
// await tester.tapCustomLocationButton();
|
||||
// tester.expectToSeeHomePage();
|
||||
// await tester.pumpAndSettle();
|
||||
|
||||
// // Login as userA in custom folder
|
||||
// await tester.openSettings();
|
||||
// await tester.openSettingsPage(SettingsPage.user);
|
||||
// await tester.tapGoogleLoginInButton();
|
||||
|
||||
// await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||
// tester.expectToSeeHomePage();
|
||||
// // UserA should be displayed
|
||||
// tester.expectToSeeUserName(userA);
|
||||
// });
|
||||
});
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/board/presentation/widgets/board_column_header.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/card/container/card_container.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
import 'package:appflowy_board/appflowy_board.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../util/util.dart';
|
||||
|
||||
const defaultFirstCardName = 'Card 1';
|
||||
const defaultLastCardName = 'Card 3';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('board add row test:', () {
|
||||
testWidgets('from header', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
|
||||
|
||||
final findFirstCard = find.descendant(
|
||||
of: find.byType(AppFlowyGroupCard),
|
||||
matching: find.byType(FlowyText),
|
||||
);
|
||||
|
||||
FlowyText firstCardText = tester.firstWidget(findFirstCard);
|
||||
expect(firstCardText.text, defaultFirstCardName);
|
||||
|
||||
await tester.tap(
|
||||
find
|
||||
.descendant(
|
||||
of: find.byType(BoardColumnHeader),
|
||||
matching: find.byWidgetPredicate(
|
||||
(widget) => widget is FlowySvg && widget.svg == FlowySvgs.add_s,
|
||||
),
|
||||
)
|
||||
.at(1),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
const newCardName = 'Card 4';
|
||||
await tester.enterText(
|
||||
find.descendant(
|
||||
of: find.byType(RowCardContainer),
|
||||
matching: find.byType(TextField),
|
||||
),
|
||||
newCardName,
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.byType(AppFlowyBoard));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
firstCardText = tester.firstWidget(findFirstCard);
|
||||
expect(firstCardText.text, newCardName);
|
||||
});
|
||||
|
||||
testWidgets('from footer', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
|
||||
|
||||
final findLastCard = find.descendant(
|
||||
of: find.byType(AppFlowyGroupCard),
|
||||
matching: find.byType(FlowyText),
|
||||
);
|
||||
|
||||
FlowyText? lastCardText =
|
||||
tester.widgetList(findLastCard).last as FlowyText;
|
||||
expect(lastCardText.text, defaultLastCardName);
|
||||
|
||||
await tester.tap(
|
||||
find
|
||||
.descendant(
|
||||
of: find.byType(AppFlowyGroupFooter),
|
||||
matching: find.byType(FlowySvg),
|
||||
)
|
||||
.at(1),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
const newCardName = 'Card 4';
|
||||
await tester.enterText(
|
||||
find.descendant(
|
||||
of: find.byType(RowCardContainer),
|
||||
matching: find.byType(TextField),
|
||||
),
|
||||
newCardName,
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.byType(AppFlowyBoard));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
lastCardText = tester.widgetList(findLastCard).last as FlowyText;
|
||||
expect(lastCardText.text, newCardName);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/cells/select_option_cell/extension.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/row_property.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
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';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('board group test', () {
|
||||
testWidgets('move row to another group', (tester) async {
|
||||
const card1Name = 'Card 1';
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
|
||||
final card1 = find.ancestor(
|
||||
of: find.findTextInFlowyText(card1Name),
|
||||
matching: find.byType(AppFlowyGroupCard),
|
||||
);
|
||||
final doingGroup = find.findTextInFlowyText('Doing');
|
||||
final doingGroupCenter = tester.getCenter(doingGroup);
|
||||
final card1Center = tester.getCenter(card1);
|
||||
|
||||
await tester.timedDrag(
|
||||
card1,
|
||||
doingGroupCenter.translate(-card1Center.dx, -card1Center.dy),
|
||||
const Duration(seconds: 1),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(card1);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final card1StatusFinder = find.descendant(
|
||||
of: find.byType(RowPropertyList),
|
||||
matching: find.descendant(
|
||||
of: find.byType(SelectOptionTag),
|
||||
matching: find.byType(FlowyText),
|
||||
),
|
||||
);
|
||||
expect(card1StatusFinder, findsNWidgets(1));
|
||||
final card1StatusText = tester.widget<FlowyText>(card1StatusFinder).text;
|
||||
expect(card1StatusText, 'Doing');
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// ignore_for_file: unused_import
|
||||
|
||||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.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/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('appflowy cloud', () {
|
||||
testWidgets('anon user and then sign in', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
);
|
||||
|
||||
tester.expectToSeeText(LocaleKeys.signIn_loginStartWithAnonymous.tr());
|
||||
await tester.tapGoButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
|
||||
// reanme the name of the anon user
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
final userNameFinder = find.descendant(
|
||||
of: find.byType(SettingsUserView),
|
||||
matching: find.byType(UserNameInput),
|
||||
);
|
||||
await tester.enterText(userNameFinder, 'local_user');
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// sign up with Google
|
||||
await tester.tapGoogleLoginInButton();
|
||||
|
||||
// sign out
|
||||
await tester.expectToSeeHomePage();
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
await tester.logout();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// tap the continue as anonymous button
|
||||
await tester
|
||||
.tapButton(find.text(LocaleKeys.signIn_loginStartWithAnonymous.tr()));
|
||||
await tester.expectToSeeHomePage();
|
||||
|
||||
// New anon user name
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
final userNameInput = tester.widget(userNameFinder) as UserNameInput;
|
||||
expect(userNameInput.name, 'Me');
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// ignore_for_file: unused_import
|
||||
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.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/settings/widgets/setting_appflowy_cloud.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.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/mock/mock_file_picker.dart';
|
||||
import '../shared/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('appflowy cloud auth', () {
|
||||
testWidgets('sign in', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
});
|
||||
|
||||
testWidgets('sign out', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
|
||||
// Open the setting page and sign out
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
await tester.tapButton(find.byType(SettingLogoutButton));
|
||||
|
||||
tester.expectToSeeText(LocaleKeys.button_ok.tr());
|
||||
await tester.tapButtonWithName(LocaleKeys.button_ok.tr());
|
||||
|
||||
// Go to the sign in page again
|
||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||
tester.expectToSeeGoogleLoginButton();
|
||||
});
|
||||
|
||||
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 anonymous
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
tester.expectToSeeGoogleLoginButton();
|
||||
});
|
||||
|
||||
testWidgets('enable sync', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
);
|
||||
|
||||
await tester.tapGoogleLoginInButton();
|
||||
// Open the setting page and sign out
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.cloud);
|
||||
|
||||
// the switch should be on by default
|
||||
tester.assertAppFlowyCloudEnableSyncSwitchValue(true);
|
||||
await tester.toggleEnableSync(AppFlowyCloudEnableSync);
|
||||
|
||||
// the switch should be off
|
||||
tester.assertAppFlowyCloudEnableSyncSwitchValue(false);
|
||||
|
||||
// the switch should be on after toggling
|
||||
await tester.toggleEnableSync(AppFlowyCloudEnableSync);
|
||||
tester.assertAppFlowyCloudEnableSyncSwitchValue(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import 'anon_user_continue_test.dart' as anon_user_continue_test;
|
||||
import 'appflowy_cloud_auth_test.dart' as appflowy_cloud_auth_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 'workspace/change_name_and_icon_test.dart'
|
||||
as change_workspace_name_and_icon_test;
|
||||
import 'workspace/collaborative_workspace_test.dart'
|
||||
as collaboration_workspace_test;
|
||||
|
||||
Future<void> main() async {
|
||||
preset_af_cloud_env_test.main();
|
||||
|
||||
appflowy_cloud_auth_test.main();
|
||||
|
||||
// document_sync_test.main();
|
||||
|
||||
user_sync_test.main();
|
||||
|
||||
anon_user_continue_test.main();
|
||||
|
||||
// workspace
|
||||
collaboration_workspace_test.main();
|
||||
change_workspace_name_and_icon_test.main();
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// 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/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/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:path/path.dart' as p;
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import '../shared/dir.dart';
|
||||
import '../shared/mock/mock_file_picker.dart';
|
||||
import '../shared/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
final email = '${uuid()}@appflowy.io';
|
||||
const inputContent = 'Hello world, this is a test document';
|
||||
|
||||
// The test will create a new document called Sample, and sync it to the server.
|
||||
// Then the test will logout the user, and login with the same user. The data will
|
||||
// be synced from the server.
|
||||
group('appflowy cloud document', () {
|
||||
testWidgets('sync local docuemnt to server', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
email: email,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
|
||||
// create a new document called Sample
|
||||
await tester.createNewPage();
|
||||
|
||||
// focus on the editor
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
await tester.ime.insertText(inputContent);
|
||||
expect(find.text(inputContent, findRichText: true), findsOneWidget);
|
||||
|
||||
// TODO(nathan): remove the await
|
||||
// 6 seconds for data sync
|
||||
await tester.waitForSeconds(6);
|
||||
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
await tester.logout();
|
||||
});
|
||||
|
||||
testWidgets('sync doc from server', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
email: email,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
await tester.expectToSeeHomePage();
|
||||
|
||||
// the latest document will be opened, so the content must be the inputContent
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text(inputContent, findRichText: true), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../shared/util.dart';
|
||||
|
||||
// This test is meaningless, just for preventing the CI from failing.
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('Empty', () {
|
||||
testWidgets('set appflowy cloud', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
+5
-4
@@ -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();
|
||||
@@ -15,7 +16,7 @@ void main() {
|
||||
testWidgets('sign in with supabase', (tester) async {
|
||||
await tester.initializeAppFlowy(cloudType: AuthenticatorType.supabase);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
tester.expectToSeeHomePage();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
});
|
||||
|
||||
testWidgets('sign out with supabase', (tester) async {
|
||||
@@ -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();
|
||||
@@ -0,0 +1,100 @@
|
||||
// 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/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/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:path/path.dart' as p;
|
||||
import 'package:integration_test/integration_test.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();
|
||||
final email = '${uuid()}@appflowy.io';
|
||||
const name = 'nathan';
|
||||
|
||||
group('appflowy cloud setting', () {
|
||||
testWidgets('sync user name and icon to server', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
email: email,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
// final userAvatarFinder = find.descendant(
|
||||
// of: find.byType(SettingsUserView),
|
||||
// matching: find.byType(UserAvatar),
|
||||
// );
|
||||
|
||||
// Open icon picker dialog and select emoji
|
||||
// await tester.tap(userAvatarFinder);
|
||||
// await tester.pumpAndSettle();
|
||||
// await tester.tapEmoji('😁');
|
||||
// await tester.pumpAndSettle();
|
||||
// final UserAvatar userAvatar =
|
||||
// tester.widget(userAvatarFinder) as UserAvatar;
|
||||
// expect(userAvatar.iconUrl, '😁');
|
||||
|
||||
// enter user name
|
||||
final userNameFinder = find.descendant(
|
||||
of: find.byType(SettingsUserView),
|
||||
matching: find.byType(UserNameInput),
|
||||
);
|
||||
await tester.enterText(userNameFinder, name);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tapEscButton();
|
||||
|
||||
// wait 2 seconds for the sync to finish
|
||||
await tester.pumpAndSettle(const Duration(seconds: 2));
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('get user icon and name from server', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
email: email,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.openSettings();
|
||||
await tester.openSettingsPage(SettingsPage.user);
|
||||
|
||||
// verify icon
|
||||
// final userAvatarFinder = find.descendant(
|
||||
// of: find.byType(SettingsUserView),
|
||||
// matching: find.byType(UserAvatar),
|
||||
// );
|
||||
// final UserAvatar userAvatar = tester.widget(userAvatarFinder) as UserAvatar;
|
||||
// expect(userAvatar.iconUrl, '😁');
|
||||
|
||||
// verify name
|
||||
final userNameFinder = find.descendant(
|
||||
of: find.byType(SettingsUserView),
|
||||
matching: find.byType(UserNameInput),
|
||||
);
|
||||
final UserNameInput userNameInput =
|
||||
tester.widget(userNameFinder) as UserNameInput;
|
||||
expect(userNameInput.name, name);
|
||||
});
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
// ignore_for_file: unused_import
|
||||
|
||||
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/workspace/_sidebar_workspace_icon.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: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/mock/mock_file_picker.dart';
|
||||
import '../../shared/util.dart';
|
||||
import '../../shared/workspace.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
const icon = '😄';
|
||||
const name = 'AppFlowy';
|
||||
final email = '${uuid()}@appflowy.io';
|
||||
|
||||
testWidgets('change name and icon', (tester) async {
|
||||
// only run the test when the feature flag is on
|
||||
if (!FeatureFlag.collaborativeWorkspace.isOn) {
|
||||
return;
|
||||
}
|
||||
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
email: email, // use the same email to check the next test
|
||||
);
|
||||
|
||||
await tester.tapGoogleLoginInButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
|
||||
var workspaceIcon = tester.widget<WorkspaceIcon>(
|
||||
find.byType(WorkspaceIcon),
|
||||
);
|
||||
expect(workspaceIcon.workspace.icon, '');
|
||||
|
||||
await tester.openWorkspaceMenu();
|
||||
await tester.changeWorkspaceIcon(icon);
|
||||
await tester.changeWorkspaceName(name);
|
||||
|
||||
workspaceIcon = tester.widget<WorkspaceIcon>(
|
||||
find.byType(WorkspaceIcon),
|
||||
);
|
||||
expect(workspaceIcon.workspace.icon, icon);
|
||||
expect(find.findTextInFlowyText(name), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('verify the result again after relaunching', (tester) async {
|
||||
// only run the test when the feature flag is on
|
||||
if (!FeatureFlag.collaborativeWorkspace.isOn) {
|
||||
return;
|
||||
}
|
||||
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
email: email, // use the same email to check the next test
|
||||
);
|
||||
|
||||
await tester.tapGoogleLoginInButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
|
||||
// check the result again
|
||||
final workspaceIcon = tester.widget<WorkspaceIcon>(
|
||||
find.byType(WorkspaceIcon),
|
||||
);
|
||||
expect(workspaceIcon.workspace.icon, icon);
|
||||
expect(workspaceIcon.workspace.name, name);
|
||||
});
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
// 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/plugins/document/presentation/editor_plugins/openai/widgets/loading.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', () {
|
||||
// combine the create and delete workspace test to reduce the time
|
||||
testWidgets('create a new workspace, open it and then delete it',
|
||||
(tester) async {
|
||||
// only run the test when the feature flag is on
|
||||
if (!FeatureFlag.collaborativeWorkspace.isOn) {
|
||||
return;
|
||||
}
|
||||
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
email: email,
|
||||
);
|
||||
await tester.tapGoogleLoginInButton();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
|
||||
const name = 'AppFlowy.IO';
|
||||
// the workspace will be opened after created
|
||||
await tester.createCollaborativeWorkspace(name);
|
||||
|
||||
final loading = find.byType(Loading);
|
||||
await tester.pumpUntilNotFound(loading);
|
||||
|
||||
Finder success;
|
||||
|
||||
// delete the newly created workspace
|
||||
await tester.openCollaborativeWorkspaceMenu();
|
||||
final Finder items = find.byType(WorkspaceMenuItem);
|
||||
expect(items, findsNWidgets(2));
|
||||
expect(
|
||||
tester.widget<WorkspaceMenuItem>(items.last).workspace.name,
|
||||
name,
|
||||
);
|
||||
|
||||
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());
|
||||
await tester.pumpUntilFound(success);
|
||||
expect(success, findsOneWidget);
|
||||
await tester.pumpUntilNotFound(success);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import 'auth/appflowy_cloud_auth_test.dart' as appflowy_cloud_auth_test;
|
||||
import 'empty_test.dart' as first_test;
|
||||
|
||||
Future<void> main() async {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
// This test must be run first, otherwise the CI will fail.
|
||||
first_test.main();
|
||||
|
||||
appflowy_cloud_auth_test.main();
|
||||
}
|
||||
@@ -1,212 +0,0 @@
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/grid_page.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/header/type_option/select_option.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/protobuf.dart';
|
||||
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/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('grid field editor:', () {
|
||||
testWidgets('rename existing field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Invoke the field editor
|
||||
await tester.tapGridFieldWithName('Name');
|
||||
await tester.tapEditPropertyButton();
|
||||
|
||||
await tester.renameField('hello world');
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
await tester.tapGridFieldWithName('hello world');
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('update field type of existing field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Invoke the field editor
|
||||
await tester.tapGridFieldWithName('Type');
|
||||
await tester.tapEditPropertyButton();
|
||||
|
||||
await tester.tapTypeOptionButton();
|
||||
await tester.selectFieldType(FieldType.Checkbox);
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
await tester.assertFieldTypeWithFieldName(
|
||||
'Type',
|
||||
FieldType.Checkbox,
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('create a field and rename it', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new grid
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// create a field
|
||||
await tester.createField(FieldType.Checklist, 'checklist');
|
||||
|
||||
// check the field is created successfully
|
||||
await tester.findFieldWithName('checklist');
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('delete field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// create a field
|
||||
await tester.createField(FieldType.Checkbox, 'New field 1');
|
||||
|
||||
// Delete the field
|
||||
await tester.tapGridFieldWithName('New field 1');
|
||||
await tester.tapDeletePropertyButton();
|
||||
|
||||
// confirm delete
|
||||
await tester.tapDialogOkButton();
|
||||
|
||||
await tester.noFieldWithName('New field 1');
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('duplicate field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// create a field
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
await tester.tapNewPropertyButton();
|
||||
await tester.renameField('New field 1');
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
// duplicate the field
|
||||
await tester.tapGridFieldWithName('New field 1');
|
||||
await tester.tapDuplicatePropertyButton();
|
||||
|
||||
await tester.findFieldWithName('New field 1 (copy)');
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('insert field on either side of a field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
|
||||
// insert new field to the right
|
||||
await tester.tapGridFieldWithName('Type');
|
||||
await tester.tapInsertFieldButton(left: false, name: 'Right');
|
||||
await tester.dismissFieldEditor();
|
||||
await tester.findFieldWithName('Right');
|
||||
|
||||
// insert new field to the right
|
||||
await tester.tapGridFieldWithName('Type');
|
||||
await tester.tapInsertFieldButton(left: true, name: "Left");
|
||||
await tester.dismissFieldEditor();
|
||||
await tester.findFieldWithName('Left');
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('create checklist field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
await tester.tapNewPropertyButton();
|
||||
|
||||
// Open the type option menu
|
||||
await tester.tapTypeOptionButton();
|
||||
|
||||
await tester.selectFieldType(FieldType.Checklist);
|
||||
|
||||
// After update the field type, the cells should be updated
|
||||
await tester.findCellByFieldType(FieldType.Checklist);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('create list of fields', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
|
||||
for (final fieldType in [
|
||||
FieldType.Checklist,
|
||||
FieldType.DateTime,
|
||||
FieldType.Number,
|
||||
FieldType.URL,
|
||||
FieldType.MultiSelect,
|
||||
FieldType.LastEditedTime,
|
||||
FieldType.CreatedTime,
|
||||
FieldType.Checkbox,
|
||||
]) {
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
await tester.tapNewPropertyButton();
|
||||
await tester.renameField(fieldType.name);
|
||||
|
||||
// Open the type option menu
|
||||
await tester.tapTypeOptionButton();
|
||||
|
||||
await tester.selectFieldType(fieldType);
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
// After update the field type, the cells should be updated
|
||||
await tester.findCellByFieldType(fieldType);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('add option', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(
|
||||
layout: ViewLayoutPB.Grid,
|
||||
);
|
||||
|
||||
// Invoke the field editor
|
||||
await tester.tapGridFieldWithName('Type');
|
||||
await tester.tapEditPropertyButton();
|
||||
|
||||
// tap 'add option' button
|
||||
await tester.tapAddSelectOptionButton();
|
||||
const text = 'Hello AppFlowy';
|
||||
final inputField = find.descendant(
|
||||
of: find.byType(CreateOptionTextField),
|
||||
matching: find.byType(TextField),
|
||||
);
|
||||
await tester.enterText(inputField, text);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.testTextInput.receiveAction(TextInputAction.done);
|
||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||
|
||||
// check the result
|
||||
tester.expectToSeeText(text);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/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';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('grid', () {
|
||||
testWidgets('create row of the grid', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.tapCreateRowButtonInGrid();
|
||||
|
||||
// The initial number of rows is 3
|
||||
await tester.assertNumberOfRowsInGridPage(4);
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('create row from row menu of the grid', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
|
||||
await tester.hoverOnFirstRowOfGrid();
|
||||
|
||||
await tester.tapCreateRowButtonInRowMenuOfGrid();
|
||||
|
||||
// The initial number of rows is 3
|
||||
await tester.assertNumberOfRowsInGridPage(4);
|
||||
await tester.assertRowCountInGridPage(4);
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('delete row of the grid', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.hoverOnFirstRowOfGrid();
|
||||
|
||||
// Open the row menu and then click the delete
|
||||
await tester.tapRowMenuButtonInGrid();
|
||||
await tester.tapDeleteOnRowMenu();
|
||||
|
||||
// The initial number of rows is 3
|
||||
await tester.assertNumberOfRowsInGridPage(2);
|
||||
await tester.assertRowCountInGridPage(2);
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('check number of row indicator in the initial grid',
|
||||
(tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.assertRowCountInGridPage(3);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,268 +0,0 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../util/database_test_op.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('grid', () {
|
||||
testWidgets('add text sort', (tester) async {
|
||||
await tester.openV020database();
|
||||
// create a sort
|
||||
await tester.tapDatabaseSortButton();
|
||||
await tester.tapCreateSortByFieldType(FieldType.RichText, 'Name');
|
||||
|
||||
// check the text cell order
|
||||
final textCells = <String>[
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
];
|
||||
for (final (index, content) in textCells.indexed) {
|
||||
await tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.RichText,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
|
||||
// open the sort menu and select order by descending
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.tapSortButtonByName('Name');
|
||||
await tester.tapSortByDescending();
|
||||
for (final (index, content) in <String>[
|
||||
'E',
|
||||
'D',
|
||||
'C',
|
||||
'B',
|
||||
'A',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
].indexed) {
|
||||
await tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.RichText,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
|
||||
// delete all sorts
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.tapAllSortButton();
|
||||
|
||||
// check the text cell order
|
||||
for (final (index, content) in <String>[
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
].indexed) {
|
||||
await tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.RichText,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('add checkbox sort', (tester) async {
|
||||
await tester.openV020database();
|
||||
// create a filter
|
||||
await tester.tapDatabaseSortButton();
|
||||
await tester.tapCreateSortByFieldType(FieldType.Checkbox, 'Done');
|
||||
|
||||
// check the checkbox cell order
|
||||
for (final (index, content) in <bool>[
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
].indexed) {
|
||||
await tester.assertCheckboxCell(
|
||||
rowIndex: index,
|
||||
isSelected: content,
|
||||
);
|
||||
}
|
||||
|
||||
// open the sort menu and select order by descending
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.tapSortButtonByName('Done');
|
||||
await tester.tapSortByDescending();
|
||||
for (final (index, content) in <bool>[
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
].indexed) {
|
||||
await tester.assertCheckboxCell(
|
||||
rowIndex: index,
|
||||
isSelected: content,
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('add number sort', (tester) async {
|
||||
await tester.openV020database();
|
||||
// create a filter
|
||||
await tester.tapDatabaseSortButton();
|
||||
await tester.tapCreateSortByFieldType(FieldType.Number, 'number');
|
||||
|
||||
// check the number cell order
|
||||
for (final (index, content) in <String>[
|
||||
'-2',
|
||||
'-1',
|
||||
'0.1',
|
||||
'0.2',
|
||||
'1',
|
||||
'2',
|
||||
'10',
|
||||
'11',
|
||||
'12',
|
||||
'',
|
||||
].indexed) {
|
||||
await tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.Number,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
|
||||
// open the sort menu and select order by descending
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.tapSortButtonByName('number');
|
||||
await tester.tapSortByDescending();
|
||||
for (final (index, content) in <String>[
|
||||
'12',
|
||||
'11',
|
||||
'10',
|
||||
'2',
|
||||
'1',
|
||||
'0.2',
|
||||
'0.1',
|
||||
'-1',
|
||||
'-2',
|
||||
'',
|
||||
].indexed) {
|
||||
await tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.Number,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('add checkbox and number sort', (tester) async {
|
||||
await tester.openV020database();
|
||||
// create a filter
|
||||
await tester.tapDatabaseSortButton();
|
||||
await tester.tapCreateSortByFieldType(FieldType.Checkbox, 'Done');
|
||||
|
||||
// open the sort menu and sort checkbox by descending
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.tapSortButtonByName('Done');
|
||||
await tester.tapSortByDescending();
|
||||
for (final (index, content) in <bool>[
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
].indexed) {
|
||||
await tester.assertCheckboxCell(
|
||||
rowIndex: index,
|
||||
isSelected: content,
|
||||
);
|
||||
}
|
||||
|
||||
// add another sort, this time by number descending
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.tapCreateSortByFieldTypeInSortMenu(
|
||||
FieldType.Number,
|
||||
'number',
|
||||
);
|
||||
await tester.tapSortButtonByName('number');
|
||||
await tester.tapSortByDescending();
|
||||
|
||||
// check checkbox cell order
|
||||
for (final (index, content) in <bool>[
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
].indexed) {
|
||||
await tester.assertCheckboxCell(
|
||||
rowIndex: index,
|
||||
isSelected: content,
|
||||
);
|
||||
}
|
||||
|
||||
// check number cell order
|
||||
for (final (index, content) in <String>[
|
||||
'1',
|
||||
'0.2',
|
||||
'0.1',
|
||||
'-1',
|
||||
'-2',
|
||||
'12',
|
||||
'11',
|
||||
'10',
|
||||
'2',
|
||||
'',
|
||||
].indexed) {
|
||||
await tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.Number,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/plugins/database/board/presentation/widgets/board_column_header.dart';
|
||||
import 'package:appflowy/plugins/database/widgets/card/container/card_container.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_board/appflowy_board.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../../shared/util.dart';
|
||||
|
||||
const defaultFirstCardName = 'Card 1';
|
||||
const defaultLastCardName = 'Card 3';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('board add row test:', () {
|
||||
testWidgets('from header', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
|
||||
final findFirstCard = find.descendant(
|
||||
of: find.byType(AppFlowyGroupCard),
|
||||
matching: find.byType(Text),
|
||||
);
|
||||
|
||||
Text firstCardText = tester.firstWidget(findFirstCard);
|
||||
expect(firstCardText.data, defaultFirstCardName);
|
||||
|
||||
await tester.tap(
|
||||
find
|
||||
.descendant(
|
||||
of: find.byType(BoardColumnHeader),
|
||||
matching: find.byWidgetPredicate(
|
||||
(widget) => widget is FlowySvg && widget.svg == FlowySvgs.add_s,
|
||||
),
|
||||
)
|
||||
.at(1),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
const newCardName = 'Card 4';
|
||||
await tester.enterText(
|
||||
find.descendant(
|
||||
of: find.byType(RowCardContainer),
|
||||
matching: find.byType(TextField),
|
||||
),
|
||||
newCardName,
|
||||
);
|
||||
await tester.pumpAndSettle(const Duration(milliseconds: 500));
|
||||
|
||||
await tester.tap(find.byType(AppFlowyBoard));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
firstCardText = tester.firstWidget(findFirstCard);
|
||||
expect(firstCardText.data, newCardName);
|
||||
});
|
||||
|
||||
testWidgets('from footer', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
|
||||
final findLastCard = find.descendant(
|
||||
of: find.byType(AppFlowyGroupCard),
|
||||
matching: find.byType(Text),
|
||||
);
|
||||
|
||||
Text? lastCardText = tester.widgetList(findLastCard).last as Text;
|
||||
expect(lastCardText.data, defaultLastCardName);
|
||||
|
||||
await tester.tap(
|
||||
find
|
||||
.descendant(
|
||||
of: find.byType(AppFlowyGroupFooter),
|
||||
matching: find.byType(FlowySvg),
|
||||
)
|
||||
.at(1),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
const newCardName = 'Card 4';
|
||||
await tester.enterText(
|
||||
find.descendant(
|
||||
of: find.byType(RowCardContainer),
|
||||
matching: find.byType(TextField),
|
||||
),
|
||||
newCardName,
|
||||
);
|
||||
await tester.pumpAndSettle(const Duration(milliseconds: 500));
|
||||
|
||||
await tester.tap(find.byType(AppFlowyBoard));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
lastCardText = tester.widgetList(findLastCard).last as Text;
|
||||
expect(lastCardText.data, newCardName);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import 'package:appflowy/plugins/database/widgets/cell_editor/extension.dart';
|
||||
import 'package:appflowy/plugins/database/widgets/row/row_property.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:appflowy_board/appflowy_board.dart';
|
||||
|
||||
import '../../shared/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('board group test', () {
|
||||
testWidgets('move row to another group', (tester) async {
|
||||
const card1Name = 'Card 1';
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
final card1 = find.ancestor(
|
||||
of: find.text(card1Name),
|
||||
matching: find.byType(AppFlowyGroupCard),
|
||||
);
|
||||
final doingGroup = find.text('Doing');
|
||||
final doingGroupCenter = tester.getCenter(doingGroup);
|
||||
final card1Center = tester.getCenter(card1);
|
||||
|
||||
await tester.timedDrag(
|
||||
card1,
|
||||
doingGroupCenter.translate(-card1Center.dx, -card1Center.dy),
|
||||
const Duration(seconds: 1),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(card1);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final card1StatusFinder = find.descendant(
|
||||
of: find.byType(RowPropertyList),
|
||||
matching: find.descendant(
|
||||
of: find.byType(SelectOptionTag),
|
||||
matching: find.byType(Text),
|
||||
),
|
||||
);
|
||||
expect(card1StatusFinder, findsNWidgets(1));
|
||||
final card1StatusText = tester.widget<Text>(card1StatusFinder).data;
|
||||
expect(card1StatusText, 'Doing');
|
||||
});
|
||||
});
|
||||
}
|
||||
+8
-8
@@ -1,14 +1,14 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/board/presentation/widgets/board_column_header.dart';
|
||||
import 'package:appflowy/plugins/database_view/board/presentation/widgets/board_hidden_groups.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
import 'package:appflowy/plugins/database/board/presentation/widgets/board_column_header.dart';
|
||||
import 'package:appflowy/plugins/database/board/presentation/widgets/board_hidden_groups.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
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();
|
||||
@@ -17,7 +17,7 @@ void main() {
|
||||
testWidgets('expand/collapse hidden groups', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
|
||||
final collapseFinder = find.byFlowySvg(FlowySvgs.pull_left_outlined_s);
|
||||
final expandFinder = find.byFlowySvg(FlowySvgs.hamburger_s_s);
|
||||
@@ -46,7 +46,7 @@ void main() {
|
||||
testWidgets('hide first group, and show it again', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
|
||||
// Tap the options of the first group
|
||||
final optionsFinder = find
|
||||
@@ -82,7 +82,7 @@ void main() {
|
||||
testWidgets('delete a group', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
|
||||
expect(tester.widgetList(find.byType(BoardColumnHeader)).length, 4);
|
||||
|
||||
+12
-12
@@ -1,14 +1,14 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/card/card.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
import 'package:appflowy/plugins/database/widgets/card/card.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_board/appflowy_board.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
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();
|
||||
@@ -18,31 +18,31 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
const name = 'Card 1';
|
||||
final card1 = find.findTextInFlowyText(name);
|
||||
final card1 = find.text(name);
|
||||
await tester.hoverOnWidget(
|
||||
card1,
|
||||
onHover: () async {
|
||||
final moreOption = find.byType(CardMoreOption);
|
||||
final moreOption = find.byType(MoreCardOptionsAccessory);
|
||||
await tester.tapButton(moreOption);
|
||||
},
|
||||
);
|
||||
await tester.tapButtonWithName(LocaleKeys.button_delete.tr());
|
||||
expect(find.findTextInFlowyText(name), findsNothing);
|
||||
expect(find.text(name), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('duplicate item in ToDo card', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
const name = 'Card 1';
|
||||
final card1 = find.findTextInFlowyText(name);
|
||||
final card1 = find.text(name);
|
||||
await tester.hoverOnWidget(
|
||||
card1,
|
||||
onHover: () async {
|
||||
final moreOption = find.byType(CardMoreOption);
|
||||
final moreOption = find.byType(MoreCardOptionsAccessory);
|
||||
await tester.tapButton(moreOption);
|
||||
},
|
||||
);
|
||||
@@ -53,7 +53,7 @@ void main() {
|
||||
testWidgets('add new group', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Board);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
|
||||
|
||||
// assert number of groups
|
||||
tester.assertNumberOfGroups(4);
|
||||
File renamed without changes.
+60
-9
@@ -1,10 +1,12 @@
|
||||
import 'package:appflowy/plugins/database/calendar/presentation/calendar_event_editor.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pbenum.dart';
|
||||
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();
|
||||
@@ -14,7 +16,9 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Calendar);
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Calendar,
|
||||
);
|
||||
|
||||
// open setting
|
||||
await tester.tapDatabaseSettingButton();
|
||||
@@ -36,7 +40,7 @@ void main() {
|
||||
|
||||
// Create calendar view
|
||||
const name = 'calendar';
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: name,
|
||||
layout: ViewLayoutPB.Calendar,
|
||||
);
|
||||
@@ -68,7 +72,9 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create the calendar view
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Calendar);
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Calendar,
|
||||
);
|
||||
|
||||
// Scroll until today's date cell is visible
|
||||
await tester.scrollToToday();
|
||||
@@ -76,7 +82,7 @@ void main() {
|
||||
// Hover over today's calendar cell
|
||||
await tester.hoverOnTodayCalendarCell(
|
||||
// Tap on create new event button
|
||||
onHover: () async => await tester.tapAddCalendarEventButton(),
|
||||
onHover: tester.tapAddCalendarEventButton,
|
||||
);
|
||||
|
||||
// Make sure that the event editor popup is shown
|
||||
@@ -143,16 +149,61 @@ void main() {
|
||||
tester.assertNumberOfEventsOnSpecificDay(1, DateTime.now());
|
||||
});
|
||||
|
||||
testWidgets('create and duplicate calendar event', (tester) async {
|
||||
const customTitle = "EventTitleCustom";
|
||||
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create the calendar view
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Calendar,
|
||||
);
|
||||
|
||||
// Scroll until today's date cell is visible
|
||||
await tester.scrollToToday();
|
||||
|
||||
// Hover over today's calendar cell
|
||||
await tester.hoverOnTodayCalendarCell(
|
||||
// Tap on create new event button
|
||||
onHover: () async => tester.tapAddCalendarEventButton(),
|
||||
);
|
||||
|
||||
// Make sure that the event editor popup is shown
|
||||
tester.assertEventEditorOpen();
|
||||
|
||||
tester.assertNumberOfEventsInCalendar(1);
|
||||
|
||||
// Change the title of the event
|
||||
await tester.editEventTitle(customTitle);
|
||||
|
||||
// Duplicate event
|
||||
final duplicateBtnFinder = find
|
||||
.descendant(
|
||||
of: find.byType(CalendarEventEditor),
|
||||
matching: find.byType(
|
||||
FlowyIconButton,
|
||||
),
|
||||
)
|
||||
.first;
|
||||
await tester.tap(duplicateBtnFinder);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
tester.assertNumberOfEventsInCalendar(2, title: customTitle);
|
||||
});
|
||||
|
||||
testWidgets('rescheduling events', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create the calendar view
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Calendar);
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Calendar,
|
||||
);
|
||||
|
||||
// Create a new event on the first of this month
|
||||
final today = DateTime.now();
|
||||
final firstOfThisMonth = DateTime(today.year, today.month, 1);
|
||||
final firstOfThisMonth = DateTime(today.year, today.month);
|
||||
await tester.doubleClickCalendarCell(firstOfThisMonth);
|
||||
await tester.dismissEventEditor();
|
||||
|
||||
+31
-26
@@ -1,11 +1,11 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
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();
|
||||
@@ -15,7 +15,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
await tester.editCell(
|
||||
rowIndex: 0,
|
||||
@@ -23,7 +23,7 @@ void main() {
|
||||
input: 'hello world',
|
||||
);
|
||||
|
||||
await tester.assertCellContent(
|
||||
tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.RichText,
|
||||
content: 'hello world',
|
||||
@@ -37,7 +37,7 @@ void main() {
|
||||
testWidgets('multiple text cells', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'my grid',
|
||||
layout: ViewLayoutPB.Grid,
|
||||
);
|
||||
@@ -56,14 +56,13 @@ void main() {
|
||||
cellIndex: 1,
|
||||
);
|
||||
|
||||
await tester.assertCellContent(
|
||||
tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.RichText,
|
||||
content: 'hello',
|
||||
cellIndex: 0,
|
||||
);
|
||||
|
||||
await tester.assertCellContent(
|
||||
tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.RichText,
|
||||
content: 'world',
|
||||
@@ -77,7 +76,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
const fieldType = FieldType.Number;
|
||||
|
||||
@@ -96,7 +95,7 @@ void main() {
|
||||
input: '0.2',
|
||||
);
|
||||
// -1 -> -1
|
||||
await tester.assertCellContent(
|
||||
tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: fieldType,
|
||||
content: '-1',
|
||||
@@ -109,7 +108,7 @@ void main() {
|
||||
input: '.1',
|
||||
);
|
||||
// 0.2 -> 0.2
|
||||
await tester.assertCellContent(
|
||||
tester.assertCellContent(
|
||||
rowIndex: 1,
|
||||
fieldType: fieldType,
|
||||
content: '0.2',
|
||||
@@ -122,7 +121,7 @@ void main() {
|
||||
input: '',
|
||||
);
|
||||
// .1 -> 0.1
|
||||
await tester.assertCellContent(
|
||||
tester.assertCellContent(
|
||||
rowIndex: 2,
|
||||
fieldType: fieldType,
|
||||
content: '0.1',
|
||||
@@ -135,7 +134,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
await tester.assertCheckboxCell(rowIndex: 0, isSelected: false);
|
||||
await tester.tapCheckboxCellInGrid(rowIndex: 0);
|
||||
@@ -153,7 +152,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
const fieldType = FieldType.CreatedTime;
|
||||
// Create a create time field
|
||||
@@ -171,7 +170,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
const fieldType = FieldType.LastEditedTime;
|
||||
// Create a last time field
|
||||
@@ -189,7 +188,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
const fieldType = FieldType.DateTime;
|
||||
await tester.createField(fieldType, fieldType.name);
|
||||
@@ -216,13 +215,13 @@ void main() {
|
||||
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
await tester.assertDateCellInGrid(
|
||||
tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.DateTime,
|
||||
content: DateFormat('MMM dd, y').format(today),
|
||||
);
|
||||
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Toggle include time
|
||||
final now = DateTime.now();
|
||||
@@ -230,8 +229,9 @@ void main() {
|
||||
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
await tester.assertDateCellInGrid(
|
||||
tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.DateTime,
|
||||
content: DateFormat('MMM dd, y HH:mm').format(now),
|
||||
);
|
||||
|
||||
@@ -239,12 +239,14 @@ void main() {
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Change date format
|
||||
await tester.tapChangeDateTimeFormatButton();
|
||||
await tester.changeDateFormat();
|
||||
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
await tester.assertDateCellInGrid(
|
||||
tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.DateTime,
|
||||
content: DateFormat('dd/MM/y HH:mm').format(now),
|
||||
);
|
||||
|
||||
@@ -252,12 +254,14 @@ void main() {
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Change time format
|
||||
await tester.tapChangeDateTimeFormatButton();
|
||||
await tester.changeTimeFormat();
|
||||
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
await tester.assertDateCellInGrid(
|
||||
tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.DateTime,
|
||||
content: DateFormat('dd/MM/y hh:mm a').format(now),
|
||||
);
|
||||
|
||||
@@ -267,8 +271,9 @@ void main() {
|
||||
// Clear the date and time
|
||||
await tester.clearDate();
|
||||
|
||||
await tester.assertDateCellInGrid(
|
||||
tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.DateTime,
|
||||
content: '',
|
||||
);
|
||||
|
||||
@@ -282,7 +287,7 @@ void main() {
|
||||
const fieldType = FieldType.SingleSelect;
|
||||
|
||||
// When create a grid, it will create a single select field by default
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Tap the cell to invoke the selection option editor
|
||||
await tester.tapSelectOptionCellInGrid(rowIndex: 0, fieldType: fieldType);
|
||||
@@ -358,7 +363,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
const fieldType = FieldType.MultiSelect;
|
||||
await tester.createField(fieldType, fieldType.name);
|
||||
@@ -441,7 +446,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
const fieldType = FieldType.Checklist;
|
||||
await tester.createField(fieldType, fieldType.name);
|
||||
+10
-10
@@ -1,11 +1,11 @@
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/grid_page.dart';
|
||||
import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pbenum.dart';
|
||||
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();
|
||||
@@ -15,7 +15,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
await tester.tapCreateLinkedDatabaseViewButton(DatabaseLayoutPB.Grid);
|
||||
|
||||
// create a field
|
||||
@@ -27,29 +27,29 @@ void main() {
|
||||
// hide the field
|
||||
await tester.tapGridFieldWithName('New field 1');
|
||||
await tester.tapHidePropertyButton();
|
||||
await tester.noFieldWithName('New field 1');
|
||||
tester.noFieldWithName('New field 1');
|
||||
|
||||
// go back to inline database view, expect field to be shown
|
||||
await tester.tapTabBarLinkedViewByViewName('Untitled');
|
||||
await tester.findFieldWithName('New field 1');
|
||||
tester.findFieldWithName('New field 1');
|
||||
|
||||
// go back to linked database view, expect field to be hidden
|
||||
await tester.tapTabBarLinkedViewByViewName('Grid');
|
||||
await tester.noFieldWithName('New field 1');
|
||||
tester.noFieldWithName('New field 1');
|
||||
|
||||
// use the settings button to show the field
|
||||
await tester.tapDatabaseSettingButton();
|
||||
await tester.tapViewPropertiesButton();
|
||||
await tester.tapViewTogglePropertyVisibilityButtonByName('New field 1');
|
||||
await tester.dismissFieldEditor();
|
||||
await tester.findFieldWithName('New field 1');
|
||||
tester.findFieldWithName('New field 1');
|
||||
|
||||
// open first row in popup then hide the field
|
||||
await tester.openFirstRowDetailPage();
|
||||
await tester.tapGridFieldWithNameInRowDetailPage('New field 1');
|
||||
await tester.tapHidePropertyButtonInFieldEditor();
|
||||
await tester.dismissRowDetailPage();
|
||||
await tester.noFieldWithName('New field 1');
|
||||
tester.noFieldWithName('New field 1');
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart';
|
||||
import 'package:appflowy/plugins/database/widgets/field/type_option_editor/select/select_option.dart';
|
||||
import 'package:appflowy/util/field_type_extension.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../shared/database_test_op.dart';
|
||||
import '../../shared/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('grid field editor:', () {
|
||||
testWidgets('rename existing field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Invoke the field editor
|
||||
await tester.tapGridFieldWithName('Name');
|
||||
await tester.tapEditFieldButton();
|
||||
|
||||
await tester.renameField('hello world');
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
await tester.tapGridFieldWithName('hello world');
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('update field type of existing field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Invoke the field editor
|
||||
await tester.changeFieldTypeOfFieldWithName('Type', FieldType.Checkbox);
|
||||
|
||||
await tester.assertFieldTypeWithFieldName(
|
||||
'Type',
|
||||
FieldType.Checkbox,
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('create a field and rename it', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new grid
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// create a field
|
||||
await tester.createField(FieldType.Checklist, 'checklist');
|
||||
|
||||
// check the field is created successfully
|
||||
tester.findFieldWithName('checklist');
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('delete field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// create a field
|
||||
await tester.createField(FieldType.Checkbox, 'New field 1');
|
||||
|
||||
// Delete the field
|
||||
await tester.tapGridFieldWithName('New field 1');
|
||||
await tester.tapDeletePropertyButton();
|
||||
|
||||
// confirm delete
|
||||
await tester.tapDialogOkButton();
|
||||
|
||||
tester.noFieldWithName('New field 1');
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('duplicate field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// create a field
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
await tester.tapNewPropertyButton();
|
||||
await tester.renameField('New field 1');
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
// duplicate the field
|
||||
await tester.tapGridFieldWithName('New field 1');
|
||||
await tester.tapDuplicatePropertyButton();
|
||||
|
||||
tester.findFieldWithName('New field 1 (copy)');
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('insert field on either side of a field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
|
||||
// insert new field to the right
|
||||
await tester.tapGridFieldWithName('Type');
|
||||
await tester.tapInsertFieldButton(left: false, name: 'Right');
|
||||
await tester.dismissFieldEditor();
|
||||
tester.findFieldWithName('Right');
|
||||
|
||||
// insert new field to the right
|
||||
await tester.tapGridFieldWithName('Type');
|
||||
await tester.tapInsertFieldButton(left: true, name: "Left");
|
||||
await tester.dismissFieldEditor();
|
||||
tester.findFieldWithName('Left');
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('create checklist field', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
await tester.tapNewPropertyButton();
|
||||
|
||||
// Open the type option menu
|
||||
await tester.tapSwitchFieldTypeButton();
|
||||
|
||||
await tester.selectFieldType(FieldType.Checklist);
|
||||
|
||||
// After update the field type, the cells should be updated
|
||||
await tester.findCellByFieldType(FieldType.Checklist);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('create list of fields', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
for (final fieldType in [
|
||||
FieldType.Checklist,
|
||||
FieldType.DateTime,
|
||||
FieldType.Number,
|
||||
FieldType.URL,
|
||||
FieldType.MultiSelect,
|
||||
FieldType.LastEditedTime,
|
||||
FieldType.CreatedTime,
|
||||
FieldType.Checkbox,
|
||||
]) {
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
await tester.tapNewPropertyButton();
|
||||
await tester.renameField(fieldType.name);
|
||||
|
||||
// Open the type option menu
|
||||
await tester.tapSwitchFieldTypeButton();
|
||||
|
||||
await tester.selectFieldType(fieldType);
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
// After update the field type, the cells should be updated
|
||||
await tester.findCellByFieldType(fieldType);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('field types with empty type option editor', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
for (final fieldType in [
|
||||
FieldType.RichText,
|
||||
FieldType.Checkbox,
|
||||
FieldType.Checklist,
|
||||
FieldType.URL,
|
||||
]) {
|
||||
// create the field
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
await tester.tapNewPropertyButton();
|
||||
await tester.renameField(fieldType.i18n);
|
||||
|
||||
// change field type
|
||||
await tester.tapSwitchFieldTypeButton();
|
||||
await tester.selectFieldType(fieldType);
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
// open the field editor
|
||||
await tester.tapGridFieldWithName(fieldType.i18n);
|
||||
await tester.tapEditFieldButton();
|
||||
|
||||
// check type option editor is empty
|
||||
tester.expectEmptyTypeOptionEditor();
|
||||
await tester.dismissFieldEditor();
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('number field type option', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
|
||||
// create a number field
|
||||
await tester.tapNewPropertyButton();
|
||||
await tester.renameField("Number");
|
||||
await tester.tapSwitchFieldTypeButton();
|
||||
await tester.selectFieldType(FieldType.Number);
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
// enter some data into the first number cell
|
||||
await tester.editCell(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.Number,
|
||||
input: '123',
|
||||
);
|
||||
// edit the next cell to force the previous cell at row 0 to lose focus
|
||||
await tester.editCell(
|
||||
rowIndex: 1,
|
||||
fieldType: FieldType.Number,
|
||||
input: '0.2',
|
||||
);
|
||||
tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.Number,
|
||||
content: '123',
|
||||
);
|
||||
|
||||
// open editor and change number format
|
||||
await tester.tapGridFieldWithName('Number');
|
||||
await tester.tapEditFieldButton();
|
||||
await tester.changeNumberFieldFormat();
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
// assert number format has been changed
|
||||
tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.Number,
|
||||
content: '\$123',
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('add option', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Grid,
|
||||
);
|
||||
|
||||
// invoke the field editor
|
||||
await tester.tapGridFieldWithName('Type');
|
||||
await tester.tapEditFieldButton();
|
||||
|
||||
// tap 'add option' button
|
||||
await tester.tapAddSelectOptionButton();
|
||||
const text = 'Hello AppFlowy';
|
||||
final inputField = find.descendant(
|
||||
of: find.byType(CreateOptionTextField),
|
||||
matching: find.byType(TextField),
|
||||
);
|
||||
await tester.enterText(inputField, text);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.testTextInput.receiveAction(TextInputAction.done);
|
||||
await tester.pumpAndSettle(const Duration(milliseconds: 500));
|
||||
|
||||
// check the result
|
||||
tester.expectToSeeText(text);
|
||||
});
|
||||
|
||||
testWidgets('date time field type options', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
await tester.scrollToRight(find.byType(GridPage));
|
||||
|
||||
// create a date field
|
||||
await tester.tapNewPropertyButton();
|
||||
await tester.renameField(FieldType.DateTime.i18n);
|
||||
await tester.tapSwitchFieldTypeButton();
|
||||
await tester.selectFieldType(FieldType.DateTime);
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
// edit the first date cell
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: FieldType.DateTime);
|
||||
await tester.toggleIncludeTime();
|
||||
final now = DateTime.now();
|
||||
await tester.selectDay(content: now.day);
|
||||
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.DateTime,
|
||||
content: DateFormat('MMM dd, y HH:mm').format(now),
|
||||
);
|
||||
|
||||
// open editor and change date & time format
|
||||
await tester.tapGridFieldWithName(FieldType.DateTime.i18n);
|
||||
await tester.tapEditFieldButton();
|
||||
await tester.changeDateFormat();
|
||||
await tester.changeTimeFormat();
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
// assert date format has been changed
|
||||
tester.assertCellContent(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.DateTime,
|
||||
content: DateFormat('dd/MM/y hh:mm a').format(now),
|
||||
);
|
||||
});
|
||||
|
||||
// Disable this test because it fails on CI randomly
|
||||
// testWidgets('last modified and created at field type options',
|
||||
// (tester) async {
|
||||
// await tester.initializeAppFlowy();
|
||||
// await tester.tapGoButton();
|
||||
|
||||
// await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
// final created = DateTime.now();
|
||||
|
||||
// // create a created at field
|
||||
// await tester.tapNewPropertyButton();
|
||||
// await tester.renameField(FieldType.CreatedTime.i18n);
|
||||
// await tester.tapSwitchFieldTypeButton();
|
||||
// await tester.selectFieldType(FieldType.CreatedTime);
|
||||
// await tester.dismissFieldEditor();
|
||||
|
||||
// // create a last modified field
|
||||
// await tester.tapNewPropertyButton();
|
||||
// await tester.renameField(FieldType.LastEditedTime.i18n);
|
||||
// await tester.tapSwitchFieldTypeButton();
|
||||
|
||||
// // get time just before modifying
|
||||
// final modified = DateTime.now();
|
||||
|
||||
// // create a last modified field (cont'd)
|
||||
// await tester.selectFieldType(FieldType.LastEditedTime);
|
||||
// await tester.dismissFieldEditor();
|
||||
|
||||
// tester.assertCellContent(
|
||||
// rowIndex: 0,
|
||||
// fieldType: FieldType.CreatedTime,
|
||||
// content: DateFormat('MMM dd, y HH:mm').format(created),
|
||||
// );
|
||||
// tester.assertCellContent(
|
||||
// rowIndex: 0,
|
||||
// fieldType: FieldType.LastEditedTime,
|
||||
// content: DateFormat('MMM dd, y HH:mm').format(modified),
|
||||
// );
|
||||
|
||||
// // open field editor and change date & time format
|
||||
// await tester.tapGridFieldWithName(FieldType.LastEditedTime.i18n);
|
||||
// await tester.tapEditFieldButton();
|
||||
// await tester.changeDateFormat();
|
||||
// await tester.changeTimeFormat();
|
||||
// await tester.dismissFieldEditor();
|
||||
|
||||
// // open field editor and change date & time format
|
||||
// await tester.tapGridFieldWithName(FieldType.CreatedTime.i18n);
|
||||
// await tester.tapEditFieldButton();
|
||||
// await tester.changeDateFormat();
|
||||
// await tester.changeTimeFormat();
|
||||
// await tester.dismissFieldEditor();
|
||||
|
||||
// // assert format has been changed
|
||||
// tester.assertCellContent(
|
||||
// rowIndex: 0,
|
||||
// fieldType: FieldType.CreatedTime,
|
||||
// content: DateFormat('dd/MM/y hh:mm a').format(created),
|
||||
// );
|
||||
// tester.assertCellContent(
|
||||
// rowIndex: 0,
|
||||
// fieldType: FieldType.LastEditedTime,
|
||||
// content: DateFormat('dd/MM/y hh:mm a').format(modified),
|
||||
// );
|
||||
// });
|
||||
});
|
||||
}
|
||||
+6
-6
@@ -1,15 +1,15 @@
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/filter/choicechip/checkbox.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/filter/choicechip/text.dart';
|
||||
import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/choicechip/checkbox.dart';
|
||||
import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/choicechip/text.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
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();
|
||||
|
||||
group('database filter', () {
|
||||
group('grid filter:', () {
|
||||
testWidgets('add text filter', (tester) async {
|
||||
await tester.openV020database();
|
||||
|
||||
@@ -103,8 +103,8 @@ void main() {
|
||||
// select the option 's4'
|
||||
await tester.tapOptionFilterWithName('s4');
|
||||
|
||||
// The row with 's4' or 's5' should be shown.
|
||||
await tester.assertNumberOfRowsInGridPage(2);
|
||||
// The row with 's4' should be shown.
|
||||
await tester.assertNumberOfRowsInGridPage(1);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
import 'package:appflowy/workspace/presentation/notifications/widgets/notification_item.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/date_picker/widgets/reminder_selector.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../../shared/database_test_op.dart';
|
||||
import '../../shared/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('reminder in database', () {
|
||||
testWidgets('add date field and add reminder', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Invoke the field editor
|
||||
await tester.tapGridFieldWithName('Type');
|
||||
await tester.tapEditFieldButton();
|
||||
|
||||
// Change to date type
|
||||
await tester.tapSwitchFieldTypeButton();
|
||||
await tester.selectFieldType(FieldType.DateTime);
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
// Open date picker
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: FieldType.DateTime);
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Select date
|
||||
final isToday = await tester.selectLastDateInPicker();
|
||||
|
||||
// Select "On day of event" reminder
|
||||
await tester.selectReminderOption(ReminderOption.onDayOfEvent);
|
||||
|
||||
// Expect "On day of event" to be displayed
|
||||
tester.expectSelectedReminder(ReminderOption.onDayOfEvent);
|
||||
|
||||
// Dismiss the cell/date editor
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
// Open date picker again
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: FieldType.DateTime);
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Expect "On day of event" to be displayed
|
||||
tester.expectSelectedReminder(ReminderOption.onDayOfEvent);
|
||||
|
||||
// Dismiss the cell/date editor
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
int tabIndex = 1;
|
||||
final now = DateTime.now();
|
||||
if (isToday && now.hour >= 9) {
|
||||
tabIndex = 0;
|
||||
}
|
||||
|
||||
// Open "Upcoming" in Notification hub
|
||||
await tester.openNotificationHub(tabIndex: tabIndex);
|
||||
|
||||
// Expect 1 notification
|
||||
tester.expectNotificationItems(1);
|
||||
});
|
||||
|
||||
testWidgets('navigate from reminder to open row', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Invoke the field editor
|
||||
await tester.tapGridFieldWithName('Type');
|
||||
await tester.tapEditFieldButton();
|
||||
|
||||
// Change to date type
|
||||
await tester.tapSwitchFieldTypeButton();
|
||||
await tester.selectFieldType(FieldType.DateTime);
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
// Open date picker
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: FieldType.DateTime);
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Select date
|
||||
final isToday = await tester.selectLastDateInPicker();
|
||||
|
||||
// Select "On day of event"-reminder
|
||||
await tester.selectReminderOption(ReminderOption.onDayOfEvent);
|
||||
|
||||
// Expect "On day of event" to be displayed
|
||||
tester.expectSelectedReminder(ReminderOption.onDayOfEvent);
|
||||
|
||||
// Dismiss the cell/date editor
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
// Open date picker again
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: FieldType.DateTime);
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Expect "On day of event" to be displayed
|
||||
tester.expectSelectedReminder(ReminderOption.onDayOfEvent);
|
||||
|
||||
// Dismiss the cell/date editor
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
// Create and Navigate to a new document
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
int tabIndex = 1;
|
||||
final now = DateTime.now();
|
||||
if (isToday && now.hour >= 9) {
|
||||
tabIndex = 0;
|
||||
}
|
||||
|
||||
// Open correct tab in Notification hub
|
||||
await tester.openNotificationHub(tabIndex: tabIndex);
|
||||
|
||||
// Expect 1 notification
|
||||
tester.expectNotificationItems(1);
|
||||
|
||||
// Tap on the notification
|
||||
await tester.tap(find.byType(NotificationItem));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Expect to see Row Editor Dialog
|
||||
tester.expectToSeeRowDetailsPageDialog();
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'toggle include time sets reminder option correctly',
|
||||
(tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
layout: ViewLayoutPB.Grid,
|
||||
);
|
||||
|
||||
// Invoke the field editor
|
||||
await tester.tapGridFieldWithName('Type');
|
||||
await tester.tapEditFieldButton();
|
||||
|
||||
// Change to date type
|
||||
await tester.tapSwitchFieldTypeButton();
|
||||
await tester.selectFieldType(FieldType.DateTime);
|
||||
await tester.dismissFieldEditor();
|
||||
|
||||
// Open date picker
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: FieldType.DateTime);
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Select date
|
||||
await tester.selectLastDateInPicker();
|
||||
|
||||
// Select "On day of event"-reminder
|
||||
await tester.selectReminderOption(ReminderOption.onDayOfEvent);
|
||||
|
||||
// Expect "On day of event" to be displayed
|
||||
tester.expectSelectedReminder(ReminderOption.onDayOfEvent);
|
||||
|
||||
// Dismiss the cell/date editor
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
// Open date picker again
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: FieldType.DateTime);
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Expect "On day of event" to be displayed
|
||||
tester.expectSelectedReminder(ReminderOption.onDayOfEvent);
|
||||
|
||||
// Toggle include time on
|
||||
await tester.toggleIncludeTime();
|
||||
|
||||
// Expect "At time of event" to be displayed
|
||||
tester.expectSelectedReminder(ReminderOption.atTimeOfEvent);
|
||||
|
||||
// Dismiss the cell/date editor
|
||||
await tester.dismissCellEditor();
|
||||
|
||||
// Open date picker again
|
||||
await tester.tapCellInGrid(rowIndex: 0, fieldType: FieldType.DateTime);
|
||||
await tester.findDateEditor(findsOneWidget);
|
||||
|
||||
// Expect "At time of event" to be displayed
|
||||
tester.expectSelectedReminder(ReminderOption.atTimeOfEvent);
|
||||
|
||||
// Select "One hour before"-reminder
|
||||
await tester.selectReminderOption(ReminderOption.oneHourBefore);
|
||||
|
||||
// Expect "One hour before" to be displayed
|
||||
tester.expectSelectedReminder(ReminderOption.oneHourBefore);
|
||||
|
||||
// Toggle include time off
|
||||
await tester.toggleIncludeTime();
|
||||
|
||||
// Expect "On day of event" to be displayed
|
||||
tester.expectSelectedReminder(ReminderOption.onDayOfEvent);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
+28
-39
@@ -1,40 +1,43 @@
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/row_banner.dart';
|
||||
import 'package:appflowy/plugins/database/widgets/row/row_banner.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
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();
|
||||
|
||||
group('grid', () {
|
||||
testWidgets('row details page opens', (tester) async {
|
||||
group('grid row detail page:', () {
|
||||
testWidgets('opens', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create a new grid
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Hover first row and then open the row page
|
||||
await tester.openFirstRowDetailPage();
|
||||
|
||||
// Make sure that the row page is opened
|
||||
tester.assertRowDetailPageOpened();
|
||||
|
||||
// Each row detail page should have a document
|
||||
await tester.assertDocumentExistInRowDetailPage();
|
||||
});
|
||||
|
||||
testWidgets('insert emoji in the row detail page', (tester) async {
|
||||
testWidgets('add emoji', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create a new grid
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Hover first row and then open the row page
|
||||
await tester.openFirstRowDetailPage();
|
||||
@@ -48,12 +51,12 @@ void main() {
|
||||
await tester.tapButton(find.byType(EmojiButton));
|
||||
});
|
||||
|
||||
testWidgets('update emoji in the row detail page', (tester) async {
|
||||
testWidgets('update emoji', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create a new grid
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Hover first row and then open the row page
|
||||
await tester.openFirstRowDetailPage();
|
||||
@@ -75,12 +78,12 @@ void main() {
|
||||
expect(emojiText, findsNWidgets(2));
|
||||
});
|
||||
|
||||
testWidgets('remove emoji in the row detail page', (tester) async {
|
||||
testWidgets('remove emoji', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create a new grid
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Hover first row and then open the row page
|
||||
await tester.openFirstRowDetailPage();
|
||||
@@ -96,12 +99,12 @@ void main() {
|
||||
expect(emojiText, findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('create list of fields in row detail page', (tester) async {
|
||||
testWidgets('create list of fields', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create a new grid
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Hover first row and then open the row page
|
||||
await tester.openFirstRowDetailPage();
|
||||
@@ -120,7 +123,7 @@ void main() {
|
||||
await tester.renameField(fieldType.name);
|
||||
|
||||
// Open the type option menu
|
||||
await tester.tapTypeOptionButton();
|
||||
await tester.tapSwitchFieldTypeButton();
|
||||
|
||||
await tester.selectFieldType(fieldType);
|
||||
|
||||
@@ -135,7 +138,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create a new grid
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Hover first row and then open the row page
|
||||
await tester.openFirstRowDetailPage();
|
||||
@@ -168,7 +171,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create a new grid
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Hover first row and then open the row page
|
||||
await tester.openFirstRowDetailPage();
|
||||
@@ -211,27 +214,13 @@ void main() {
|
||||
tester.assertToggleShowHiddenFieldsVisibility(false);
|
||||
});
|
||||
|
||||
testWidgets('check document exists in row detail page', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create a new grid
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Hover first row and then open the row page
|
||||
await tester.openFirstRowDetailPage();
|
||||
|
||||
// Each row detail page should have a document
|
||||
await tester.assertDocumentExistInRowDetailPage();
|
||||
});
|
||||
|
||||
testWidgets('update the contents of the document and re-open it',
|
||||
(tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create a new grid
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Hover first row and then open the row page
|
||||
await tester.openFirstRowDetailPage();
|
||||
@@ -271,7 +260,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create a new grid
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Hover first row and then open the row page
|
||||
await tester.openFirstRowDetailPage();
|
||||
@@ -305,12 +294,12 @@ void main() {
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('delete row in row detail page', (tester) async {
|
||||
testWidgets('delete row', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create a new grid
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Hover first row and then open the row page
|
||||
await tester.openFirstRowDetailPage();
|
||||
@@ -322,12 +311,12 @@ void main() {
|
||||
await tester.assertNumberOfRowsInGridPage(2);
|
||||
});
|
||||
|
||||
testWidgets('duplicate row in row detail page', (tester) async {
|
||||
testWidgets('duplicate row', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// Create a new grid
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Hover first row and then open the row page
|
||||
await tester.openFirstRowDetailPage();
|
||||
@@ -0,0 +1,65 @@
|
||||
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 '../../shared/database_test_op.dart';
|
||||
import '../../shared/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('grid', () {
|
||||
testWidgets('create row of the grid', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
await tester.tapCreateRowButtonInGrid();
|
||||
|
||||
// 3 initial rows + 1 created
|
||||
await tester.assertNumberOfRowsInGridPage(4);
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('create row from row menu of the grid', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
await tester.hoverOnFirstRowOfGrid();
|
||||
|
||||
await tester.tapCreateRowButtonInRowMenuOfGrid();
|
||||
|
||||
// 3 initial rows + 1 created
|
||||
await tester.assertNumberOfRowsInGridPage(4);
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('delete row of the grid', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
await tester.hoverOnFirstRowOfGrid();
|
||||
|
||||
// Open the row menu and then click the delete
|
||||
await tester.tapRowMenuButtonInGrid();
|
||||
await tester.tapDeleteOnRowMenu();
|
||||
|
||||
// 3 initial rows - 1 deleted
|
||||
await tester.assertNumberOfRowsInGridPage(2);
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('check number of row indicator in the initial grid',
|
||||
(tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
});
|
||||
}
|
||||
+5
-5
@@ -1,10 +1,10 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
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();
|
||||
@@ -14,7 +14,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// open setting
|
||||
await tester.tapDatabaseSettingButton();
|
||||
@@ -31,7 +31,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// open setting
|
||||
await tester.tapDatabaseSettingButton();
|
||||
+7
-6
@@ -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();
|
||||
@@ -16,7 +16,7 @@ void main() {
|
||||
// check the text cell
|
||||
final textCells = <String>['A', 'B', 'C', 'D', 'E', '', '', '', '', ''];
|
||||
for (final (index, content) in textCells.indexed) {
|
||||
await tester.assertCellContent(
|
||||
tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.RichText,
|
||||
content: content,
|
||||
@@ -57,7 +57,7 @@ void main() {
|
||||
'',
|
||||
];
|
||||
for (final (index, content) in numberCells.indexed) {
|
||||
await tester.assertCellContent(
|
||||
tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.Number,
|
||||
content: content,
|
||||
@@ -74,7 +74,7 @@ void main() {
|
||||
'',
|
||||
];
|
||||
for (final (index, content) in urlCells.indexed) {
|
||||
await tester.assertCellContent(
|
||||
tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.URL,
|
||||
content: content,
|
||||
@@ -135,7 +135,7 @@ void main() {
|
||||
null,
|
||||
];
|
||||
for (final (index, percent) in checklistCells.indexed) {
|
||||
await tester.assertChecklistCellInGrid(
|
||||
tester.assertChecklistCellInGrid(
|
||||
rowIndex: index,
|
||||
percent: percent,
|
||||
);
|
||||
@@ -155,8 +155,9 @@ void main() {
|
||||
'',
|
||||
];
|
||||
for (final (index, content) in dateCells.indexed) {
|
||||
await tester.assertDateCellInGrid(
|
||||
tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.DateTime,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../../shared/database_test_op.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('grid', () {
|
||||
testWidgets('add text sort', (tester) async {
|
||||
await tester.openV020database();
|
||||
// create a sort
|
||||
await tester.tapDatabaseSortButton();
|
||||
await tester.tapCreateSortByFieldType(FieldType.RichText, 'Name');
|
||||
|
||||
// check the text cell order
|
||||
final textCells = <String>[
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
];
|
||||
for (final (index, content) in textCells.indexed) {
|
||||
tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.RichText,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
|
||||
// open the sort menu and select order by descending
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.tapSortButtonByName('Name');
|
||||
await tester.tapSortByDescending();
|
||||
for (final (index, content) in <String>[
|
||||
'E',
|
||||
'D',
|
||||
'C',
|
||||
'B',
|
||||
'A',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
].indexed) {
|
||||
tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.RichText,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
|
||||
// delete all sorts
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.tapAllSortButton();
|
||||
|
||||
// check the text cell order
|
||||
for (final (index, content) in <String>[
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
].indexed) {
|
||||
tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.RichText,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('add checkbox sort', (tester) async {
|
||||
await tester.openV020database();
|
||||
// create a sort
|
||||
await tester.tapDatabaseSortButton();
|
||||
await tester.tapCreateSortByFieldType(FieldType.Checkbox, 'Done');
|
||||
|
||||
// check the checkbox cell order
|
||||
for (final (index, content) in <bool>[
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
].indexed) {
|
||||
await tester.assertCheckboxCell(
|
||||
rowIndex: index,
|
||||
isSelected: content,
|
||||
);
|
||||
}
|
||||
|
||||
// open the sort menu and select order by descending
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.tapSortButtonByName('Done');
|
||||
await tester.tapSortByDescending();
|
||||
for (final (index, content) in <bool>[
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
].indexed) {
|
||||
await tester.assertCheckboxCell(
|
||||
rowIndex: index,
|
||||
isSelected: content,
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('add number sort', (tester) async {
|
||||
await tester.openV020database();
|
||||
// create a sort
|
||||
await tester.tapDatabaseSortButton();
|
||||
await tester.tapCreateSortByFieldType(FieldType.Number, 'number');
|
||||
|
||||
// check the number cell order
|
||||
for (final (index, content) in <String>[
|
||||
'-2',
|
||||
'-1',
|
||||
'0.1',
|
||||
'0.2',
|
||||
'1',
|
||||
'2',
|
||||
'10',
|
||||
'11',
|
||||
'12',
|
||||
'',
|
||||
].indexed) {
|
||||
tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.Number,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
|
||||
// open the sort menu and select order by descending
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.tapSortButtonByName('number');
|
||||
await tester.tapSortByDescending();
|
||||
for (final (index, content) in <String>[
|
||||
'12',
|
||||
'11',
|
||||
'10',
|
||||
'2',
|
||||
'1',
|
||||
'0.2',
|
||||
'0.1',
|
||||
'-1',
|
||||
'-2',
|
||||
'',
|
||||
].indexed) {
|
||||
tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.Number,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('add checkbox and number sort', (tester) async {
|
||||
await tester.openV020database();
|
||||
// create a sort
|
||||
await tester.tapDatabaseSortButton();
|
||||
await tester.tapCreateSortByFieldType(FieldType.Checkbox, 'Done');
|
||||
|
||||
// open the sort menu and sort checkbox by descending
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.tapSortButtonByName('Done');
|
||||
await tester.tapSortByDescending();
|
||||
for (final (index, content) in <bool>[
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
].indexed) {
|
||||
await tester.assertCheckboxCell(
|
||||
rowIndex: index,
|
||||
isSelected: content,
|
||||
);
|
||||
}
|
||||
|
||||
// add another sort, this time by number descending
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.tapCreateSortByFieldTypeInSortMenu(
|
||||
FieldType.Number,
|
||||
'number',
|
||||
);
|
||||
await tester.tapSortButtonByName('number');
|
||||
await tester.tapSortByDescending();
|
||||
|
||||
// check checkbox cell order
|
||||
for (final (index, content) in <bool>[
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
].indexed) {
|
||||
await tester.assertCheckboxCell(
|
||||
rowIndex: index,
|
||||
isSelected: content,
|
||||
);
|
||||
}
|
||||
|
||||
// check number cell order
|
||||
for (final (index, content) in <String>[
|
||||
'1',
|
||||
'0.2',
|
||||
'0.1',
|
||||
'-1',
|
||||
'-2',
|
||||
'12',
|
||||
'11',
|
||||
'10',
|
||||
'2',
|
||||
'',
|
||||
].indexed) {
|
||||
tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.Number,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('reorder sort', (tester) async {
|
||||
await tester.openV020database();
|
||||
// create a sort
|
||||
await tester.tapDatabaseSortButton();
|
||||
await tester.tapCreateSortByFieldType(FieldType.Checkbox, 'Done');
|
||||
|
||||
// open the sort menu and sort checkbox by descending
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.tapSortButtonByName('Done');
|
||||
await tester.tapSortByDescending();
|
||||
|
||||
// add another sort, this time by number descending
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.tapCreateSortByFieldTypeInSortMenu(
|
||||
FieldType.Number,
|
||||
'number',
|
||||
);
|
||||
await tester.tapSortButtonByName('number');
|
||||
await tester.tapSortByDescending();
|
||||
|
||||
// check checkbox cell order
|
||||
for (final (index, content) in <bool>[
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
].indexed) {
|
||||
await tester.assertCheckboxCell(
|
||||
rowIndex: index,
|
||||
isSelected: content,
|
||||
);
|
||||
}
|
||||
|
||||
// check number cell order
|
||||
for (final (index, content) in <String>[
|
||||
'1',
|
||||
'0.2',
|
||||
'0.1',
|
||||
'-1',
|
||||
'-2',
|
||||
'12',
|
||||
'11',
|
||||
'10',
|
||||
'2',
|
||||
'',
|
||||
].indexed) {
|
||||
tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.Number,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
|
||||
// reorder sort
|
||||
await tester.tapSortMenuInSettingBar();
|
||||
await tester.reorderSort(
|
||||
(FieldType.Number, 'number'),
|
||||
(FieldType.Checkbox, 'Done'),
|
||||
);
|
||||
|
||||
// check checkbox cell order
|
||||
for (final (index, content) in <bool>[
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
].indexed) {
|
||||
await tester.assertCheckboxCell(
|
||||
rowIndex: index,
|
||||
isSelected: content,
|
||||
);
|
||||
}
|
||||
|
||||
// check the number cell order
|
||||
for (final (index, content) in <String>[
|
||||
'12',
|
||||
'11',
|
||||
'10',
|
||||
'2',
|
||||
'1',
|
||||
'0.2',
|
||||
'0.1',
|
||||
'-1',
|
||||
'-2',
|
||||
'',
|
||||
].indexed) {
|
||||
tester.assertCellContent(
|
||||
rowIndex: index,
|
||||
fieldType: FieldType.Number,
|
||||
content: content,
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/setting_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
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();
|
||||
@@ -14,7 +14,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Create board view
|
||||
await tester.tapCreateLinkedDatabaseViewButton(DatabaseLayoutPB.Board);
|
||||
@@ -35,7 +35,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Create board view
|
||||
await tester.tapCreateLinkedDatabaseViewButton(DatabaseLayoutPB.Board);
|
||||
@@ -60,7 +60,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName(layout: ViewLayoutPB.Grid);
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Create board view
|
||||
await tester.tapCreateLinkedDatabaseViewButton(DatabaseLayoutPB.Board);
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
||||
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 '../../shared/keyboard.dart';
|
||||
import '../../shared/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('document alignment', () {
|
||||
testWidgets('edit alignment in toolbar', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
final selection = Selection.single(
|
||||
path: [0],
|
||||
startOffset: 0,
|
||||
endOffset: 1,
|
||||
);
|
||||
// click the first line of the readme
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
await tester.editor.updateSelection(selection);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// click the align center
|
||||
await tester.tapButtonWithFlowySvgData(FlowySvgs.toolbar_align_left_s);
|
||||
await tester.tapButtonWithFlowySvgData(FlowySvgs.toolbar_align_center_s);
|
||||
|
||||
// expect to see the align center
|
||||
final editorState = tester.editor.getCurrentEditorState();
|
||||
final first = editorState.getNodeAtPath([0])!;
|
||||
expect(first.attributes[blockComponentAlign], 'center');
|
||||
|
||||
// click the align right
|
||||
await tester.tapButtonWithFlowySvgData(FlowySvgs.toolbar_align_center_s);
|
||||
await tester.tapButtonWithFlowySvgData(FlowySvgs.toolbar_align_right_s);
|
||||
expect(first.attributes[blockComponentAlign], 'right');
|
||||
|
||||
// click the align left
|
||||
await tester.tapButtonWithFlowySvgData(FlowySvgs.toolbar_align_right_s);
|
||||
await tester.tapButtonWithFlowySvgData(FlowySvgs.toolbar_align_left_s);
|
||||
expect(first.attributes[blockComponentAlign], 'left');
|
||||
});
|
||||
|
||||
testWidgets('edit alignment using shortcut', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// click the first line of the readme
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final editorState = tester.editor.getCurrentEditorState();
|
||||
final first = editorState.getNodeAtPath([0])!;
|
||||
|
||||
// expect to see text aligned to the right
|
||||
await FlowyTestKeyboard.simulateKeyDownEvent(
|
||||
[
|
||||
LogicalKeyboardKey.control,
|
||||
LogicalKeyboardKey.shift,
|
||||
LogicalKeyboardKey.keyR,
|
||||
],
|
||||
tester: tester,
|
||||
);
|
||||
expect(first.attributes[blockComponentAlign], rightAlignmentKey);
|
||||
|
||||
// expect to see text aligned to the center
|
||||
await FlowyTestKeyboard.simulateKeyDownEvent(
|
||||
[
|
||||
LogicalKeyboardKey.control,
|
||||
LogicalKeyboardKey.shift,
|
||||
LogicalKeyboardKey.keyE,
|
||||
],
|
||||
tester: tester,
|
||||
);
|
||||
expect(first.attributes[blockComponentAlign], centerAlignmentKey);
|
||||
|
||||
// expect to see text aligned to the left
|
||||
await FlowyTestKeyboard.simulateKeyDownEvent(
|
||||
[
|
||||
LogicalKeyboardKey.control,
|
||||
LogicalKeyboardKey.shift,
|
||||
LogicalKeyboardKey.keyL,
|
||||
],
|
||||
tester: tester,
|
||||
);
|
||||
expect(first.attributes[blockComponentAlign], leftAlignmentKey);
|
||||
});
|
||||
});
|
||||
}
|
||||
+2
-2
@@ -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();
|
||||
@@ -18,7 +18,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithName();
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
|
||||
// mock the clipboard
|
||||
const lines = 3;
|
||||
+19
-2
@@ -3,11 +3,12 @@ import 'dart:io';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/clipboard_service.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
|
||||
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();
|
||||
@@ -276,6 +277,22 @@ void main() {
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'auto convert url to link preview block',
|
||||
(widgetTester) async {
|
||||
const url = 'https://appflowy.io';
|
||||
await widgetTester.pasteContent(
|
||||
plainText: url,
|
||||
(editorState) {
|
||||
expect(editorState.document.root.children.length, 2);
|
||||
final node = editorState.getNodeAtPath([0])!;
|
||||
expect(node.type, LinkPreviewBlockKeys.type);
|
||||
expect(node.attributes[LinkPreviewBlockKeys.url], url);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
extension on WidgetTester {
|
||||
@@ -290,7 +307,7 @@ extension on WidgetTester {
|
||||
await tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await createNewPageWithName();
|
||||
await createNewPageWithNameUnderParent();
|
||||
|
||||
await beforeTest?.call(editor.getCurrentEditorState());
|
||||
|
||||
+4
-4
@@ -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();
|
||||
@@ -17,7 +17,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithName();
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
|
||||
// expect to see a new document
|
||||
tester.expectToSeePageName(
|
||||
@@ -35,7 +35,7 @@ void main() {
|
||||
// delete the readme page
|
||||
await tester.hoverOnPageName(
|
||||
gettingStarted,
|
||||
onHover: () async => await tester.tapDeletePageButton(),
|
||||
onHover: () async => tester.tapDeletePageButton(),
|
||||
);
|
||||
|
||||
// the banner should show up and the readme page should be gone
|
||||
@@ -59,7 +59,7 @@ void main() {
|
||||
// delete the readme page
|
||||
await tester.hoverOnPageName(
|
||||
gettingStarted,
|
||||
onHover: () async => await tester.tapDeletePageButton(),
|
||||
onHover: () async => tester.tapDeletePageButton(),
|
||||
);
|
||||
|
||||
// the banner should show up and the readme page should be gone
|
||||
+5
-7
@@ -1,14 +1,13 @@
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/base/link_to_page_widget.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:appflowy_backend/protobuf/flowy-folder2/protobuf.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();
|
||||
@@ -30,7 +29,7 @@ void main() {
|
||||
|
||||
// Select result
|
||||
final optionFinder = find.descendant(
|
||||
of: find.byType(LinkToPageMenu),
|
||||
of: find.byType(InlineActionsHandler),
|
||||
matching: find.text(name),
|
||||
);
|
||||
|
||||
@@ -86,9 +85,8 @@ void main() {
|
||||
Future<String> createDocumentToReference(WidgetTester tester) async {
|
||||
final name = 'document_${uuid()}';
|
||||
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: name,
|
||||
layout: ViewLayoutPB.Document,
|
||||
openAfterCreated: false,
|
||||
);
|
||||
|
||||
+2
-2
@@ -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();
|
||||
@@ -32,7 +32,7 @@ void main() {
|
||||
await tester.tapAt(Offset.zero);
|
||||
await tester.tapAt(Offset.zero);
|
||||
|
||||
await tester.createNewPageWithName(name: 'test');
|
||||
await tester.createNewPageWithNameUnderParent(name: 'test');
|
||||
await tester.openPage(gettingStarted);
|
||||
|
||||
// check the status again
|
||||
File renamed without changes.
+6
-7
@@ -1,16 +1,15 @@
|
||||
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||
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();
|
||||
|
||||
group('text direction', () {
|
||||
testWidgets(
|
||||
'''no text direction items will be displayed in the default/LTR mode,and three text direction items will be displayed in the RTL mode.''',
|
||||
'''no text direction items will be displayed in the default/LTR mode, and three text direction items will be displayed when toggle is enabled.''',
|
||||
(tester) async {
|
||||
// combine the two tests into one to avoid the time-consuming process of initializing the app
|
||||
await tester.initializeAppFlowy();
|
||||
@@ -29,10 +28,10 @@ void main() {
|
||||
// because this icons are defined in the appflowy_editor package, we can't fetch the icons by SVG data. [textDirectionItems]
|
||||
final textDirectionIconNames = [
|
||||
'toolbar/text_direction_auto',
|
||||
'toolbar/text_direction_left',
|
||||
'toolbar/text_direction_right',
|
||||
'toolbar/text_direction_ltr',
|
||||
'toolbar/text_direction_rtl',
|
||||
];
|
||||
// no text direction items in default/LTR mode
|
||||
// no text direction items by default
|
||||
var button = find.byWidgetPredicate(
|
||||
(widget) =>
|
||||
widget is SVGIconItemWidget &&
|
||||
@@ -41,7 +40,7 @@ void main() {
|
||||
expect(button, findsNothing);
|
||||
|
||||
// switch to the RTL mode
|
||||
await tester.switchLayoutDirectionMode(LayoutDirection.rtlLayout);
|
||||
await tester.toggleEnableRTLToolbarItems();
|
||||
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
await tester.editor.updateSelection(selection);
|
||||
+3
-5
@@ -1,14 +1,14 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
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();
|
||||
@@ -43,8 +43,6 @@ void main() {
|
||||
await tester.editor.hoverOnCover();
|
||||
await tester.editor.tapOnChangeCover();
|
||||
await tester.editor.addNetworkImageCover(imageUrl);
|
||||
await tester.editor.switchNetworkImageCover(imageUrl);
|
||||
await tester.editor.dismissCoverPicker();
|
||||
tester.expectToSeeDocumentCover(CoverType.file);
|
||||
|
||||
// Remove the cover
|
||||
+15
-19
@@ -1,18 +1,18 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/board/presentation/board_page.dart';
|
||||
import 'package:appflowy/plugins/database_view/calendar/presentation/calendar_page.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/grid_page.dart';
|
||||
import 'package:appflowy/plugins/database_view/widgets/row/cells/text_cell/text_cell.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/base/link_to_page_widget.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-folder2/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.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 '../util/util.dart';
|
||||
import '../../shared/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
@@ -40,7 +40,7 @@ void main() {
|
||||
Position(path: [1]),
|
||||
),
|
||||
);
|
||||
final gridTextCell = find.byType(GridTextCell).first;
|
||||
final gridTextCell = find.byType(EditableTextCell).first;
|
||||
await tester.tapButton(gridTextCell);
|
||||
|
||||
expect(tester.editor.getCurrentEditorState().selection, isNull);
|
||||
@@ -84,7 +84,7 @@ void main() {
|
||||
|
||||
await createInlineDatabase(tester, ViewLayoutPB.Grid);
|
||||
|
||||
// validate the referenced grid is inserted
|
||||
// validate the inline grid is created
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(AppFlowyEditor),
|
||||
@@ -100,7 +100,7 @@ void main() {
|
||||
|
||||
await createInlineDatabase(tester, ViewLayoutPB.Board);
|
||||
|
||||
// validate the referenced grid is inserted
|
||||
// validate the inline board is created
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(AppFlowyEditor),
|
||||
@@ -116,7 +116,7 @@ void main() {
|
||||
|
||||
await createInlineDatabase(tester, ViewLayoutPB.Calendar);
|
||||
|
||||
// validate the referenced grid is inserted
|
||||
// validate the inline calendar is created
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(AppFlowyEditor),
|
||||
@@ -136,16 +136,14 @@ Future<void> insertReferenceDatabase(
|
||||
// create a new grid
|
||||
final id = uuid();
|
||||
final name = '${layout.name}_$id';
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: name,
|
||||
layout: layout,
|
||||
openAfterCreated: false,
|
||||
);
|
||||
// create a new document
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'insert_a_reference_${layout.name}',
|
||||
layout: ViewLayoutPB.Document,
|
||||
openAfterCreated: true,
|
||||
);
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@@ -155,7 +153,7 @@ Future<void> insertReferenceDatabase(
|
||||
layout.referencedMenuName,
|
||||
);
|
||||
|
||||
final linkToPageMenu = find.byType(LinkToPageMenu);
|
||||
final linkToPageMenu = find.byType(InlineActionsHandler);
|
||||
expect(linkToPageMenu, findsOneWidget);
|
||||
final referencedDatabase = find.descendant(
|
||||
of: linkToPageMenu,
|
||||
@@ -171,10 +169,8 @@ Future<void> createInlineDatabase(
|
||||
) async {
|
||||
// create a new document
|
||||
final documentName = 'insert_a_inline_${layout.name}';
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: documentName,
|
||||
layout: ViewLayoutPB.Document,
|
||||
openAfterCreated: true,
|
||||
);
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
+12
-10
@@ -1,13 +1,17 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy/core/config/kv.dart';
|
||||
import 'package:appflowy/core/config/kv_keys.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/image/custom_image_block_component.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/image/embed_image_url_widget.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/image/image_placeholder.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/image/resizeable_image.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/image/unsplash_image_widget.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/image/upload_image_menu.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/protobuf.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart' hide UploadImageMenu;
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart'
|
||||
hide UploadImageMenu, ResizableImage;
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -18,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();
|
||||
@@ -31,9 +35,8 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: LocaleKeys.document_plugins_image_addAnImage.tr(),
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
|
||||
// tap the first line of the document
|
||||
@@ -61,6 +64,7 @@ void main() {
|
||||
paths: [imagePath],
|
||||
);
|
||||
|
||||
await getIt<KeyValueStorage>().set(KVKeys.kCloudType, '0');
|
||||
await tester.tapButtonWithName(
|
||||
LocaleKeys.document_imageBlock_upload_placeholder.tr(),
|
||||
);
|
||||
@@ -79,9 +83,8 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: LocaleKeys.document_plugins_image_addAnImage.tr(),
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
|
||||
// tap the first line of the document
|
||||
@@ -133,9 +136,8 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: LocaleKeys.document_plugins_image_addAnImage.tr(),
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
|
||||
// tap the first line of the document
|
||||
+3
-6
@@ -1,6 +1,5 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/protobuf.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
@@ -8,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();
|
||||
@@ -20,9 +19,8 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'math equation',
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
|
||||
// tap the first line of the document
|
||||
@@ -66,9 +64,8 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'math equation',
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
|
||||
// tap the first line of the document
|
||||
File renamed without changes.
File renamed without changes.
+6
-7
@@ -1,11 +1,11 @@
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_page_block.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:flowy_infra/uuid.dart';
|
||||
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();
|
||||
@@ -65,7 +65,7 @@ void main() {
|
||||
const newName = 'RenameToNewPageName';
|
||||
await tester.hoverOnPageName(
|
||||
pageName,
|
||||
onHover: () async => await tester.renamePage(newName),
|
||||
onHover: () async => tester.renamePage(newName),
|
||||
);
|
||||
final finder = find.descendant(
|
||||
of: find.byType(MentionPageBlock),
|
||||
@@ -84,7 +84,7 @@ void main() {
|
||||
await tester.hoverOnPageName(
|
||||
pageName,
|
||||
layout: ViewLayoutPB.Grid,
|
||||
onHover: () async => await tester.tapDeletePageButton(),
|
||||
onHover: () async => tester.tapDeletePageButton(),
|
||||
);
|
||||
final finder = find.descendant(
|
||||
of: find.byType(MentionPageBlock),
|
||||
@@ -105,16 +105,15 @@ Future<String> insertInlinePage(
|
||||
// create a new grid
|
||||
final id = uuid();
|
||||
final name = '${layout.name}_$id';
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: name,
|
||||
layout: layout,
|
||||
openAfterCreated: false,
|
||||
);
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'insert_a_inline_page_${layout.name}',
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
|
||||
// tap the first line of the document
|
||||
+2
-5
@@ -1,4 +1,3 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/protobuf.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@@ -6,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();
|
||||
@@ -24,9 +23,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithName(
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/outline/outline_block_component.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../../shared/util.dart';
|
||||
|
||||
const String heading1 = "Heading 1";
|
||||
const String heading2 = "Heading 2";
|
||||
const String heading3 = "Heading 3";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('outline block test', () {
|
||||
testWidgets('insert an outline block', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'outline_test',
|
||||
);
|
||||
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
await insertOutlineInDocument(tester);
|
||||
|
||||
// validate the outline is inserted
|
||||
expect(find.byType(OutlineBlockWidget), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('insert an outline block and check if headings are visible',
|
||||
(tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'outline_test',
|
||||
);
|
||||
|
||||
await insertHeadingComponent(tester);
|
||||
/* Results in:
|
||||
* # Heading 1
|
||||
* ## Heading 2
|
||||
* ### Heading 3
|
||||
*/
|
||||
|
||||
await tester.editor.tapLineOfEditorAt(3);
|
||||
await insertOutlineInDocument(tester);
|
||||
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(OutlineBlockWidget),
|
||||
matching: find.text(heading1),
|
||||
),
|
||||
findsOneWidget,
|
||||
);
|
||||
|
||||
// Heading 2 is prefixed with a bullet
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(OutlineBlockWidget),
|
||||
matching: find.text(heading2),
|
||||
),
|
||||
findsOneWidget,
|
||||
);
|
||||
|
||||
// Heading 3 is prefixed with a dash
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(OutlineBlockWidget),
|
||||
matching: find.text(heading3),
|
||||
),
|
||||
findsOneWidget,
|
||||
);
|
||||
|
||||
// update the Heading 1 to Heading 1Hello world
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
await tester.ime.insertText('Hello world');
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(OutlineBlockWidget),
|
||||
matching: find.text('${heading1}Hello world'),
|
||||
),
|
||||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets("control the depth of outline block", (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: 'outline_test',
|
||||
);
|
||||
|
||||
await insertHeadingComponent(tester);
|
||||
/* Results in:
|
||||
* # Heading 1
|
||||
* ## Heading 2
|
||||
* ### Heading 3
|
||||
*/
|
||||
|
||||
await tester.editor.tapLineOfEditorAt(3);
|
||||
await insertOutlineInDocument(tester);
|
||||
|
||||
// expect to find only the `heading1` widget under the [OutlineBlockWidget]
|
||||
await hoverAndClickDepthOptionAction(tester, [3], 1);
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(OutlineBlockWidget),
|
||||
matching: find.text(heading2),
|
||||
),
|
||||
findsNothing,
|
||||
);
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(OutlineBlockWidget),
|
||||
matching: find.text(heading3),
|
||||
),
|
||||
findsNothing,
|
||||
);
|
||||
//////
|
||||
|
||||
/// expect to find only the 'heading1' and 'heading2' under the [OutlineBlockWidget]
|
||||
await hoverAndClickDepthOptionAction(tester, [3], 2);
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(OutlineBlockWidget),
|
||||
matching: find.text(heading3),
|
||||
),
|
||||
findsNothing,
|
||||
);
|
||||
//////
|
||||
|
||||
// expect to find all the headings under the [OutlineBlockWidget]
|
||||
await hoverAndClickDepthOptionAction(tester, [3], 3);
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(OutlineBlockWidget),
|
||||
matching: find.text(heading1),
|
||||
),
|
||||
findsOneWidget,
|
||||
);
|
||||
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(OutlineBlockWidget),
|
||||
matching: find.text(heading2),
|
||||
),
|
||||
findsOneWidget,
|
||||
);
|
||||
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(OutlineBlockWidget),
|
||||
matching: find.text(heading3),
|
||||
),
|
||||
findsOneWidget,
|
||||
);
|
||||
//////
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// Inserts an outline block in the document
|
||||
Future<void> insertOutlineInDocument(WidgetTester tester) async {
|
||||
// open the actions menu and insert the outline block
|
||||
await tester.editor.showSlashMenu();
|
||||
await tester.editor.tapSlashMenuItemWithName(
|
||||
LocaleKeys.document_selectionMenu_outline.tr(),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
Future<void> hoverAndClickDepthOptionAction(
|
||||
WidgetTester tester,
|
||||
List<int> path,
|
||||
int level,
|
||||
) async {
|
||||
await tester.editor.hoverAndClickOptionMenuButton([3]);
|
||||
await tester.tap(find.byType(AppFlowyPopover).hitTestable().last);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Find a total of 4 HoverButtons under the [BlockOptionButton],
|
||||
// in addition to 3 HoverButtons under the [DepthOptionAction] - (child of BlockOptionButton)
|
||||
await tester.tap(find.byType(HoverButton).hitTestable().at(3 + level));
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
Future<void> insertHeadingComponent(WidgetTester tester) async {
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
await tester.ime.insertText('# $heading1\n');
|
||||
await tester.ime.insertText('## $heading2\n');
|
||||
await tester.ime.insertText('### $heading3\n');
|
||||
}
|
||||
+9
-23
@@ -1,14 +1,13 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/protobuf.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
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();
|
||||
@@ -40,9 +39,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithName(
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@@ -86,9 +83,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithName(
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@@ -125,9 +120,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithName(
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@@ -162,9 +155,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithName(
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@@ -176,11 +167,8 @@ void main() {
|
||||
final toggleListIcon = find.byIcon(Icons.arrow_right);
|
||||
await tester.tapButton(toggleListIcon);
|
||||
|
||||
await tester.editor.updateSelection(
|
||||
Selection.collapsed(
|
||||
Position(path: [0], offset: 0),
|
||||
),
|
||||
);
|
||||
await tester.editor
|
||||
.updateSelection(Selection.collapsed(Position(path: [0])));
|
||||
await tester.ime.insertCharacter('\n');
|
||||
|
||||
final editorState = tester.editor.getCurrentEditorState();
|
||||
@@ -196,9 +184,7 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
// create a new document
|
||||
await tester.createNewPageWithName(
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
|
||||
// tap the first line of the document
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@@ -209,7 +195,7 @@ void main() {
|
||||
|
||||
await tester.editor.updateSelection(
|
||||
Selection.collapsed(
|
||||
Position(path: [0], offset: 0),
|
||||
Position(path: [0]),
|
||||
),
|
||||
);
|
||||
await tester.simulateKeyEvent(
|
||||
+4
-11
@@ -1,12 +1,11 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
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/util.dart';
|
||||
import '../../shared/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
@@ -18,10 +17,7 @@ void main() {
|
||||
|
||||
// create a new document called Sample
|
||||
const pageName = 'Sample';
|
||||
await tester.createNewPageWithName(
|
||||
name: pageName,
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent(name: pageName);
|
||||
|
||||
// focus on the editor
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@@ -75,10 +71,7 @@ void main() {
|
||||
|
||||
// create a new document called Sample
|
||||
const pageName = 'Sample';
|
||||
await tester.createNewPageWithName(
|
||||
name: pageName,
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
await tester.createNewPageWithNameUnderParent(name: pageName);
|
||||
|
||||
// focus on the editor
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
@@ -104,7 +97,7 @@ void main() {
|
||||
});
|
||||
}
|
||||
|
||||
const _sample = r'''
|
||||
const _sample = '''
|
||||
# Heading 1
|
||||
## Heading 2
|
||||
### Heading 3
|
||||
File renamed without changes.
@@ -0,0 +1,107 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pbenum.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../../shared/database_test_op.dart';
|
||||
import '../../shared/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('Grid Calculations', () {
|
||||
testWidgets('add calculation and update cell', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Change one Field to Number
|
||||
await tester.changeFieldTypeOfFieldWithName('Type', FieldType.Number);
|
||||
|
||||
expect(find.text('Calculate'), findsOneWidget);
|
||||
|
||||
await tester.changeCalculateAtIndex(1, CalculationType.Sum);
|
||||
|
||||
// Enter values in cells
|
||||
await tester.editCell(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.Number,
|
||||
input: '100',
|
||||
);
|
||||
|
||||
await tester.editCell(
|
||||
rowIndex: 1,
|
||||
fieldType: FieldType.Number,
|
||||
input: '100',
|
||||
);
|
||||
|
||||
// Dismiss edit cell
|
||||
await tester.sendKeyDownEvent(LogicalKeyboardKey.enter);
|
||||
|
||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||
|
||||
expect(find.text('200'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('add calculations and remove row', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
|
||||
|
||||
// Change two Fields to Number
|
||||
await tester.changeFieldTypeOfFieldWithName('Type', FieldType.Number);
|
||||
await tester.changeFieldTypeOfFieldWithName('Done', FieldType.Number);
|
||||
|
||||
expect(find.text('Calculate'), findsNWidgets(2));
|
||||
|
||||
await tester.changeCalculateAtIndex(1, CalculationType.Sum);
|
||||
await tester.changeCalculateAtIndex(2, CalculationType.Min);
|
||||
|
||||
// Enter values in cells
|
||||
await tester.editCell(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.Number,
|
||||
input: '100',
|
||||
);
|
||||
await tester.editCell(
|
||||
rowIndex: 1,
|
||||
fieldType: FieldType.Number,
|
||||
input: '150',
|
||||
);
|
||||
await tester.editCell(
|
||||
rowIndex: 0,
|
||||
fieldType: FieldType.Number,
|
||||
input: '50',
|
||||
cellIndex: 1,
|
||||
);
|
||||
await tester.editCell(
|
||||
rowIndex: 1,
|
||||
fieldType: FieldType.Number,
|
||||
input: '100',
|
||||
cellIndex: 1,
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Dismiss edit cell
|
||||
await tester.sendKeyDownEvent(LogicalKeyboardKey.enter);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('250'), findsOneWidget);
|
||||
expect(find.text('50'), findsNWidgets(2));
|
||||
|
||||
// Delete 1st row
|
||||
await tester.hoverOnFirstRowOfGrid();
|
||||
await tester.tapRowMenuButtonInGrid();
|
||||
await tester.tapDeleteOnRowMenu();
|
||||
|
||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||
|
||||
expect(find.text('150'), findsNWidgets(2));
|
||||
expect(find.text('100'), findsNWidgets(2));
|
||||
});
|
||||
});
|
||||
}
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
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';
|
||||
import 'package:appflowy/workspace/application/settings/date_time/date_format_ext.dart';
|
||||
import 'package:appflowy/workspace/presentation/notifications/widgets/notification_item.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/date_time.pbenum.dart';
|
||||
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 '../../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();
|
||||
|
||||
group('Reminder in Document', () {
|
||||
testWidgets('Add reminder for tomorrow, and include time', (tester) async {
|
||||
const time = "23:59";
|
||||
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
final dateTimeSettings =
|
||||
await UserSettingsBackendService().getDateTimeSettings();
|
||||
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
await tester.editor.getCurrentEditorState().insertNewLine();
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Trigger inline action menu and type 'remind tomorrow'
|
||||
final tomorrow = await _insertReminderTomorrow(tester);
|
||||
|
||||
Node node = tester.editor.getCurrentEditorState().getNodeAtPath([1])!;
|
||||
Map<String, dynamic> mentionAttr =
|
||||
node.delta!.first.attributes![MentionBlockKeys.mention];
|
||||
|
||||
expect(node.type, 'paragraph');
|
||||
expect(mentionAttr['type'], MentionType.date.name);
|
||||
expect(mentionAttr['date'], tomorrow.toIso8601String());
|
||||
|
||||
await tester.tap(
|
||||
find.text(dateTimeSettings.dateFormat.formatDate(tomorrow, false)),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.byType(Toggle));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.enterText(find.byType(FlowyTextField), time);
|
||||
|
||||
// Leave text field to submit
|
||||
await tester.tap(find.text(LocaleKeys.grid_field_includeTime.tr()));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
node = tester.editor.getCurrentEditorState().getNodeAtPath([1])!;
|
||||
mentionAttr = node.delta!.first.attributes![MentionBlockKeys.mention];
|
||||
|
||||
final tomorrowWithTime =
|
||||
_dateWithTime(dateTimeSettings.timeFormat, tomorrow, time);
|
||||
|
||||
expect(node.type, 'paragraph');
|
||||
expect(mentionAttr['type'], MentionType.date.name);
|
||||
expect(mentionAttr['date'], tomorrowWithTime.toIso8601String());
|
||||
});
|
||||
|
||||
testWidgets('Add reminder for tomorrow, and navigate to it',
|
||||
(tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.editor.tapLineOfEditorAt(0);
|
||||
await tester.editor.getCurrentEditorState().insertNewLine();
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Trigger inline action menu and type 'remind tomorrow'
|
||||
final tomorrow = await _insertReminderTomorrow(tester);
|
||||
|
||||
final Node node =
|
||||
tester.editor.getCurrentEditorState().getNodeAtPath([1])!;
|
||||
final Map<String, dynamic> mentionAttr =
|
||||
node.delta!.first.attributes![MentionBlockKeys.mention];
|
||||
|
||||
expect(node.type, 'paragraph');
|
||||
expect(mentionAttr['type'], MentionType.date.name);
|
||||
expect(mentionAttr['date'], tomorrow.toIso8601String());
|
||||
|
||||
// Create and Navigate to a new document
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Open "Upcoming" in Notification hub
|
||||
await tester.openNotificationHub(tabIndex: 1);
|
||||
|
||||
// Expect 1 notification
|
||||
tester.expectNotificationItems(1);
|
||||
|
||||
// Tap on the notification
|
||||
await tester.tap(find.byType(NotificationItem));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Expect node at path 1 to be the date/reminder
|
||||
expect(
|
||||
tester.editor
|
||||
.getCurrentEditorState()
|
||||
.getNodeAtPath([1])
|
||||
?.delta
|
||||
?.first
|
||||
.attributes?[MentionBlockKeys.mention]['type'],
|
||||
MentionType.date.name,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Future<DateTime> _insertReminderTomorrow(WidgetTester tester) async {
|
||||
await tester.editor.showAtMenu();
|
||||
|
||||
await FlowyTestKeyboard.simulateKeyDownEvent(
|
||||
[
|
||||
LogicalKeyboardKey.keyR,
|
||||
LogicalKeyboardKey.keyE,
|
||||
LogicalKeyboardKey.keyM,
|
||||
LogicalKeyboardKey.keyI,
|
||||
LogicalKeyboardKey.keyN,
|
||||
LogicalKeyboardKey.keyD,
|
||||
LogicalKeyboardKey.space,
|
||||
LogicalKeyboardKey.keyT,
|
||||
LogicalKeyboardKey.keyO,
|
||||
LogicalKeyboardKey.keyM,
|
||||
LogicalKeyboardKey.keyO,
|
||||
LogicalKeyboardKey.keyR,
|
||||
LogicalKeyboardKey.keyR,
|
||||
LogicalKeyboardKey.keyO,
|
||||
LogicalKeyboardKey.keyW,
|
||||
],
|
||||
tester: tester,
|
||||
);
|
||||
|
||||
await FlowyTestKeyboard.simulateKeyDownEvent(
|
||||
[LogicalKeyboardKey.enter],
|
||||
tester: tester,
|
||||
);
|
||||
|
||||
return DateTime.now().add(const Duration(days: 1)).withoutTime;
|
||||
}
|
||||
|
||||
DateTime _dateWithTime(UserTimeFormatPB format, DateTime date, String time) {
|
||||
final t = format == UserTimeFormatPB.TwelveHour
|
||||
? DateFormat.jm().parse(time)
|
||||
: DateFormat.Hm().parse(time);
|
||||
|
||||
return DateTime.parse(
|
||||
'${date.year}${_padZeroLeft(date.month)}${_padZeroLeft(date.day)} ${_padZeroLeft(t.hour)}:${_padZeroLeft(t.minute)}',
|
||||
);
|
||||
}
|
||||
|
||||
String _padZeroLeft(int a) => a.toString().padLeft(2, '0');
|
||||
+1
-1
@@ -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();
|
||||
-2
@@ -1,13 +1,11 @@
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import 'notifications_settings_test.dart' as notifications_settings_test;
|
||||
import 'user_icon_test.dart' as user_icon_test;
|
||||
import 'user_language_test.dart' as user_language_test;
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
notifications_settings_test.main();
|
||||
user_icon_test.main();
|
||||
user_language_test.main();
|
||||
}
|
||||
+6
-5
@@ -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();
|
||||
@@ -14,7 +15,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
|
||||
await tester.tapGoButton();
|
||||
tester.expectToSeeHomePage();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
await tester.openSettings();
|
||||
|
||||
await tester.openSettingsPage(SettingsPage.language);
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/rename_view_popover.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.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 '../../shared/keyboard.dart';
|
||||
import '../../shared/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('Rename current view item', () {
|
||||
testWidgets('by F2 shortcut', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await FlowyTestKeyboard.simulateKeyDownEvent(
|
||||
[LogicalKeyboardKey.f2],
|
||||
tester: tester,
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(RenameViewPopover), findsOneWidget);
|
||||
|
||||
await tester.enterText(
|
||||
find.descendant(
|
||||
of: find.byType(RenameViewPopover),
|
||||
matching: find.byType(FlowyTextField),
|
||||
),
|
||||
'hello',
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Dismiss rename popover
|
||||
await tester.tap(find.byType(AppFlowyEditor));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byType(SingleInnerViewItem),
|
||||
matching: find.text('hello'),
|
||||
),
|
||||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_folder.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import '../../shared/util.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('sidebar expand test', () {
|
||||
bool isExpanded({required FolderCategoryType type}) {
|
||||
if (type == FolderCategoryType.private) {
|
||||
return find
|
||||
.descendant(
|
||||
of: find.byType(PrivateSectionFolder),
|
||||
matching: find.byType(ViewItem),
|
||||
)
|
||||
.evaluate()
|
||||
.isNotEmpty;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
testWidgets('first time the personal folder is expanded', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
// first time is expanded
|
||||
expect(isExpanded(type: FolderCategoryType.private), true);
|
||||
|
||||
// collapse the personal folder
|
||||
await tester.tapButton(
|
||||
find.byTooltip(LocaleKeys.sideBar_clickToHidePrivate.tr()),
|
||||
);
|
||||
expect(isExpanded(type: FolderCategoryType.private), false);
|
||||
|
||||
// expand the personal folder
|
||||
await tester.tapButton(
|
||||
find.byTooltip(LocaleKeys.sideBar_clickToHidePrivate.tr()),
|
||||
);
|
||||
expect(isExpanded(type: FolderCategoryType.private), true);
|
||||
});
|
||||
});
|
||||
}
|
||||
+9
-21
@@ -1,15 +1,14 @@
|
||||
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/favorite_folder.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/_favorite_folder.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
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();
|
||||
@@ -31,17 +30,11 @@ void main() {
|
||||
].map((e) => 'document_$e').toList();
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
final parentName = i == 0 ? gettingStarted : names[i - 1];
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: names[i],
|
||||
parentName: parentName,
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
tester.expectToSeePageName(
|
||||
names[i],
|
||||
parentName: parentName,
|
||||
layout: ViewLayoutPB.Document,
|
||||
parentLayout: ViewLayoutPB.Document,
|
||||
);
|
||||
tester.expectToSeePageName(names[i], parentName: parentName);
|
||||
}
|
||||
|
||||
await tester.favoriteViewByName(gettingStarted);
|
||||
@@ -87,7 +80,6 @@ void main() {
|
||||
await tester.favoriteViewByName(gettingStarted);
|
||||
await tester.hoverOnPageName(
|
||||
gettingStarted,
|
||||
layout: ViewLayoutPB.Document,
|
||||
onHover: () async {
|
||||
await tester.renamePage(name);
|
||||
await tester.pumpAndSettle();
|
||||
@@ -113,10 +105,9 @@ void main() {
|
||||
final names = [1, 2].map((e) => 'document_$e').toList();
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
final parentName = i == 0 ? gettingStarted : names[i - 1];
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: names[i],
|
||||
parentName: parentName,
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
tester.expectToSeePageName(names[i], parentName: parentName);
|
||||
}
|
||||
@@ -136,7 +127,6 @@ void main() {
|
||||
|
||||
await tester.hoverOnPageName(
|
||||
names[1],
|
||||
layout: ViewLayoutPB.Document,
|
||||
onHover: () async {
|
||||
await tester.tapDeletePageButton();
|
||||
await tester.pumpAndSettle();
|
||||
@@ -150,7 +140,6 @@ void main() {
|
||||
|
||||
await tester.hoverOnPageName(
|
||||
gettingStarted,
|
||||
layout: ViewLayoutPB.Document,
|
||||
onHover: () async {
|
||||
await tester.tapDeletePageButton();
|
||||
await tester.pumpAndSettle();
|
||||
@@ -170,7 +159,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName();
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
await tester.favoriteViewByName(gettingStarted);
|
||||
expect(
|
||||
find.byWidgetPredicate(
|
||||
@@ -190,11 +179,10 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.tapGoButton();
|
||||
|
||||
await tester.createNewPageWithName();
|
||||
await tester.createNewPageWithNameUnderParent();
|
||||
await tester.favoriteViewByName(gettingStarted);
|
||||
await tester.hoverOnPageName(
|
||||
gettingStarted,
|
||||
layout: ViewLayoutPB.Document,
|
||||
useLast: false,
|
||||
onHover: () async {
|
||||
await tester.tapPageOptionButton();
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
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();
|
||||
@@ -18,7 +18,7 @@ void main() {
|
||||
|
||||
// create document, board, grid and calendar views
|
||||
for (final value in ViewLayoutPB.values) {
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: value.name,
|
||||
parentName: gettingStarted,
|
||||
layout: value,
|
||||
@@ -46,7 +46,7 @@ void main() {
|
||||
|
||||
// create document, board, grid and calendar views
|
||||
for (final value in ViewLayoutPB.values) {
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: value.name,
|
||||
parentName: gettingStarted,
|
||||
layout: value,
|
||||
+11
-13
@@ -1,18 +1,18 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database_view/board/presentation/board_page.dart';
|
||||
import 'package:appflowy/plugins/database_view/calendar/presentation/calendar_page.dart';
|
||||
import 'package:appflowy/plugins/database_view/grid/presentation/grid_page.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/workspace/presentation/home/menu/view/draggable_view_item.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_add_button.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_more_action_button.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
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();
|
||||
@@ -41,7 +41,7 @@ void main() {
|
||||
for (final layout in ViewLayoutPB.values) {
|
||||
// create a new page
|
||||
final name = 'AppFlowy_$layout';
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: name,
|
||||
layout: layout,
|
||||
);
|
||||
@@ -79,10 +79,9 @@ void main() {
|
||||
final names = [1, 2, 3, 4].map((e) => 'document_$e').toList();
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
final parentName = i == 0 ? gettingStarted : names[i - 1];
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: names[i],
|
||||
parentName: parentName,
|
||||
layout: ViewLayoutPB.Document,
|
||||
);
|
||||
tester.expectToSeePageName(names[i], parentName: parentName);
|
||||
}
|
||||
@@ -144,14 +143,14 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
const document = 'document';
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: document,
|
||||
openAfterCreated: false,
|
||||
);
|
||||
tester.expectToSeePageName(document, layout: ViewLayoutPB.Document);
|
||||
tester.expectToSeePageName(document);
|
||||
|
||||
const grid = 'grid';
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: grid,
|
||||
layout: ViewLayoutPB.Grid,
|
||||
openAfterCreated: false,
|
||||
@@ -187,10 +186,9 @@ void main() {
|
||||
await tester.tapGoButton();
|
||||
|
||||
const grid = 'grid';
|
||||
await tester.createNewPageWithName(
|
||||
await tester.createNewPageWithNameUnderParent(
|
||||
name: grid,
|
||||
layout: ViewLayoutPB.Grid,
|
||||
openAfterCreated: true,
|
||||
);
|
||||
tester.expectToSeePageName(grid, layout: ViewLayoutPB.Grid);
|
||||
|
||||
+1
-2
@@ -1,6 +1,5 @@
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
import 'sidebar_expand_test.dart' as sidebar_expanded_test;
|
||||
import 'sidebar_favorites_test.dart' as sidebar_favorite_test;
|
||||
import 'sidebar_icon_test.dart' as sidebar_icon_test;
|
||||
import 'sidebar_test.dart' as sidebar_test;
|
||||
@@ -10,7 +9,7 @@ void startTesting() {
|
||||
|
||||
// Sidebar integration tests
|
||||
sidebar_test.main();
|
||||
sidebar_expanded_test.main();
|
||||
// sidebar_expanded_test.main();
|
||||
sidebar_favorite_test.main();
|
||||
sidebar_icon_test.main();
|
||||
}
|
||||
+3
-3
@@ -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();
|
||||
@@ -16,7 +16,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
|
||||
await tester.tapGoButton();
|
||||
tester.expectToSeeHomePage();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
await tester.openSettings();
|
||||
|
||||
await tester.openSettingsPage(SettingsPage.appearance);
|
||||
@@ -48,7 +48,7 @@ void main() {
|
||||
await tester.initializeAppFlowy();
|
||||
|
||||
await tester.tapGoButton();
|
||||
tester.expectToSeeHomePage();
|
||||
await tester.expectToSeeHomePageWithGetStartedPage();
|
||||
await tester.openSettings();
|
||||
|
||||
await tester.openSettingsPage(SettingsPage.appearance);
|
||||
Loaded 100 of 3545 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user