Compare commits

...
221 Commits
Author SHA1 Message Date
Lucas.Xu 05603c9472 chore: bump version 0.5.7 2024-05-10 15:29:08 +08:00
Richard Shiue e28d463cb9 fix: kanban board card text input inconsistency (#5307) 2024-05-10 15:16:31 +08:00
Lucas.Xu bdc66103c8 fix: android navigation bar issues (#5294) 2024-05-10 15:00:48 +08:00
Lucas.Xu e2b6e14762 refactor: mobile view page (#5288)
* refactor: mobile view page

* fix: provider not found

* chore: add page style integration tests

* fix: android title bar padding

* fix: unable to click mentioned page on Android

* fix: font family not available log
2024-05-10 15:00:40 +08:00
Lucas.Xu 6220680ce0 feat: support system default font family on desktop (#5279)
* fix: add permission check before selecting image in image block

* feat: use system default font on desktop

* fix: set appbar icon size to 30

* feat: add default font family on desktop
2024-05-07 19:44:00 +08:00
Nathan.foooandLucas.Xu b4279f8004 fix: ws connect with invalid token (#5282)
* chore: bump client api

* chore: fix potentail ws connect with invalid token

* fix: cargo clippy

---------

Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
2024-05-07 17:37:11 +08:00
Nathan.fooo dc813d85a8 chore: disable ai summary (#5277) 2024-05-07 12:38:44 +08:00
Lucas.Xu aa4fe2ba50 fix: color selection compatible with older versions (#5276)
* fix: color selection compatible with older versions

* chore: add a cover color function
2024-05-07 12:13:52 +08:00
Nathan.fooo a5b5a1f679 chore: bump client api (#5275) 2024-05-07 10:34:11 +08:00
Lucas.Xu 287c69a4fb fix: assert on uploading image on macos (#5272) 2024-05-07 09:11:35 +08:00
Mathias Mogensen c4f6703b76 fix: launch review improvements (#5263)
* fix: recent views fix

* fix: text button font color

* fix: sidebar scrollbar inset

* fix: account settings launch review

* fix: open + menu on mobile provider issue

* fix: code review

* fix: push view improvement
2024-05-06 18:13:17 +08:00
Nathan.fooo 3bdc8c222c chore: drop old user awarenss when open workspace (#5271) 2024-05-06 18:12:56 +08:00
Lucas.Xu 560529f7d9 fix: korean IME issue on Windows (#5267) 2024-05-06 16:23:13 +08:00
Lucas.Xu 9f44ae959a fix: the cursor will jump up when creating a new document on desktop. (#5269)
* fix: the cursor will jump up when creating a new document on desktop

* fix: the titlbar flashes when switching to another page

* fix: unit test

* fix: default font family copy
2024-05-06 15:50:32 +08:00
Lucas.Xu b2c366f6ae chore: remove debug print (#5268) 2024-05-06 13:34:59 +08:00
Nathan.fooo 3a9de61599 chore: update yrs version (#5262)
* chore: update yrs version

* chore: update client api
2024-05-06 11:30:13 +08:00
Lucas.Xu 266a2a53ab feat: request permission again if the user denied the photo permission (#5251)
* fix: clear the email field after sending email

* fix: ask permission before picking image

* feat: improve photo permission UI design

* chore: update translations

* fix: android photo permission

* chore: update translations

* fix: awareness meta data decode error
2024-05-06 11:27:55 +08:00
Richard Shiue d52042fa4f fix: open-row-as-full-page-related launch review issues (#5266) 2024-05-06 10:50:28 +08:00
Nathan.fooo a69e83c2cb feat: Implement summary field for database row (#5246)
* chore: impl summary field

* chore: draft ui

* chore: add summary event

* chore: impl desktop ui

* chore: impl mobile ui

* chore: update test

* chore: disable ai test
2024-05-05 22:04:34 +08:00
Richard Shiue 999ffeba21 chore: bump appflowy-board rev (#5260) 2024-05-05 11:16:09 +08:00
Lucas.Xu cb15018825 fix: google fonts not found exceptation (#5255) 2024-05-03 13:41:21 +08:00
Lucas.Xu 22e89fd197 fix: minor UI issues (#5253)
* fix: the desktop cover didn't sync with the mobile cover

* fix: remove unnecessary space when editing the title

* fix: recent view border issue

* fix: double focus on the title and doc
2024-05-03 09:13:11 +08:00
Lucas.Xu 554c821db9 fix: the desktop cover didn't sync with the mobile cover (#5252) 2024-05-03 09:12:49 +08:00
Richard Shiue 2eb88821ca fix: open row as full page launch review issues (#5254)
* perf: improve getting database speed

* fix: navigate to incorrect origin database view from full-width row

* fix: import row detail page action placement
2024-05-02 22:00:35 +08:00
Stefan Weiberg 813d024810 chore: update German translations and fixing English labels (#5233)
* chore: update translations with Fink 🐦

* chore: update translations with Fink 🐦
2024-05-02 14:10:36 +08:00
nathan 401ce7dfea chore: fix test 2024-05-02 13:46:15 +08:00
Lucas.Xu cadb177acd chore: upgrade editor version (#5244) 2024-05-02 12:10:46 +08:00
Lucas.Xu 016e131bd3 feat: adjust toolbar count based on the screen size (#5243) 2024-05-02 12:08:35 +08:00
Nathan.fooo 7831d8d4ab refactor: database row and cell notification (#5237)
* refactor: database row and cell notification

* chore: clippy

* chore: fix test
2024-05-02 11:42:33 +08:00
Mathias Mogensen e1e8747f15 feat: support mention page on mobile (#5158)
* feat: support mention page on mobile

* chore: clean up toggle notifier

* fix: changes after merge

* fix: depends on inherited widget error

* fix: amend after merge

* feat: add icon to search

* chore: slight style changes

* chore: revert podfile change

* ci: fix disposal
2024-05-02 02:10:56 +02:00
Lucas.Xu 6bfac6b80a feat: improve immersive cover style (#5241) 2024-05-01 22:24:55 +08:00
Chirag BargoojarandMathias Mogensen a971f3c6d2 fix: new group clear splash (#5214)
* fix: splash color for clear btn

* fix: translation for New group

* fix: complete rest of the issue

---------

Co-authored-by: Mathias Mogensen <mathias@appflowy.io>
2024-05-01 11:59:45 +02:00
Richard Shiue 1d73174b0c fix: export created at and last modified cells to csv (#5235)
* fix: export created at and last modified cells to csv

* fix: export csv test
2024-05-01 12:24:11 +08:00
Lucas.Xu 10a1571910 chore: revert auto expand feature (#5232) 2024-04-30 22:04:12 +08:00
Lucas.Xu 4d860cc404 feat: support inviting members (#5118)
* feat: support inviting members

* chore: update memeber error log

* feat: invite as member
2024-04-30 21:38:46 +08:00
Nathan.fooo 9a8109f5f8 chore: update client api and collab (#5231) 2024-04-30 20:40:03 +08:00
Mathias Mogensen 4981baac13 feat: settings my account (#5223)
* feat: my account settings page

* test: amend tests

* chore: remove unused code

* test: remove widget tests

* fix: text color on select buttons

* test: clean and remove unused test helpers

* test: fix test after refactor
2024-04-30 14:09:08 +02:00
Richard Shiue f3544375c9 fix: kanban UX bugs (#5227)
* chore: improve title editing behavior

* chore: fix editable text field

* chore: fix autoscroll
2024-04-30 17:35:03 +08:00
Lucas.Xu 33802fa62d feat: immersive page style on mobile (#5135) 2024-04-30 16:55:15 +08:00
Kilu.He 6d0598b101 feat: parse folder collab and display document title/icon/cover (#5222)
* feat: support web document and cypress test

* fix: support blocks

* fix: support table and outline

* fix: update nginx

* fix: support document title, icon, cover

fix: mock test folder
2024-04-30 11:32:26 +08:00
Richard Shiue e0d6b194bf fix: some database bugs (#5210)
* fix: open logic for url cell in database

* fix: row date created not working

* fix: help my toasts are burnt

* chore: quote style and add comment
2024-04-29 17:34:18 +08:00
Kilu.He 9135fb94ad feat: support web document and cypress test (#5116)
* feat: support web document and cypress test

* fix: support blocks

* fix: support table and outline

* fix: update nginx
2024-04-29 14:32:14 +08:00
Richard Shiue 969726ef73 feat: open a row as a full page (#5111)
* feat: open a row as a full page

* chore: don't set latest open view

* chore: fix calendar open

* chore: disable in relation

* chore: code cleanup

* chore: fix merge conflicts
2024-04-29 13:44:42 +08:00
Lucas.Xu 3c446d5e78 feat: use font name instead of name_regular (#5163) 2024-04-29 11:41:25 +08:00
Lucas.XuandMathias Mogensen 3fce5eebf8 fix: migrate OKRs issues (#5215)
* fix: disable color paraser when pasting texts

* fix: compile error

* fix: register hotkeys in init function

* fix: improve settings hotkey

* chore: update editor

* fix: view title overflow

* fix: integration test

* chore: improve auto expanding animation

* chore: bump version 0.5.6

* chore: enable collab workspace

---------

Co-authored-by: Mathias Mogensen <mathias@appflowy.io>
2024-04-29 11:41:09 +08:00
Richard Shiue 119fb03342 feat: mobile floating toolbar animation (#5170) 2024-04-29 10:33:57 +08:00
Richard Shiue 0b94e2b25d fix: kanban card icon not displaying (#5181) 2024-04-29 09:30:51 +08:00
Nathan.fooo 044dad1d3e chore: bump client api (#5217)
* chore: bump client api

* chore: fix compile

* chore: fix compile
2024-04-27 21:55:12 +08:00
Richard Shiue d4278a7549 chore: update documentation for type option cell-related traits (#5207) 2024-04-27 10:20:32 +08:00
Stefan Weiberg d467dcd68a chore: update translations with Fink 🐦 (#5200)
* chore: update translations with Fink 🐦

* chore: update translations with Fink 🐦
2024-04-26 20:11:46 +08:00
Korovandnathan 1ad351195d fix: websocket support custom port (#5123)
Co-authored-by: nathan <nathan@appflowy.io>
2024-04-26 20:09:55 +08:00
Nathan.fooo 122a392bf8 chore: update client api (#5208)
* chore: update client api

* chore: rename test target

* chore: fix test
2024-04-26 18:00:56 +08:00
Lucas.Xu d86afb03ba chore: add workspace log (#5206) 2024-04-26 14:09:02 +08:00
Nathan.fooo cc66147bc0 chore: checking workspace state consistent after switching workspace (#5201)
* refactor: getting workspace id

* refactor: check workspace id is match for http response

* refactor: check http repsonse in valid by checing the workspace id

* chore: update log

* chore: fix test

* chore: fix test

* chore: add test

* chore: update test
2024-04-26 09:44:07 +08:00
Lucas.Xu 65a289648e chore: release 0.5.5 (#5198) 2024-04-24 20:41:13 +08:00
Nathan.fooo 6ecbf971b2 chore: check workspace id before write to disk (#5197)
* chore: check workspace id before write to disk

* chore: update logs

* chore: update logs

* chore: update ci

* chore: bump client api
2024-04-24 14:38:47 +08:00
Sore d21d095f0b chore: update Kurdish (#5156) 2024-04-24 13:48:06 +08:00
hasanbeder 91635ee0cb chore: improve tr_TR language (#5182) 2024-04-24 13:47:31 +08:00
Nathan.fooo 77d600a742 chore: remove unused features (#5196)
* chore: remove unused features

* chore: update logs
2024-04-24 10:26:58 +08:00
Nathan.fooo 9aaada961f chore: remove unused code & update log (#5194)
* chore: remove unused code & update log

* chore: clippy

* chore: log
2024-04-24 08:47:33 +08:00
275d0b2ac4 fix: search launch review (#5169)
* fix: support filtering results by workspace

* feat: add search button to sidebar

* fix: reduce view/recent view fetching across application

* feat: add channel to search listener

* feat: clean + localization

* chore: remove redundant code

* fix: disable search

* chore: trigger ci

* chore: disable search in backend

* test: disable search tests for now

* feat: temp disable reliance on folder search

* fix: add debounce to inline actions

* chore: complete future if disposed

* fix: clean code

* chore: disable unused bloc with feature flag

* fix: recent views lazy read

* chore: revert podilfe change

* chore: update logs

* chore: update client api and collab

* chore: fix tst

* chore: fix test & update collab commit

* chore: update collab commit

* test: fix unit tests

* chore: update rust toolchain 1.77

* chore: use opt-level 1

* fix: code review

* chore: clippy

---------

Co-authored-by: nathan <nathan@appflowy.io>
Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
2024-04-23 21:46:57 +08:00
Lucas.Xu bf64b0d2fa fix: use database sync bloc in database page (#5183) 2024-04-23 13:49:51 +08:00
Lucas.Xu 0355ca5d73 feat: expand the view automatically upon opening (#5180)
* chore: remove unused code

* feat: expand the view automatically upon opening
2024-04-22 16:57:51 +08:00
Mathias Mogensen fe32079ab0 feat: code block launch review (#5175)
* feat: code block launch review

* chore: test lock file change

* chore: update version
2024-04-22 10:04:06 +02:00
Lucas.Xu 568311a855 fix: launch review issues 0.5.5 (#5162)
* fix: remove doubel tap to rename

* fix: keep showing the magic link toast

* feat: display workspace name instead of workspace

* feat: set the keyboard type of magic link textfield to email_address

* feat: support switching sign in and sign up

* fix: magic link ui design

* fix: improve sign in error toast

* fix: improve image load failed
2024-04-22 14:04:55 +08:00
Sore fd4783e19a Update translations (#5174)
* chore: update translations with Fink 🐦

* chore: update translations with Fink 🐦

* chore: update translations with Fink 🐦
2024-04-22 14:04:35 +08:00
Richard Shiue c60ed11fe5 fix: add an outline to accessory buttons (#5178) 2024-04-22 14:04:17 +08:00
Zack 62c80303c6 chore: update client api (#5177) 2024-04-22 14:03:57 +08:00
Nathan.fooo 83cf8b067c chore: bump client api (#5176) 2024-04-22 12:46:58 +08:00
Zack 35ff74cf7c chore: use inferred error instead (#5164) 2024-04-22 09:32:14 +08:00
Richard Shiue d8b0c783bf chore: update translation text for wrap cell content (#5172) 2024-04-22 09:27:57 +08:00
nathan 9b4fd3bf57 chore: update log 2024-04-19 21:32:36 +08:00
Richard ShiueandLucas.Xu 7745e54221 chore: improve link between folder and database (#5024)
* chore: improve link between folder and database

* chore: fix tests

* chore: update collab rev

---------

Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
2024-04-19 17:24:11 +08:00
careworry fab871eedb chore: fix some typos in comments (#5161)
Signed-off-by: careworry <worrycare@outlook.com>
2024-04-18 20:52:58 +08:00
Lucas.Xu 236374ea2e fix: clear the collaborators when the app paused (#5155) 2024-04-18 13:16:29 +08:00
Lucas.Xu d4fe957f24 fix: unable to open mentioned page on mobile (#5151) 2024-04-18 10:18:26 +08:00
Mathias Mogensen 8ccc879ef5 chore: update plugins package version (#5157) 2024-04-18 00:39:34 +02:00
Mathias Mogensen 0a5f3e8fa1 feat: use new appflowy-editor-plugins package (#5147)
* feat: use new appflowy-editor-plugins package

* fix: code block slash menu item

* chore: update build runner dependency

* chore: change dependency to pub.dev version

* chore: revert generate: false in pubspec
2024-04-17 10:52:58 +02:00
Abhijeet Singh 49e9b8c358 chore: update es-VE translations (#5149) 2024-04-17 08:33:11 +08:00
Richard Shiue 241bfa9ddd chore: remove field width and visibility (#5119) 2024-04-16 18:20:15 +08:00
amwps290 edc745e88a chore: update zh_CN translations (#5138)
* Fink 🐦: update translations

* Fink 🐦: update translations
2024-04-15 16:12:31 +08:00
Nathan.fooo d758e62c1a chore: Bump collab (#5136)
* chore: bump collab

* chore: bump collab

* chore: bump collab

* chore: fix test

* chore: disable supabse test
2024-04-15 14:50:28 +08:00
Richard Shiue e9e483291e chore: move responsibility of url valdiation to front-frontend (#5129)
* chore: move responsibility of url valdiation to frontend

* chore: fix test

* chore: fix tauri build
2024-04-15 11:43:02 +08:00
Richard Shiue 8947a89a24 feat: allow fields to not wrap cell content (#5128) 2024-04-13 16:48:28 +08:00
Richard Shiue 891fd16a0c refactor: fetch all select options from field type option instead of cell (#5122)
* refactor: fetch all options from type option

* chore: rustfmt

* ci: fix rust ci

* chore: fix clippy
2024-04-13 01:08:47 +08:00
kolowy 0ebcca63bb chore: update fr-FR translations (#5121) 2024-04-12 23:01:29 +08:00
b4d22bab14 feat: search mvp (#5064)
* feat: implement folder indexer

* feat: sqlite search views using fts5

* feat: add view indexing to user manager

* feat: implement folder indexer

* feat: add sqlite search documents

* feat: add document indexing to user manager

* feat: add document indexing to folder indexer

* chore: update collab rev

* feat: search frontend integration

* refactor: search index

* test: add event test

* chore: fix ci

* feat: initial command palette overlay impl (#4619)

* chore: test search engine

* chore: initial structure

* chore: replace old search request

* chore: enable log for lib-dispatch

* chore: move search manager to core

* feat: move traits and responsibility to search crate

* feat: move search to search crate

* feat: replace sqlite with tantivy

* feat: deserialize tantivy documents

* chore: fixes after rebase

* chore: clean code

* feat: fetch and sort results

* fix: code review + cleaning

* feat: support custom icons

* feat: support view layout icons

* feat: rename bloc and fix indexing

* fix: prettify dialog

* feat: score results

* chore: update collab rev

* feat: add recent view history to command palette

* test: add integration_tests

* fix: clippy changes

* fix: focus traversal in cmd palette

* fix: remove file after merging main

* chore: code review and panic-safe

* feat: index all views if index does not exist

* chore: improve logic with conditional

* chore: add is_empty check

* chore: abstract logic from folder manager init

* chore: update collab rev

* chore: code review

* chore: fixes after merge + update lock file

* chore: revert cargo lock

* fix: set icon type when removing icon

* fix: code review + dependency inversion

* fix: remove icon fix for not persisting icon type

* test: simple tests manipulating views

* test: create 100 views

* fix: tauri build

* chore: create 1000 views

* chore: create util methods

* chore: test

* chore: test

* chore: remove logs

* chore: fix build.rs

* chore: export models

* chore: enable clear cache on Rust-CI

* fix: navigate to newly created views

* fix: force disable setting workspace listener on rebuilds

* fix: remove late final

* fix: missing returns

* fix: localization and minor fixes

* test: add index assert to large test

* fix: missing section param after merging main

* chore: try fix unzip file error

* chore: lower the test

* feat: show hint when result is in trash

* feat: one index_writer per index

* fix: minor changes after merge

* fix: make create_log_filter public after merge

* chore: fix test

* chore: fix test

* chore: flutter analyze

* chore: flutter analyze

* chore: fix tauri build

---------

Co-authored-by: nathan <nathan@appflowy.io>
Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
Co-authored-by: Nathan.fooo <86001920+appflowy@users.noreply.github.com>
2024-04-12 16:21:41 +08:00
Lucas.Xu 39d8d428a6 fix: rust ci (#5115)
* fix: rust ci

* fix: flutter ci
2024-04-11 20:15:40 +08:00
景蓝 3a42e94907 chore: update ZH_CN translate (#4180) 2024-04-11 20:02:14 +08:00
VashonandLucas.Xu a50918fa6a feat: expand share option (#5021)
* feat: expand share option

* chore: optimize the code

---------

Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
2024-04-11 20:01:36 +08:00
Lucas.Xu 1597f7d94c feat: implement magic link sign in (#5036) 2024-04-11 16:33:28 +08:00
Richard Shiue b7b4ea2da1 refactor: cell data transform logic (#5039)
* refactor: cell data transform logic

* chore: remove redundant select option event

* chore: adapt tests to changes
2024-04-11 14:49:36 +08:00
Zack 828f312294 feat: workspace invite (#4827)
* feat: add rename and change icon for workspace cloud api

* feat: added created at field for UserWorkspacePB

* test: added view check after creating workspace

* fix: allow new_icon to be empty string

* feat: add invitation api cloud services

* chore: cargo clippy

* chore: merge conflict

* feat: add workspace invitation test

* fix: use back old role and af role

* chore: use 1.75 channel rust toolchain

* chore: added error for test case

* chore: added ci var

* chore: cargo clippy
2024-04-11 14:47:34 +08:00
Vivek Verma b51ff318a1 feat: double tab edit side panel (#5000)
* feat: double tab edit side panel

* fix: double tap edit only for selected view, check added

* fix: format
2024-04-11 14:47:02 +08:00
Lucas.Xu f93429de8b chore: commit machine translation (#5110)
* chore: machine translation

* Fink 🐦: update translations
2024-04-11 14:12:31 +08:00
Richard Shiue 6e3c731162 chore: remove single field listener (#5113) 2024-04-11 13:43:36 +08:00
Niklas Buchfink 3de2a20278 feat: add ninja_i18n.yml i18n lint action (#4950) 2024-04-10 21:07:17 +08:00
Richard ShiueandLucas.Xu 066a511dc5 feat: relation field improvements (#5070)
* feat: keyboard navigation for relation cell editor

* feat: open related rows

* feat: separated selected and unselected rows

* chore: apply suggestions from code review

Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>

* chore: fix launch review issues

* chore: add documentation

---------

Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
2024-04-10 20:39:20 +08:00
Vishwa Karthik 3bbba2eeb4 fix: import panel exits on esc key (#4259) (#5062) 2024-04-10 15:59:53 +08:00
Mathias Mogensen d35742d34c feat: code block improvements (#5054)
* feat: prettify code block component + copy code

* feat: search for languages in code block

* feat: non-collapsed selection indentation in code block

* fix: focus workaround for language search

* feat: multi selection outdent

* feat: add line numbering

* feat: prefer built in mono font for code block

* fix: add clamping physics to scrollview

* feat: pseudo auto indent and fix rebuild issue

* refactor: consolidate commands

* fix: track cursor in code block

* fix: no need to set selection on updating language
2024-04-10 15:33:00 +08:00
Richard Shiue a1a7321f4c fix: regression selected options not scrolling automatically (#5058) 2024-04-10 15:28:26 +08:00
Kilu.He 11ed32cf4f fix: remove deploy web in main (#5105) 2024-04-10 13:50:25 +08:00
Lucas.Xu 1909726c9a chore: bump version 0.5.5 (#5107) 2024-04-10 12:27:39 +08:00
Richard Shiue 12ec90ada0 chore: rename folder builder for re-use (#5020) 2024-04-10 11:40:02 +08:00
Lucas.Xu 17df31a512 fix: windows size overflow (#5103) 2024-04-10 11:36:22 +08:00
kolowy 1aa4646433 chore: update French translations (#5101) 2024-04-10 11:36:04 +08:00
Lucas.Xu 34cf4da49e chore: enable team workspace (#5102) 2024-04-09 20:05:28 +08:00
Mathias Mogensen ec46a30e6c fix: update last modified on icon change (#4798)
* fix: update last modified on icon change

* fix: clippy

* chore: clean code

* chore: reorder operations

* chore: fix import after merge
2024-04-09 14:05:12 +02:00
Lucas.Xu 8042be6575 fix: only fetch visible recent view (#5090)
* fix: only fetch visible recent view

* fix: flutter analyze
2024-04-09 20:01:29 +08:00
Mathias Mogensen 72049d28d5 fix: hide menu resize when collapsed (#5076) 2024-04-09 13:27:23 +02:00
Mathias Mogensen 2126e6e449 fix: do not fetch reminders on resize window (#5100) 2024-04-09 13:26:40 +02:00
Lucas.Xu 09f5317768 chore: disable team workspace (#5099) 2024-04-09 09:46:53 +08:00
hasanbeder b2f0c4f109 chore: update tr-TR.json (#5095)
This commit updates the Turkish translations for the AppFlowy application. 

Several improvements and fixes have been made to enhance the accuracy and consistency of the translations. Additionally, translations for new features and UI elements have been added.

This update aims to provide a better user experience for Turkish-speaking users of AppFlowy. 🇹🇷

chore(localization): Update Turkish translations
feat(localization): Update Turkish translations (tr-TR.json)
fix(localization): Improve Turkish translations for accuracy and consistency
docs(localization): Add Turkish translations for new features and UI elements
2024-04-09 09:00:46 +08:00
Lucas.Xu da5b369aec feat: get view ancestors (#5096) 2024-04-09 08:58:53 +08:00
Lucas.Xu a92f3d30c2 chore: update editor version & update CHANGELOG (#5094)
* chore: update editor version

* chore: update changelog
2024-04-08 21:40:09 +08:00
Nathan.fooo 5c96a2c5cb chore: fix open workspace (#5092)
* chore: fix open workspace

* chore: fix open workspace
2024-04-08 20:55:02 +08:00
hongttandLucas.Xu 31798959c7 chore: update Vietnamese translations (#5080)
Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
2024-04-08 20:43:38 +08:00
Kilu.He 5479d3ec6e chore: web build size optimization (#5071)
* chore: deploy test web

fix: update nginx.conf

fix: support https

* fix: support wasm gzip

* chore: optimize web build size

* fix: code review
2024-04-08 20:09:15 +08:00
Lucas.Xu 5777830730 feat: doc auto refresh (#5088)
* feat: doc auto refresh

* chore: update editor version
2024-04-08 18:01:20 +08:00
Nathan.fooo 79ea485a27 chore: update client api (#5087) 2024-04-08 16:13:37 +08:00
Lucas.Xu f0d8eee8a0 fix: doc state refresh (#5086) 2024-04-08 14:06:05 +08:00
Kilu.He 83b18c4825 fix: tauri ci error (#5085) 2024-04-08 12:11:58 +08:00
Lucas.Xu 429892aefc fix: delta insert assert (#5083) 2024-04-08 10:00:00 +08:00
JulesDmn d56de308e1 chore: update French translations (#5077) 2024-04-08 09:34:32 +08:00
Juliano Penna 3171712380 chore: enable more editor text to be translated (#4426) 2024-04-08 09:33:45 +08:00
47d321b8c2 fix: twelve hour parsing issue (#4721)
* fix: twelve hour time format fixed

* fix: time format for 12hour

* feat: auto capitalize am-pm in formatter

* fix: time field placeholder based on user time format

* chore: bugfix + improvements

---------

Co-authored-by: Mathias Mogensen <mathias@appflowy.io>
Co-authored-by: Mathias Mogensen <42929161+Xazin@users.noreply.github.com>
2024-04-08 09:33:18 +08:00
Lucas.Xu 9536cde789 feat: add a loading indicator when creating, deleting, or switching workspaces. (#5067) 2024-04-07 23:06:33 +08:00
Nathan.fooo 3e32fac876 chore: pass platform info to rust side (#5079)
* chore: pass platform info to rust side

* chore: pass platform info to rust side

* chore: fix test

* chore: fix test

* chore: fix test

* chore: enable ios log
2024-04-07 21:36:55 +08:00
Nathan.fooo 81594fa796 chore: bump client api (#5078) 2024-04-07 15:22:37 +08:00
Nathan.fooo db6767f61e chore: fix create workspace bugs (#5074) 2024-04-06 21:59:37 +08:00
nathan 5ceb132b0b chore: disable supabase 2024-04-05 13:58:40 +08:00
Nathan.fooo 587de161f6 chore: bump collab and client api (#5069)
* chore: bump collab that do not emit awareness by default

* chore: bump collab
2024-04-05 13:57:34 +08:00
Richard Shiue 7ca3f215a3 chore: rename android ci yaml (#5065) 2024-04-05 09:25:58 +08:00
Sore 2f386ff24d chore: update ckb-KU.json (#5066)
* Update ckb-KU.json

* Update settings.json

* Update project.inlang.json
2024-04-05 09:25:12 +08:00
Nathan.fooo 33dd21f4a5 chore: bump collab that do not emit awareness by default (#5063) 2024-04-04 22:46:54 +08:00
Nathan.fooo 65e7e2347a chore: versionize migration (#5060) 2024-04-04 13:03:40 +08:00
Nathan.fooo 8ade3b5f73 chore: bump client api (#5057) 2024-04-04 10:56:10 +08:00
Lucas.Xu 0ace832374 chore: enable collaborator (#5051) 2024-04-04 09:09:53 +08:00
Lucas.Xu 382ce827c1 fix: workspace integration test (#5049) 2024-04-03 22:30:01 +08:00
Kilu.He c97ece5e81 chore: web and tauri project (#4996)
* chore: web and tauri project

fix: clippy

* fix: update version
2024-04-03 19:25:54 +08:00
Nathan.fooo 046e0bac36 chore: fix awareness test (#5050)
* chore: fix awarenss test

* ci: try fix docker ci

* ci: clippy
2024-04-03 17:16:32 +08:00
Nathan.fooo 58fb529eaa chore: fix user awareness fetch (#5048)
* chore: fix user awareness fetch

* chore: update

* chore: update
2024-04-03 15:43:19 +08:00
Lucas.Xu 38fe61ff69 chore: bump version 0.5.4 (#5047) 2024-04-03 13:29:11 +08:00
Lucas.Xu e8931c5bd2 fix: workspaces empty error in local mode (#5045)
* fix: workspaces empty error in local mode

* fix: not allowed the user delete the only workspace
2024-04-03 12:21:02 +08:00
Nathan.fooo a25c728866 chore: bump collab (#5042)
* chore: bump collab

* chore: bump client api

* chore: fix test
2024-04-03 11:26:48 +08:00
Lucas.Xu e022ee88da fix: disable collaborators in local mode (#5043) 2024-04-03 10:30:22 +08:00
Nathan.fooo dff3ea60bd chore: start init sync when open document/database (#5040) 2024-04-02 22:15:42 +08:00
Nathan.fooo 419600ca11 chore: fix flutter log (#5038) 2024-04-02 20:02:45 +08:00
Kilu.He 4da624d2d3 chore: stop run web ci (#5037) 2024-04-02 15:55:15 +08:00
Kilu.He acec664879 fix: the error of miss update yrs repo (#5035) 2024-04-02 15:14:45 +08:00
Lucas.Xu 682f2a6a3b chore: replace close_document with close_view (#5033) 2024-04-02 13:36:59 +08:00
nathan 5a00361207 chore: remove doc state check that download from remote 2024-04-02 12:57:38 +08:00
Lucas.Xu 096a01ed44 fix: remove the deleted workspace from local storage (#5026)
* fix: remove the deleted workspace from local storage

* fix: unable to get latest workspaces on mobile

* fix: unable to get latest workspaces on desktop

* chore: try to fix ios ci

* fix: user workspace menu flash

* Revert "chore: try to fix ios ci"

This reverts commit 4a1e8bcb9d.
2024-04-02 11:28:05 +08:00
Nathan.fooo 1816b15b55 feat: fetch missing updates (#5030)
* chore: using patch yrs

* chore: bump client api

* chore: bump client api

* chore: bump client api

* chore: bump client api

* chore: bump collab

* chore: bump client api

* chore: bump client api

* chore: bump client api
2024-04-02 10:14:09 +08:00
Lucas.Xu 7576796e2f feat: filter recent views not belong to current user (#5014)
* feat: filter recent views not belong to current user

* fix: filter the trash ids and other private view ids
2024-04-02 09:57:14 +08:00
Lucas.Xu 555649c535 chore: upgrade android min sdk version to 23(android 6.0) (#5029) 2024-04-01 22:27:09 +08:00
Richard Shiue 440253f0d9 chore: restrict successful url launch to only http/https (#5028) 2024-04-01 21:09:38 +08:00
Lucas.Xu 75e51fdeea fix: favorite section doesn't update after switching workspace (#5025) 2024-04-01 15:34:30 +08:00
Lucas.Xu 723423d423 feat: support moving view across sections (#5015) 2024-04-01 14:27:29 +08:00
Lucas.Xu 893d23d6a3 fix: duplicated selections from remote (#5023)
* fix: duplicated selections from remote

* fix: docker ci
2024-04-01 12:08:52 +08:00
Lucas.Xu 932a403b5d feat: enable collab workspace features (#5012)
* feat: enable collab workspace features

* feat: change collaborator background color
2024-04-01 09:07:38 +08:00
Richard Shiue 53dbef25ab chore: more select option cell editor improvements (#5019) 2024-03-31 19:03:02 +08:00
Simon WordshiftyandRichard Shiue 129d56e494 chore: update sv-SE.json (#4916)
* Fink 🐦: update translations

---------

Co-authored-by: Richard Shiue <71320345+richardshiue@users.noreply.github.com>
2024-03-31 12:15:51 +08:00
TheRetroFAN 3f9f53c7a1 chore: update de-DE translations (#4994) 2024-03-31 12:09:35 +08:00
Richard Shiue 419464c175 feat: select option cell editor revamp (#5011)
* chore: gen new select option color on frontend

* chore: reorder select options

* chore: fix performance regression

* chore: add text field tap region

* chore: implement hover focus

* chore: implement keyboard focus

* chore: fix tests

* chore: reorder options in field editor

* chore: fix tests
2024-03-31 10:54:17 +08:00
Nathan.fooo adc2ee755e chore: remove lru (#5008)
* chore: remove lru

* chore: update logs

* chore: clippy
2024-03-30 16:28:24 +08:00
Nathan.fooo c2c84a5812 chore: Init sync when missing updates (#5001)
* chore: bump client api

* chore: update

* chore: update

* chore: bump client api

* chore: bump client api
2024-03-29 19:34:51 +08:00
Lucas.Xu 0e7b3c7db2 feat: support leaving workspace (#5007) 2024-03-29 19:01:43 +08:00
Lucas.Xu dc8f632e3e feat: database sync indicator (#5005)
* feat: database sync indicator

* fix: sync state error

* fix: ios ci
2024-03-29 17:37:02 +08:00
ZackandLucas.Xu 3f4a409364 feat: leave workspace api (#4942)
* feat: leave workpspace event

* feat: add leave workspace event

---------

Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
2024-03-29 16:53:59 +08:00
Richard Shiue 490cb48354 chore: organize code (#5004)
* chore: rename files and classes

* chore: move some files around
2024-03-29 11:54:42 +08:00
Richard Shiue 97575d4f6a fix: single select option filter ui (#5002) 2024-03-29 10:47:04 +08:00
crazeteam e16e8693c8 chore: remove repetitive words (#4992)
Signed-off-by: crazeteam <lilujing@outlook.com>
2024-03-28 17:52:33 +08:00
Lucas.Xu 60acf8c889 feat: collab cursor/selection (#4983)
* feat: support collab selection

* feat: collab cusro/selection

* chore: add metadata field

* feat: support displaying user name above cursor

* fix: emit error

* feat: support displaying collaborators

* feat: sync collaborator

* fix: collab doc issues

* chore: update deps

* feat: refactor device id

* chore: enable share button

* chore: update collab a816214

* fix: clippy lint

* chore: use extension type instead class function

* feat: add clear recent views button in debug mode

* chore: support clear recent views

* feat: support saving the last opened workspace

* chore: update collab
2024-03-28 17:46:31 +08:00
Lucas.Xu bf98a627b9 fix: workspace names align issue (#4993) 2024-03-26 15:36:48 +08:00
Lucas.Xu 6e5b346f25 feat: show member count on mobile (#4991)
* feat: show member count on mobile

* fix: favorite section not sync after switching workspace

* fix: favorite page will throw an error

* fix: flutter analyze
2024-03-26 14:52:48 +08:00
Lucas.Xu a1b183f330 feat: support for switching workspace on mobile (#4990)
* feat: support switching workspaces on mobile

* fix: sync recent section
2024-03-26 11:21:49 +08:00
Mayur Mahajan b8e3de97a5 docs: replace broken links with working ones (#4988)
* docs: replace broken links with working ones

* fix: some more links

- I made a mistake in the first commit for the link of installing from Mac/windows/linux
- replaced the link for roadmap
2024-03-26 10:52:50 +08:00
Nathan.fooo 84559afefa chore: bump collab that fixs database row sync issue (#4985) 2024-03-26 07:34:37 +08:00
Lucas.Xu de3e7ca9be fix: create new page error on mobile (#4984)
* chore: update translations

* fix: remove sidebar_root_view_bloc

* fix: remove sidebar_root_view_bloc

* chore: fix ios ci

* feat: customize image cache path
2024-03-25 23:08:52 +08:00
Nathan.fooo 701384cd74 chore: bump collab rev (#4982)
* chore: bump collab rev

* chore: bump collab rev

* chore: bump client api
2024-03-25 16:15:46 +08:00
Richard Shiue 477e43b5e6 chore: adjust select option editor (#4980)
* chore: adjust wording of hint

* chore: remove unnecessary add button

* chore: pdate select_option_editor.dart

* chore: udate en.json
2024-03-25 11:58:10 +08:00
Lucas.Xu 755083509f fix: discord notify ci (#4978) 2024-03-25 10:19:50 +08:00
Nathan.fooo 91e00d3782 chore: bump client api (#4976) 2024-03-25 08:13:49 +08:00
Nathan.fooo 3f0b3478c1 chore: bump client api that deduplicate sync message (#4972)
* chore: bump client api

* chore: update log

* chore: bump client api
2024-03-24 07:31:41 +08:00
Nathan.fooo b307312a71 chore: fix database row sync (#4964)
* chore: fix database row sync

* ci: fix test

* ci: fix web build

* chore: bump collab
2024-03-23 09:18:47 +08:00
Lucas.Xu c0642d3ff3 fix: collab workspace issues (#4961) 2024-03-22 17:15:18 +08:00
Richard Shiue 99ee60a60d fix: launch review issues (#4960)
* fix: i18n for multi select condition list

* fix: lookup url cell content to assert validity

* fix: compromise checkmark color
2024-03-22 16:50:01 +08:00
Lucas.Xu 27ff5f07ab Revert "feat: folder search mvp (#4665)" (#4962)
This reverts commit c1006c18c3.
2024-03-22 15:15:38 +08:00
Mathias Mogensen e2e38f72bb feat: clear all cells (#4856)
* feat: clear all cells

* fix: smaller dialog width

* fix: clippy warning
2024-03-21 17:40:23 +01:00
c1006c18c3 feat: folder search mvp (#4665)
* feat: implement folder indexer

* feat: sqlite search views using fts5

* feat: add view indexing to user manager

* feat: implement folder indexer

* feat: add sqlite search documents

* feat: add document indexing to user manager

* feat: add document indexing to folder indexer

* chore: update collab rev

* feat: search frontend integration

* refactor: search index

* test: add event test

* chore: fix ci

* feat: initial command palette overlay impl (#4619)

* chore: test search engine

* chore: initial structure

* chore: replace old search request

* chore: enable log for lib-dispatch

* chore: move search manager to core

* feat: move traits and responsibility to search crate

* feat: move search to search crate

* feat: replace sqlite with tantivy

* feat: deserialize tantivy documents

* chore: fixes after rebase

* chore: clean code

* feat: fetch and sort results

* fix: code review + cleaning

* feat: support custom icons

* feat: support view layout icons

* feat: rename bloc and fix indexing

* fix: prettify dialog

* feat: score results

* chore: update collab rev

* feat: add recent view history to command palette

* test: add integration_tests

* fix: clippy changes

* fix: focus traversal in cmd palette

* fix: remove file after merging main

* chore: code review and panic-safe

* feat: index all views if index does not exist

* chore: improve logic with conditional

* chore: add is_empty check

* chore: abstract logic from folder manager init

* chore: update collab rev

* chore: code review

* chore: fixes after merge + update lock file

* chore: revert cargo lock

* fix: set icon type when removing icon

* fix: code review + dependency inversion

* fix: remove icon fix for not persisting icon type

* test: simple tests manipulating views

* test: create 100 views

* fix: tauri build

* chore: create 1000 views

* chore: create util methods

* chore: test

* chore: test

* chore: remove logs

* chore: fix build.rs

* chore: export models

* chore: enable clear cache on Rust-CI

* fix: navigate to newly created views

* fix: force disable setting workspace listener on rebuilds

* fix: remove late final

* fix: missing returns

* fix: localization and minor fixes

* test: add index assert to large test

* fix: missing section param after merging main

* chore: try fix unzip file error

* chore: lower the test

* feat: show hint when result is in trash

---------

Co-authored-by: nathan <nathan@appflowy.io>
Co-authored-by: Jiraffe7 <twajxjiraffe@gmail.com>
Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
2024-03-21 17:34:53 +01:00
Kilu.He 4e99952b0e feat: support editor default shortcuts (#4943)
fix: pasted bugs
2024-03-21 21:52:48 +08:00
Richard Shiue 98876b149f ci: remove workaround for windows flutter ci (#4957) 2024-03-21 21:31:05 +08:00
Kilu.He 370f8a6558 feat: support custom scrollbar for document (#4936)
feat: support keywords for slash list to search

feat: support right-click to copy,pasted,cut

fix: the hint text should follow the align setting

feat: support get/set latest view

feat: support to show snackbar after delete page

fix: some bugs
2024-03-21 21:12:37 +08:00
Lucas.Xu 40b710d140 chore: enable feature flags in settings (#4956) 2024-03-21 14:20:43 +08:00
Zack 8c8be741b0 feat: support error for limit exceed (#4947) 2024-03-21 13:38:48 +08:00
Mathias MogensenandLucas.Xu 96af517c65 chore: bump version 0.5.3 (#4954)
* chore: bump version 0.5.3

* chore: update CHANGELOG.md

---------

Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
2024-03-21 13:27:25 +08:00
Lucas.Xu 5f8ef3856a feat: initial version for collab document (#4937)
* feat: initial version for collab document

* feat: show sync indicator

* feat: add sync document feature flag

* fix: rust ci

* chore: remove unused code

* chore: update doc_bloc.dart
2024-03-21 13:26:48 +08:00
Richard Shiue 37f521ae57 chore: kanban filter mvp (#4935)
* chore: add filter controller in group controller

* chore: enable url filter

* chore: bump collab rev

* chore: fix test

* chore: bump collab rev
2024-03-21 12:54:56 +08:00
Lucas.Xu ef9891abfe feat: support private section (#4882) 2024-03-21 12:02:03 +08:00
Mukund-TandonandLucas.Xu 9201cd6347 fix: import table from markdown (#4881)
* fix: fixed error while importing table from markdown

* test: added test for the changes made

* fix: made changes from code review

* chore: remove the force unwrap code

---------

Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
2024-03-20 21:33:39 +08:00
Kilu.He 73df51f35f feat: support list item style (#4934)
* fix: wrong offset of mention panel

feat: support list item style

* feat: support backward selection when the end selection is empty
2024-03-20 18:29:13 +08:00
Richard Shiue b2fb631500 fix: use bg color for mobile url bottom sheet (#4944) 2024-03-20 17:24:09 +08:00
Lucas.Xu 7a9cb03c8e refactor: improve mobile toolbar design (v3) (#4891)
* refactor: mobile toolbar v3 design

* feat: customize color item

* feat: close keyboard directly when clicking the close button even opening Aa menu

* feat: enable undo/redo in editing list mode
2024-03-20 15:41:12 +08:00
Nathan.fooo d19fa5a34a chore: support skip gc (#4926)
* chore: support skip gc

* chore: fix test
2024-03-20 14:34:50 +08:00
Lucas.Xu 822d62b562 feat: support 32-bit android devices (#4940)
* feat: support 32-bit android devices

* chore: update appflowy_editor
2024-03-20 13:08:32 +08:00
Kilu.He cb617cd9d3 feat: support markdown for heading 4-6 and inline math (#4917)
* feat: support-OAuth-login

* fix: optimize editor experience and fix bugs (0315)
2024-03-18 18:42:19 +08:00
Lucas.Xu 7375349626 fix: legacy bugs on mobile (#4927) 2024-03-18 14:06:12 +08:00
Richard Shiue fdc105a3e8 fix: docker ci (#4925) 2024-03-18 08:00:01 +08:00
Richard Shiue b557f89829 refactor: group controller traits (#4880)
* chore: remove async trait

* chore: require From<AnyMap> for trait TypeOption

* refactor: simplify group controller by removing GroupController trait

* chore: rename GroupControllerOperation trait to GroupController

* chore: add some docs

* chore: remove plural struct and use Vec directly

* chore: unnecessary mut

* chore: use same name to indicate passthrough

* chore: remove unused trait

* chore: rename group context to group controller context

* chore: remove group name

* chore: move type option interceptor to GroupCustomize and split off delegates for group context and group controller

* chore: adapt tests to changes

* chore: adapt flutter frontend to changes

* chore: code cleanup

* chore: fix clippy and adapt tauri frontend to changes

* chore: group controller code clean up

* chore: no need to pass cell data when moving row

* chore: rename some functions and variables

* chore: remove content filter
2024-03-16 17:18:40 +08:00
Richard Shiue 0f006fa60b feat: pre-fill row cells with filter data before row creation (#4854)
* feat: fill cells according to active filters

* chore: short circuit filter_row function

* chore: delete corresponding filters when filtered filter is deleted

* chore: validate filters when loading

* chore: remove unnecessary tuple in return

* chore: use trait

* chore: add tests
2024-03-16 17:18:30 +08:00
Lucas.Xu 452974ab99 feat: support el_GR language (#4922) 2024-03-16 11:53:34 +08:00
ひもの a16196eee5 chore: update ja-JP translations (#4921) 2024-03-16 10:29:06 +08:00
Anthony Belshi 31a33fdbfd feat: support el-GR language (#4920) 2024-03-16 09:50:51 +08:00
Nathan.foooandRichard Shiue bb414c3fd6 chore: enable relation to (#4866)
* chore: enable relation to

* chore: fix database name and improve UI

* chore: remove database view id from relation type option

* chore: add remove row id test

* chore: improve appearance of untitled rows

* chore: empty in row detail

* fix: cannot add events after closing

---------

Co-authored-by: Richard Shiue <71320345+richardshiue@users.noreply.github.com>
2024-03-15 22:58:55 +08:00
T I Z E NandLucas.Xu 8d01d54e7f chore: update german translations (#4865)
Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
2024-03-15 22:58:17 +08:00
Kilu.He 6d4cfe7316 feat: support-OAuth-login (#4899)
* feat: support-OAuth-login

* fix: modified ubuntu version and devtool

* fix: ts lint error
2024-03-15 20:29:00 +08:00
q200892907 57e3a2ce68 fix: apply formatting to pasted text only when the block is a paragraph (#4906) 2024-03-15 14:38:27 +08:00
Lucas.Xu ac34617e51 feat: support changing the workspace icon (#4898) 2024-03-15 14:10:30 +08:00
Abhijeet Singh 8776ac5c36 chore: update Spanish translations (#4896) 2024-03-15 09:35:19 +08:00
Lucas.Xu 3e1b4d81c1 fix: mobile keyboard issues (#4903) 2024-03-15 09:03:38 +08:00
1640 changed files with 71655 additions and 22488 deletions

No files matched your search

-7
View File
@@ -37,13 +37,6 @@ runs:
override: true
profile: minimal
- name: Export pub environment variables and add to PATH
run: |
if [ "$RUNNER_OS" == "Windows" ]; then
echo "PUB_CACHE=$LOCALAPPDATA\\Pub\\Cache" >> $GITHUB_ENV
fi
shell: bash
- name: Install flutter
id: flutter
uses: subosito/flutter-action@v2
@@ -20,7 +20,7 @@
# env:
# CARGO_TERM_COLOR: always
# FLUTTER_VERSION: "3.19.0"
# RUST_TOOLCHAIN: "1.75"
# RUST_TOOLCHAIN: "1.77.2"
# CARGO_MAKE_VERSION: "0.36.6"
# concurrency:
+72
View File
@@ -0,0 +1,72 @@
name: Deploy Web (Test)
on:
push:
branches:
- build/test
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
+11 -8
View File
@@ -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 }}
@@ -33,6 +27,15 @@ jobs:
- name: Checkout source code
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
run: |
@@ -45,4 +48,4 @@ jobs:
else \
echo "$line"; \
fi; \
done \
done
+20 -14
View File
@@ -7,6 +7,7 @@ on:
- "release/*"
paths:
- ".github/workflows/flutter_ci.yaml"
- ".github/actions/flutter_build/**"
- "frontend/rust-lib/**"
- "frontend/appflowy_flutter/**"
- "frontend/resources/**"
@@ -17,6 +18,7 @@ on:
- "release/*"
paths:
- ".github/workflows/flutter_ci.yaml"
- ".github/actions/flutter_build/**"
- "frontend/rust-lib/**"
- "frontend/appflowy_flutter/**"
- "frontend/resources/**"
@@ -24,7 +26,7 @@ on:
env:
CARGO_TERM_COLOR: always
FLUTTER_VERSION: "3.19.0"
RUST_TOOLCHAIN: "1.75"
RUST_TOOLCHAIN: "1.77.2"
CARGO_MAKE_VERSION: "0.36.6"
concurrency:
@@ -37,7 +39,7 @@ jobs:
strategy:
fail-fast: true
matrix:
os: [ubuntu-latest]
os: [ ubuntu-latest ]
include:
- os: ubuntu-latest
flutter_profile: development-linux-x86_64
@@ -71,7 +73,7 @@ jobs:
strategy:
fail-fast: true
matrix:
os: [windows-latest]
os: [ windows-latest ]
include:
- os: windows-latest
flutter_profile: development-windows-x86
@@ -97,7 +99,7 @@ jobs:
strategy:
fail-fast: true
matrix:
os: [macos-latest]
os: [ macos-latest ]
include:
- os: macos-latest
flutter_profile: development-mac-x86_64
@@ -119,12 +121,12 @@ jobs:
flutter_profile: ${{ matrix.flutter_profile }}
unit_test:
needs: [prepare-linux]
needs: [ prepare-linux ]
if: github.event.pull_request.draft != true
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
os: [ ubuntu-latest ]
include:
- os: ubuntu-latest
flutter_profile: development-linux-x86_64
@@ -198,6 +200,8 @@ jobs:
run: cargo make pub_get
- name: Run Flutter unit tests
env:
DISABLE_EVENT_LOG: true
working-directory: frontend
run: |
if [ "$RUNNER_OS" == "macOS" ]; then
@@ -210,11 +214,11 @@ jobs:
shell: bash
cloud_integration_test:
needs: [prepare-linux]
needs: [ prepare-linux ]
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
os: [ ubuntu-latest ]
include:
- os: ubuntu-latest
flutter_profile: development-linux-x86_64
@@ -239,6 +243,8 @@ jobs:
- name: Run Docker-Compose
working-directory: AppFlowy-Cloud
env:
BACKEND_VERSION: 0.3.24-amd64
run: |
docker compose down -v --remove-orphans
docker compose pull
@@ -299,12 +305,12 @@ jobs:
# split the integration tests into different machines to minimize the time
integration_test_1:
needs: [prepare-linux]
needs: [ prepare-linux ]
if: github.event.pull_request.draft != true
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
os: [ ubuntu-latest ]
include:
- os: ubuntu-latest
target: 'x86_64-unknown-linux-gnu'
@@ -323,12 +329,12 @@ jobs:
rust_target: ${{ matrix.target }}
integration_test_2:
needs: [prepare-linux]
needs: [ prepare-linux ]
if: github.event.pull_request.draft != true
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
os: [ ubuntu-latest ]
include:
- os: ubuntu-latest
target: 'x86_64-unknown-linux-gnu'
@@ -347,12 +353,12 @@ jobs:
rust_target: ${{ matrix.target }}
integration_test_3:
needs: [prepare-linux]
needs: [ prepare-linux ]
if: github.event.pull_request.draft != true
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
os: [ ubuntu-latest ]
include:
- os: ubuntu-latest
target: 'x86_64-unknown-linux-gnu'
+17 -5
View File
@@ -8,6 +8,7 @@ on:
- ".github/workflows/mobile_ci.yaml"
- "frontend/**"
- "!frontend/appflowy_tauri/**"
- "!frontend/appflowy_web_app/**"
pull_request:
branches:
@@ -16,10 +17,11 @@ on:
- ".github/workflows/mobile_ci.yaml"
- "frontend/**"
- "!frontend/appflowy_tauri/**"
- "!frontend/appflowy_web_app/**"
env:
FLUTTER_VERSION: "3.19.0"
RUST_TOOLCHAIN: "1.75"
RUST_TOOLCHAIN: "1.77.2"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -31,7 +33,7 @@ jobs:
strategy:
fail-fast: true
matrix:
os: [macos-14]
os: [ macos-14 ]
runs-on: ${{ matrix.os }}
steps:
@@ -86,6 +88,16 @@ jobs:
model: 'iPhone 15'
shutdown_after_job: false
- name: Run integration tests
working-directory: frontend/appflowy_flutter
run: flutter test integration_test/runner.dart -d ${{ steps.simulator-action.outputs.udid }}
# - name: Run AppFlowy on simulator
# working-directory: frontend/appflowy_flutter
# run: |
# flutter run -d ${{ steps.simulator-action.outputs.udid }} &
# pid=$!
# sleep 500
# kill $pid
# continue-on-error: true
# 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 }}
+25
View File
@@ -0,0 +1,25 @@
name: Ninja i18n action
on:
pull_request_target:
# explicitly configure permissions, in case your GITHUB_TOKEN workflow permissions are set to read-only in repository settings
permissions:
pull-requests: write
jobs:
ninja-i18n:
name: Ninja i18n - GitHub Lint Action
runs-on: ubuntu-latest
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
- name: Run Ninja i18n
id: ninja-i18n
uses: opral/ninja-i18n-action@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+15 -20
View File
@@ -7,7 +7,7 @@ on:
env:
FLUTTER_VERSION: "3.19.0"
RUST_TOOLCHAIN: "1.75"
RUST_TOOLCHAIN: "1.77.2"
jobs:
create-release:
@@ -54,13 +54,6 @@ jobs:
- name: Checkout source code
uses: actions/checkout@v4
- name: Export pub environment variable on Windows
run: |
if [ "$RUNNER_OS" == "Windows" ]; then
echo "PUB_CACHE=$LOCALAPPDATA\\Pub\\Cache" >> $GITHUB_ENV
fi
shell: bash
- name: Install flutter
uses: subosito/flutter-action@v2
with:
@@ -239,10 +232,10 @@ jobs:
matrix:
job:
- {
targets: "aarch64-apple-darwin,x86_64-apple-darwin",
os: macos-11,
extra-build-args: "",
}
targets: "aarch64-apple-darwin,x86_64-apple-darwin",
os: macos-11,
extra-build-args: "",
}
steps:
- name: Checkout source code
uses: actions/checkout@v4
@@ -336,18 +329,19 @@ jobs:
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
matrix:
job:
- {
arch: x86_64,
target: x86_64-unknown-linux-gnu,
os: ubuntu-20.04,
extra-build-args: "",
flutter_profile: production-linux-x86_64,
}
arch: x86_64,
target: x86_64-unknown-linux-gnu,
os: ubuntu-20.04,
extra-build-args: "",
flutter_profile: production-linux-x86_64,
}
steps:
- name: Checkout source code
uses: actions/checkout@v4
@@ -412,7 +406,8 @@ jobs:
continue-on-error: true
run: |
sh scripts/linux_distribution/appimage/build_appimage.sh ${{ github.ref_name }}
cp -r ${{ env.LINUX_PACKAGE_TMP_APPIMAGE_NAME }} ${{ env.LINUX_PACKAGE_APPIMAGE_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
@@ -422,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
+20 -17
View File
@@ -19,27 +19,27 @@ on:
env:
CARGO_TERM_COLOR: always
RUST_TOOLCHAIN: "1.75"
RUST_TOOLCHAIN: "1.77.2"
jobs:
test-on-ubuntu:
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: 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@v4
@@ -81,6 +81,8 @@ jobs:
- name: Run Docker-Compose
working-directory: AppFlowy-Cloud
env:
BACKEND_VERSION: 0.3.24-amd64
run: |
docker pull appflowyinc/appflowy_cloud:latest
docker compose up -d
@@ -93,7 +95,8 @@ jobs:
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: cargo test --no-default-features --features="rev-sqlite,dart" -- --nocapture
run: |
DISABLE_CI_TEST_LOG="true" cargo test --no-default-features --features="dart"
- name: rustfmt rust-lib
run: cargo fmt --all -- --check
+1 -1
View File
@@ -11,7 +11,7 @@ on:
env:
CARGO_TERM_COLOR: always
FLUTTER_VERSION: "3.19.0"
RUST_TOOLCHAIN: "1.75"
RUST_TOOLCHAIN: "1.77.2"
jobs:
tests:
+113
View File
@@ -0,0 +1,113 @@
name: Tauri-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.77.2"
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"
+9 -11
View File
@@ -1,16 +1,13 @@
name: Tauri-CI
on:
pull_request:
paths:
- ".github/workflows/tauri_ci.yaml"
- "frontend/rust-lib/**"
- "frontend/appflowy_tauri/**"
- "frontend/resources/**"
push:
branches:
- build/tauri
env:
NODE_VERSION: "18.16.0"
PNPM_VERSION: "8.5.0"
RUST_TOOLCHAIN: "1.75"
RUST_TOOLCHAIN: "1.77.2"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -22,7 +19,7 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest]
platform: [ ubuntu-20.04 ]
runs-on: ${{ matrix.platform }}
@@ -32,7 +29,7 @@ jobs:
- uses: actions/checkout@v4
- name: Maximize build space (ubuntu only)
if: matrix.platform == 'ubuntu-latest'
if: matrix.platform == 'ubuntu-20.04'
run: |
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
@@ -80,7 +77,7 @@ jobs:
vcpkg integrate install
- name: install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-latest'
if: matrix.platform == 'ubuntu-20.04'
working-directory: frontend
run: |
sudo apt-get update
@@ -110,4 +107,5 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tauriScript: pnpm tauri
projectPath: frontend/appflowy_tauri
projectPath: frontend/appflowy_tauri
args: "--debug"
+6 -6
View File
@@ -14,7 +14,7 @@ on:
env:
NODE_VERSION: "18.16.0"
PNPM_VERSION: "8.5.0"
RUST_TOOLCHAIN: "1.75"
RUST_TOOLCHAIN: "1.77.2"
jobs:
@@ -31,7 +31,7 @@ jobs:
- platform: macos-latest
args: "--target x86_64-apple-darwin"
target: "macos-x86_64"
- platform: ubuntu-latest
- platform: ubuntu-20.04
args: "--target x86_64-unknown-linux-gnu"
target: "linux-x86_64"
@@ -46,7 +46,7 @@ jobs:
ref: ${{ github.event.inputs.branch }}
- name: Maximize build space (ubuntu only)
if: matrix.settings.platform == 'ubuntu-latest'
if: matrix.settings.platform == 'ubuntu-20.04'
run: |
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
@@ -88,7 +88,7 @@ jobs:
vcpkg integrate install
- name: install dependencies (ubuntu only)
if: matrix.settings.platform == 'ubuntu-latest'
if: matrix.settings.platform == 'ubuntu-20.04'
working-directory: frontend
run: |
sudo apt-get update
@@ -140,14 +140,14 @@ jobs:
- name: Upload Deb package(ubuntu only)
uses: actions/upload-artifact@v4
if: matrix.settings.platform == 'ubuntu-latest'
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-latest'
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
+75
View File
@@ -0,0 +1,75 @@
name: Web-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-20.04 ]
runs-on: ${{ matrix.platform }}
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: 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
pnpm run test:unit
- 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
+8 -9
View File
@@ -1,19 +1,18 @@
name: WEB-CI
on:
pull_request:
branches:
- "main"
paths:
- ".github/workflows/web_ci.yaml"
- "frontend/rust-lib/**"
- "frontend/appflowy_web/**"
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"
RUST_TOOLCHAIN: "1.77.2"
CARGO_MAKE_VERSION: "0.36.6"
jobs:
@@ -22,7 +21,7 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest]
platform: [ ubuntu-latest ]
runs-on: ${{ matrix.platform }}
steps:
+48
View File
@@ -0,0 +1,48 @@
name: Cypress Tests
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:
cypress-run:
if: github.event.pull_request.draft != true
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Maximize build space (ubuntu only)
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 }}
# Install pnpm dependencies, cache them correctly
# and run all Cypress tests
- name: Cypress run
uses: cypress-io/github-action@v6
with:
working-directory: frontend/appflowy_web_app
component: true
build: pnpm run build
start: pnpm run start
browser: chrome
+2
View File
@@ -40,3 +40,5 @@ frontend/package
frontend/*.deb
**/Cargo.toml.bak
**/.cargo/**
+51
View File
@@ -1,4 +1,55 @@
# Release Notes
## Version 0.5.7 - 05/10/2024
### Bug Fixes
- Resolved page opening issue on Android.
- Fixed text input inconsistency on Kanban board cards.
## Version 0.5.6 - 05/07/2024
### New Features
- Team collaboration is live! Add members to your workspace to edit and collaborate on pages together.
- Collaborate in real time on the same page with other members. Edits made by others will appear instantly.
- Create multiple workspaces for different kinds of content.
- Customize your entire page on mobile through the Page Style menu with options for layout, font, font size, emoji, and cover image.
- Open a row record as a full page.
### Bug Fixes
- Resolved issue with setting background color for the Simple Table block.
- Adjusted toolbar for various screen sizes.
- Added a request for photo permission before uploading images on mobile.
- Exported creation and last modification timestamps to CSV.
## Version 0.5.5 - 04/24/2024
### New Features
- Improved the display of code blocks with line numbers
- Added support for signing in using Magic Link
### Bug Fixes
- Fixed the database synchronization indicator issue
- Resolved the issue with opening the mentioned page on mobile
- Cleared the collaboration status when the user exits AppFlowy
## 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.
+16 -18
View File
@@ -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 🌎🗺
[![translation badge](https://inlang.com/badge?url=github.com/AppFlowy-IO/AppFlowy)](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)
+4 -1
View File
@@ -115,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
+43 -43
View File
@@ -1,16 +1,16 @@
#https://github.com/sagiegurari/cargo-make
extend = [
{ path = "scripts/makefile/desktop.toml" },
{ path = "scripts/makefile/mobile.toml" },
{ path = "scripts/makefile/protobuf.toml" },
{ path = "scripts/makefile/tests.toml" },
{ path = "scripts/makefile/docker.toml" },
{ path = "scripts/makefile/env.toml" },
{ path = "scripts/makefile/flutter.toml" },
{ path = "scripts/makefile/tool.toml" },
{ path = "scripts/makefile/tauri.toml" },
{ path = "scripts/makefile/web.toml" },
{ path = "scripts/makefile/desktop.toml" },
{ path = "scripts/makefile/mobile.toml" },
{ path = "scripts/makefile/protobuf.toml" },
{ path = "scripts/makefile/tests.toml" },
{ path = "scripts/makefile/docker.toml" },
{ path = "scripts/makefile/env.toml" },
{ path = "scripts/makefile/flutter.toml" },
{ path = "scripts/makefile/tool.toml" },
{ path = "scripts/makefile/tauri.toml" },
{ path = "scripts/makefile/web.toml" },
]
[config]
@@ -26,8 +26,8 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
CARGO_MAKE_CRATE_NAME = "dart-ffi"
LIB_NAME = "dart_ffi"
APPFLOWY_VERSION = "0.5.2"
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite"
APPFLOWY_VERSION = "0.5.7"
FLUTTER_DESKTOP_FEATURES = "dart"
PRODUCT_NAME = "AppFlowy"
MACOSX_DEPLOYMENT_TARGET = "11.0"
# CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html
@@ -50,7 +50,8 @@ 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"
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"
@@ -161,7 +162,7 @@ CRATE_TYPE = "cdylib"
FLUTTER_OUTPUT_DIR = "Debug"
LIB_EXT = "so"
LINUX_ARCH = "arm64"
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite,openssl_vendored"
FLUTTER_DESKTOP_FEATURES = "dart,openssl_vendored"
[env.production-linux-aarch64]
CARGO_PROFILE = "release"
@@ -173,7 +174,7 @@ FLUTTER_OUTPUT_DIR = "Release"
LIB_EXT = "so"
LINUX_ARCH = "arm64"
APP_ENVIRONMENT = "production"
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite,openssl_vendored"
FLUTTER_DESKTOP_FEATURES = "dart,openssl_vendored"
[env.development-ios-arm64-sim]
BUILD_FLAG = "debug"
@@ -206,7 +207,7 @@ CRATE_TYPE = "cdylib"
FLUTTER_OUTPUT_DIR = "Debug"
LIB_EXT = "so"
PRODUCT_EXT = "apk"
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite,openssl_vendored"
FLUTTER_DESKTOP_FEATURES = "dart,openssl_vendored"
[env.production-android]
BUILD_FLAG = "release"
@@ -226,33 +227,32 @@ script = ['''
echo FEATURES: ${FLUTTER_DESKTOP_FEATURES}
echo PRODUCT_EXT: ${PRODUCT_EXT}
echo APP_ENVIRONMENT: ${APP_ENVIRONMENT}
echo ${platforms}
echo ${BUILD_ARCHS}
echo ${BUILD_VERSION}
echo BUILD_ARCHS: ${BUILD_ARCHS}
echo BUILD_VERSION: ${BUILD_VERSION}
''']
script_runner = "@shell"
[tasks.setup-crate-type]
private = true
script = [
"""
toml = readfile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml
val = replace ${toml} "staticlib" ${CRATE_TYPE}
result = writefile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml ${val}
assert ${result}
""",
"""
toml = readfile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml
val = replace ${toml} "staticlib" ${CRATE_TYPE}
result = writefile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml ${val}
assert ${result}
""",
]
script_runner = "@duckscript"
[tasks.restore-crate-type]
private = true
script = [
"""
toml = readfile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml
val = replace ${toml} ${CRATE_TYPE} "staticlib"
result = writefile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml ${val}
assert ${result}
""",
"""
toml = readfile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml
val = replace ${toml} ${CRATE_TYPE} "staticlib"
result = writefile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml ${val}
assert ${result}
""",
]
script_runner = "@duckscript"
@@ -280,24 +280,24 @@ TEST_COMPILE_TARGET = "x86_64-pc-windows-msvc"
[tasks.setup-test-crate-type]
private = true
script = [
"""
toml = readfile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml
val = replace ${toml} "staticlib" ${TEST_CRATE_TYPE}
result = writefile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml ${val}
assert ${result}
""",
"""
toml = readfile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml
val = replace ${toml} "staticlib" ${TEST_CRATE_TYPE}
result = writefile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml ${val}
assert ${result}
""",
]
script_runner = "@duckscript"
[tasks.restore-test-crate-type]
private = true
script = [
"""
toml = readfile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml
val = replace ${toml} ${TEST_CRATE_TYPE} "staticlib"
result = writefile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml ${val}
assert ${result}
""",
"""
toml = readfile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml
val = replace ${toml} ${TEST_CRATE_TYPE} "staticlib"
result = writefile ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/${CARGO_MAKE_CRATE_NAME}/Cargo.toml ${val}
assert ${result}
""",
]
script_runner = "@duckscript"
@@ -52,7 +52,7 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "io.appflowy.appflowy"
minSdkVersion 29
minSdkVersion 23
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
@@ -47,6 +47,12 @@
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permission to read files from external storage (outside application container).
As of Android 12 this permission no longer has any effect. Instead use the
READ_MEDIA_IMAGES, READ_MEDIA_VIDEO or READM_MEDIA_AUDIO permissions. -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<!-- Permissions to read media files. -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<queries>
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
@@ -11,6 +11,12 @@ file(COPY
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
@@ -11,6 +11,8 @@ const uint8_t *sync_event(const uint8_t *input, uintptr_t len);
int32_t set_stream_port(int64_t port);
int32_t set_log_stream_port(int64_t port);
void link_me_please(void);
void rust_log(int64_t level, const char *data);
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 731 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 KiB

@@ -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 |
@@ -1,21 +1,30 @@
// ignore_for_file: unused_import
import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/flowy_svgs.g.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/pages/settings_account_view.dart';
import 'package:appflowy/workspace/presentation/settings/shared/settings_body.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:flowy_infra_ui/style_widget/text_field.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:path/path.dart' as p;
import 'package:integration_test/integration_test.dart';
import 'package:intl/intl.dart';
import 'package:path/path.dart' as p;
import '../desktop/board/board_hide_groups_test.dart';
import '../shared/dir.dart';
import '../shared/mock/mock_file_picker.dart';
import '../shared/util.dart';
@@ -30,27 +39,40 @@ void main() {
);
tester.expectToSeeText(LocaleKeys.signIn_loginStartWithAnonymous.tr());
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
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.openSettingsPage(SettingsPage.account);
await tester.pumpAndSettle();
await tester.enterUserName('local_user');
// Scroll to sign-in
await tester.scrollUntilVisible(
find.byType(SignInOutButton),
100,
scrollable: find.findSettingsScrollable(),
);
await tester.tapButton(find.byType(SignInOutButton));
// sign up with Google
await tester.tapGoogleLoginInButton();
// sign out
await tester.expectToSeeHomePage();
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.user);
await tester.openSettingsPage(SettingsPage.account);
// Scroll to sign-out
await tester.scrollUntilVisible(
find.byType(SignInOutButton),
100,
scrollable: find.findSettingsScrollable(),
);
await tester.logout();
await tester.pumpAndSettle();
@@ -61,8 +83,9 @@ void main() {
// New anon user name
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.user);
final userNameInput = tester.widget(userNameFinder) as UserNameInput;
await tester.openSettingsPage(SettingsPage.account);
final userNameInput =
tester.widget(find.byType(UserProfileSetting)) as UserProfileSetting;
expect(userNameInput.name, 'Me');
});
});
@@ -6,8 +6,8 @@ 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/pages/settings_account_view.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';
@@ -37,11 +37,18 @@ void main() {
// Open the setting page and sign out
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.user);
await tester.tapButton(find.byType(SettingLogoutButton));
await tester.openSettingsPage(SettingsPage.account);
tester.expectToSeeText(LocaleKeys.button_ok.tr());
await tester.tapButtonWithName(LocaleKeys.button_ok.tr());
// Scroll to sign-out
await tester.scrollUntilVisible(
find.byType(SignInOutButton),
100,
scrollable: find.findSettingsScrollable(),
);
await tester.tapButton(find.byType(SignInOutButton));
tester.expectToSeeText(LocaleKeys.button_confirm.tr());
await tester.tapButtonWithName(LocaleKeys.button_confirm.tr());
// Go to the sign in page again
await tester.pumpAndSettle(const Duration(seconds: 1));
@@ -56,7 +63,16 @@ void main() {
// should not see the sync setting page when sign in as anonymous
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.user);
await tester.openSettingsPage(SettingsPage.account);
// Scroll to sign-in
await tester.scrollUntilVisible(
find.byType(SignInOutButton),
100,
scrollable: find.findSettingsScrollable(),
);
await tester.tapButton(find.byType(SignInOutButton));
tester.expectToSeeGoogleLoginButton();
});
@@ -1,9 +1,12 @@
import 'anon_user_continue_test.dart' as anon_user_continue_test;
import 'appflowy_cloud_auth_test.dart' as appflowy_cloud_auth_test;
import 'collaborative_workspace_test.dart' as collaboration_workspace_test;
import 'empty_test.dart' as preset_af_cloud_env_test;
// import 'document_sync_test.dart' as document_sync_test;
import 'user_setting_sync_test.dart' as user_sync_test;
import '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();
@@ -16,5 +19,7 @@ Future<void> main() async {
anon_user_continue_test.main();
// workspace
collaboration_workspace_test.main();
change_workspace_name_and_icon_test.main();
}
@@ -8,14 +8,15 @@ 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/pages/settings_account_view.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 'package:path/path.dart' as p;
import '../shared/dir.dart';
import '../shared/mock/mock_file_picker.dart';
import '../shared/util.dart';
@@ -50,7 +51,7 @@ void main() {
await tester.waitForSeconds(6);
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.user);
await tester.openSettingsPage(SettingsPage.account);
await tester.logout();
});
@@ -1,9 +1,7 @@
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/application/settings/prelude.dart';
import 'package:appflowy/workspace/presentation/settings/pages/settings_account_view.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/setting_supabase_cloud.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
@@ -25,11 +23,8 @@ void main() {
// 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());
await tester.openSettingsPage(SettingsPage.account);
await tester.logout();
// Go to the sign in page again
await tester.pumpAndSettle(const Duration(seconds: 1));
@@ -42,7 +37,16 @@ void main() {
// should not see the sync setting page when sign in as anonymous
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.user);
await tester.openSettingsPage(SettingsPage.account);
// Scroll to sign-out
await tester.scrollUntilVisible(
find.byType(SignInOutButton),
100,
scrollable: find.findSettingsScrollable(),
);
await tester.tapButton(find.byType(SignInOutButton));
tester.expectToSeeGoogleLoginButton();
});
@@ -2,22 +2,27 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/flowy_svgs.g.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/pages/settings_account_view.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:flowy_infra_ui/style_widget/text_field.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:path/path.dart' as p;
import 'package:integration_test/integration_test.dart';
import 'package:path/path.dart' as p;
import '../desktop/board/board_hide_groups_test.dart';
import '../shared/database_test_op.dart';
import '../shared/dir.dart';
import '../shared/emoji.dart';
@@ -39,28 +44,9 @@ void main() {
await tester.expectToSeeHomePageWithGetStartedPage();
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.user);
// final userAvatarFinder = find.descendant(
// of: find.byType(SettingsUserView),
// matching: find.byType(UserAvatar),
// );
await tester.openSettingsPage(SettingsPage.account);
// 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.enterUserName(name);
await tester.tapEscButton();
// wait 2 seconds for the sync to finish
@@ -78,23 +64,12 @@ void main() {
await tester.pumpAndSettle();
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.user);
await tester.openSettingsPage(SettingsPage.account);
// 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 profileSetting =
tester.widget(find.byType(UserProfileSetting)) as UserProfileSetting;
// 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);
expect(profileSetting.name, name);
});
}
@@ -0,0 +1,80 @@
// 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: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);
});
}
@@ -2,8 +2,11 @@
import 'dart:io';
import 'package:flutter/material.dart';
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';
@@ -13,21 +16,19 @@ import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_worksp
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';
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();
@@ -35,14 +36,14 @@ void main() {
final email = '${uuid()}@appflowy.io';
group('collaborative workspace', () {
// only run the test when the feature flag is on
if (!FeatureFlag.collaborativeWorkspace.isOn) {
return;
}
// combine the create and delete workspace test to reduce the time
testWidgets('create a new workspace, open it and then delete it',
(tester) async {
// only run the test when the feature flag is on
if (!FeatureFlag.collaborativeWorkspace.isOn) {
return;
}
await tester.initializeAppFlowy(
cloudType: AuthenticatorType.appflowyCloudSelfHost,
email: email,
@@ -51,32 +52,23 @@ void main() {
await tester.expectToSeeHomePageWithGetStartedPage();
const name = 'AppFlowy.IO';
// the workspace will be opened after created
await tester.createCollaborativeWorkspace(name);
// see the success message
var success = find.text(LocaleKeys.workspace_createSuccess.tr());
expect(success, findsOneWidget);
await tester.pumpUntilNotFound(success);
final loading = find.byType(Loading);
await tester.pumpUntilNotFound(loading);
// check the create result
Finder success;
// delete the newly created workspace
await tester.openCollaborativeWorkspaceMenu();
var items = find.byType(WorkspaceMenuItem);
final Finder items = find.byType(WorkspaceMenuItem);
expect(items, findsNWidgets(2));
expect(
tester.widget<WorkspaceMenuItem>(items.last).workspace.name,
name,
);
// open the newly created workspace
await tester.tapButton(items.last);
success = find.text(LocaleKeys.workspace_openSuccess.tr());
expect(success, findsOneWidget);
await tester.pumpUntilNotFound(success);
await tester.closeCollaborativeWorkspaceMenu();
// delete the newly created workspace
await tester.openCollaborativeWorkspaceMenu();
final secondWorkspace = find.byType(WorkspaceMenuItem).last;
await tester.hoverOnWidget(
secondWorkspace,
@@ -96,20 +88,11 @@ void main() {
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);
},
);
// check the result
await tester.openCollaborativeWorkspaceMenu();
items = find.byType(WorkspaceMenuItem);
expect(items, findsOneWidget);
expect(
tester.widget<WorkspaceMenuItem>(items.last).workspace.name != name,
true,
);
await tester.closeCollaborativeWorkspaceMenu();
});
});
}
@@ -1,6 +1,6 @@
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/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:flutter/material.dart';
@@ -18,17 +18,19 @@ void main() {
group('board add row test:', () {
testWidgets('from header', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
final findFirstCard = find.descendant(
of: find.byType(AppFlowyGroupCard),
matching: find.byType(Text),
);
final firstCard = find.byType(RowCard).first;
Text firstCardText = tester.firstWidget(findFirstCard);
expect(firstCardText.data, defaultFirstCardName);
expect(
find.descendant(
of: firstCard,
matching: find.text(defaultFirstCardName),
),
findsOneWidget,
);
await tester.tap(
find
@@ -45,7 +47,7 @@ void main() {
const newCardName = 'Card 4';
await tester.enterText(
find.descendant(
of: find.byType(RowCardContainer),
of: firstCard,
matching: find.byType(TextField),
),
newCardName,
@@ -55,23 +57,30 @@ void main() {
await tester.tap(find.byType(AppFlowyBoard));
await tester.pumpAndSettle();
firstCardText = tester.firstWidget(findFirstCard);
expect(firstCardText.data, newCardName);
expect(
find.descendant(
of: find.byType(RowCard).first,
matching: find.text(newCardName),
),
findsOneWidget,
);
});
testWidgets('from footer', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
final findLastCard = find.descendant(
of: find.byType(AppFlowyGroupCard),
matching: find.byType(Text),
);
final lastCard = find.byType(RowCard).last;
Text? lastCardText = tester.widgetList(findLastCard).last as Text;
expect(lastCardText.data, defaultLastCardName);
expect(
find.descendant(
of: lastCard,
matching: find.text(defaultLastCardName),
),
findsOneWidget,
);
await tester.tap(
find
@@ -81,12 +90,11 @@ void main() {
)
.at(1),
);
await tester.pumpAndSettle();
const newCardName = 'Card 4';
await tester.enterText(
find.descendant(
of: find.byType(RowCardContainer),
of: lastCard,
matching: find.byType(TextField),
),
newCardName,
@@ -96,8 +104,13 @@ void main() {
await tester.tap(find.byType(AppFlowyBoard));
await tester.pumpAndSettle();
lastCardText = tester.widgetList(findLastCard).last as Text;
expect(lastCardText.data, newCardName);
expect(
find.descendant(
of: find.byType(RowCard).last,
matching: find.text(newCardName),
),
findsOneWidget,
);
});
});
}
@@ -1,10 +1,10 @@
import 'package:appflowy/plugins/database/widgets/card/card.dart';
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';
@@ -15,12 +15,12 @@ void main() {
testWidgets('move row to another group', (tester) async {
const card1Name = 'Card 1';
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
final card1 = find.ancestor(
of: find.text(card1Name),
matching: find.byType(AppFlowyGroupCard),
matching: find.byType(RowCard),
);
final doingGroup = find.text('Doing');
final doingGroupCenter = tester.getCenter(doingGroup);
@@ -16,7 +16,7 @@ void main() {
group('board group options:', () {
testWidgets('expand/collapse hidden groups', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
final collapseFinder = find.byFlowySvg(FlowySvgs.pull_left_outlined_s);
@@ -45,7 +45,7 @@ void main() {
testWidgets('hide first group, and show it again', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
// Tap the options of the first group
@@ -81,7 +81,7 @@ void main() {
testWidgets('delete a group', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
expect(tester.widgetList(find.byType(BoardColumnHeader)).length, 4);
@@ -7,8 +7,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../../shared/util.dart';
import '../../shared/database_test_op.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
@@ -16,7 +16,7 @@ void main() {
group('board row test', () {
testWidgets('delete item in ToDo card', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
const name = 'Card 1';
@@ -34,7 +34,7 @@ void main() {
testWidgets('duplicate item in ToDo card', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
const name = 'Card 1';
@@ -52,7 +52,7 @@ void main() {
testWidgets('add new group', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Board);
// assert number of groups
@@ -0,0 +1,22 @@
import 'package:appflowy/workspace/presentation/command_palette/command_palette.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('Command Palette', () {
testWidgets('Toggle command palette', (tester) async {
await tester.initializeAppFlowy();
await tester.tapAnonymousSignInButton();
await tester.toggleCommandPalette();
expect(find.byType(CommandPaletteModal), findsOneWidget);
await tester.toggleCommandPalette();
expect(find.byType(CommandPaletteModal), findsNothing);
});
});
}
@@ -0,0 +1,14 @@
import 'package:integration_test/integration_test.dart';
import 'command_palette_test.dart' as command_palette_test;
import 'folder_search_test.dart' as folder_search_test;
import 'recent_history_test.dart' as recent_history_test;
void startTesting() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
// Command Palette integration tests
command_palette_test.main();
folder_search_test.main();
recent_history_test.main();
}
@@ -0,0 +1,53 @@
import 'package:appflowy/workspace/presentation/command_palette/command_palette.dart';
import 'package:appflowy/workspace/presentation/command_palette/widgets/search_field.dart';
import 'package:appflowy/workspace/presentation/command_palette/widgets/search_result_tile.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';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('Folder Search', () {
testWidgets('Search for views', (tester) async {
const firstDocument = "ViewOne";
const secondDocument = "ViewOna";
await tester.initializeAppFlowy();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(name: firstDocument);
await tester.createNewPageWithNameUnderParent(name: secondDocument);
await tester.toggleCommandPalette();
expect(find.byType(CommandPaletteModal), findsOneWidget);
final searchFieldFinder = find.descendant(
of: find.byType(SearchField),
matching: find.byType(FlowyTextField),
);
await tester.enterText(searchFieldFinder, secondDocument);
await tester.pumpAndSettle(const Duration(milliseconds: 200));
// Expect two search results "ViewOna" and "ViewOne" (Distance 1 to ViewOna)
expect(find.byType(SearchResultTile), findsNWidgets(2));
// The score should be higher for "ViewOna" thus it should be shown first
final secondDocumentWidget = tester
.widget(find.byType(SearchResultTile).first) as SearchResultTile;
expect(secondDocumentWidget.result.data, secondDocument);
// Change search to "ViewOne"
await tester.enterText(searchFieldFinder, firstDocument);
await tester.pumpAndSettle(const Duration(seconds: 1));
// The score should be higher for "ViewOne" thus it should be shown first
final firstDocumentWidget = tester
.widget(find.byType(SearchResultTile).first) as SearchResultTile;
expect(firstDocumentWidget.result.data, firstDocument);
});
});
}
@@ -0,0 +1,38 @@
import 'package:appflowy/workspace/presentation/command_palette/command_palette.dart';
import 'package:appflowy/workspace/presentation/command_palette/widgets/recent_view_tile.dart';
import 'package:appflowy/workspace/presentation/command_palette/widgets/recent_views_list.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('Recent History', () {
testWidgets('Search for views', (tester) async {
const firstDocument = "First";
const secondDocument = "Second";
await tester.initializeAppFlowy();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(name: firstDocument);
await tester.createNewPageWithNameUnderParent(name: secondDocument);
await tester.toggleCommandPalette();
expect(find.byType(CommandPaletteModal), findsOneWidget);
// Expect history list
expect(find.byType(RecentViewsList), findsOneWidget);
// Expect three recent history items
expect(find.byType(RecentViewTile), findsNWidgets(3));
// Expect the first item to be the last viewed document
final firstDocumentWidget =
tester.widget(find.byType(RecentViewTile).first) as RecentViewTile;
expect(firstDocumentWidget.view.name, secondDocument);
});
});
}
@@ -14,7 +14,7 @@ void main() {
group('calendar', () {
testWidgets('update calendar layout', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(
layout: ViewLayoutPB.Calendar,
@@ -36,7 +36,7 @@ void main() {
testWidgets('calendar start from day setting', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create calendar view
const name = 'calendar';
@@ -69,7 +69,7 @@ void main() {
testWidgets('creating and editing calendar events', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create the calendar view
await tester.createNewPageWithNameUnderParent(
@@ -153,7 +153,7 @@ void main() {
const customTitle = "EventTitleCustom";
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create the calendar view
await tester.createNewPageWithNameUnderParent(
@@ -194,7 +194,7 @@ void main() {
testWidgets('rescheduling events', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create the calendar view
await tester.createNewPageWithNameUnderParent(
@@ -13,7 +13,7 @@ void main() {
group('edit grid cell:', () {
testWidgets('text', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -36,7 +36,7 @@ void main() {
// multiple text cell
testWidgets('multiple text cells', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(
name: 'my grid',
layout: ViewLayoutPB.Grid,
@@ -74,7 +74,7 @@ void main() {
testWidgets('number', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -132,7 +132,7 @@ void main() {
testWidgets('checkbox', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -150,7 +150,7 @@ void main() {
testWidgets('created time', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -168,7 +168,7 @@ void main() {
testWidgets('last modified time', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -186,7 +186,7 @@ void main() {
testWidgets('date time', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -282,7 +282,7 @@ void main() {
testWidgets('single select', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
const fieldType = FieldType.SingleSelect;
@@ -361,7 +361,7 @@ void main() {
];
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -444,7 +444,7 @@ void main() {
testWidgets('checklist', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -13,7 +13,7 @@ void main() {
group('database field settings', () {
testWidgets('field visibility', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
await tester.tapCreateLinkedDatabaseViewButton(DatabaseLayoutPB.Grid);
@@ -1,5 +1,5 @@
import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/header/type_option/select/select_option.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';
@@ -17,7 +17,7 @@ void main() {
group('grid field editor:', () {
testWidgets('rename existing field', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -34,7 +34,7 @@ void main() {
testWidgets('update field type of existing field', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -50,7 +50,7 @@ void main() {
testWidgets('create a field and rename it', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new grid
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -65,7 +65,7 @@ void main() {
testWidgets('delete field', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -85,7 +85,7 @@ void main() {
testWidgets('duplicate field', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -105,7 +105,7 @@ void main() {
testWidgets('insert field on either side of a field', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -128,7 +128,7 @@ void main() {
testWidgets('create checklist field', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -148,7 +148,7 @@ void main() {
testWidgets('create list of fields', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -180,7 +180,7 @@ void main() {
testWidgets('field types with empty type option editor', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -212,7 +212,7 @@ void main() {
testWidgets('number field type option', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
await tester.scrollToRight(find.byType(GridPage));
@@ -258,7 +258,7 @@ void main() {
testWidgets('add option', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(
layout: ViewLayoutPB.Grid,
@@ -286,7 +286,7 @@ void main() {
testWidgets('date time field type options', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
await tester.scrollToRight(find.byType(GridPage));
@@ -327,69 +327,70 @@ void main() {
);
});
testWidgets('last modified and created at field type options',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
// 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();
// 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 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();
// // 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();
// // get time just before modifying
// final modified = DateTime.now();
// create a last modified field (cont'd)
await tester.selectFieldType(FieldType.LastEditedTime);
await tester.dismissFieldEditor();
// // 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),
);
// 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.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();
// // 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),
);
});
// // 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),
// );
// });
});
}
@@ -14,7 +14,7 @@ void main() {
group('reminder in database', () {
testWidgets('add date field and add reminder', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -68,7 +68,7 @@ void main() {
testWidgets('navigate from reminder to open row', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -135,7 +135,7 @@ void main() {
'toggle include time sets reminder option correctly',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(
layout: ViewLayoutPB.Grid,
@@ -1,9 +1,10 @@
import 'package:flutter/material.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-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';
@@ -17,7 +18,7 @@ void main() {
group('grid row detail page:', () {
testWidgets('opens', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create a new grid
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -34,7 +35,7 @@ void main() {
testWidgets('add emoji', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create a new grid
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -53,7 +54,7 @@ void main() {
testWidgets('update emoji', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create a new grid
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -80,7 +81,7 @@ void main() {
testWidgets('remove emoji', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create a new grid
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -101,7 +102,7 @@ void main() {
testWidgets('create list of fields', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create a new grid
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -135,7 +136,7 @@ void main() {
testWidgets('change order of fields and cells', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create a new grid
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -168,7 +169,7 @@ void main() {
testWidgets('hide and show hidden fields', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create a new grid
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -217,7 +218,7 @@ void main() {
testWidgets('update the contents of the document and re-open it',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create a new grid
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -257,7 +258,7 @@ void main() {
'check if the title wraps properly when a long text is inserted',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create a new grid
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -296,7 +297,7 @@ void main() {
testWidgets('delete row', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create a new grid
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -313,7 +314,7 @@ void main() {
testWidgets('duplicate row', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// Create a new grid
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -11,7 +11,7 @@ void main() {
group('grid', () {
testWidgets('create row of the grid', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
await tester.tapCreateRowButtonInGrid();
@@ -23,7 +23,7 @@ void main() {
testWidgets('create row from row menu of the grid', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -38,7 +38,7 @@ void main() {
testWidgets('delete row of the grid', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
await tester.hoverOnFirstRowOfGrid();
@@ -55,7 +55,7 @@ void main() {
testWidgets('check number of row indicator in the initial grid',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -12,7 +12,7 @@ void main() {
group('grid', () {
testWidgets('update layout', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -29,7 +29,7 @@ void main() {
testWidgets('update layout multiple times', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -12,7 +12,7 @@ void main() {
group('database', () {
testWidgets('create linked view', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -33,7 +33,7 @@ void main() {
testWidgets('rename and delete linked view', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -58,7 +58,7 @@ void main() {
testWidgets('delete the last database view', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -14,7 +14,7 @@ void main() {
group('document alignment', () {
testWidgets('edit alignment in toolbar', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
final selection = Selection.single(
path: [0],
@@ -48,7 +48,7 @@ void main() {
testWidgets('edit alignment using shortcut', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// click the first line of the readme
await tester.editor.tapLineOfEditorAt(0);
@@ -1,9 +1,10 @@
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy_editor/appflowy_editor.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';
@@ -15,7 +16,7 @@ void main() {
group('paste in codeblock', () {
testWidgets('paste multiple lines in codeblock', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document
await tester.createNewPageWithNameUnderParent();
@@ -23,11 +24,7 @@ void main() {
// mock the clipboard
const lines = 3;
final text = List.generate(lines, (index) => 'line $index').join('\n');
AppFlowyClipboard.mockSetData(
AppFlowyClipboardData(
text: text,
),
);
AppFlowyClipboard.mockSetData(AppFlowyClipboardData(text: text));
await insertCodeBlockInDocument(tester);
@@ -106,58 +106,13 @@ void main() {
expect(node2.type, ParagraphBlockKeys.type);
expect(node3.type, ParagraphBlockKeys.type);
expect(node1.delta!.toJson(), [
{
"insert": "void",
"attributes": {"font_color": "0xfffede5d"},
},
{
"insert": " ",
"attributes": {"font_color": "0xffff7edb"},
},
{
"insert": "main",
"attributes": {"font_color": "0xff36f9f6"},
},
{
"insert": "() {",
"attributes": {"font_color": "0xffff7edb"},
}
{'insert': 'void main() {'},
]);
expect(node2.delta!.toJson(), [
{
"insert": " ",
"attributes": {"font_color": "0xffff7edb"},
},
{
"insert": "runApp",
"attributes": {"font_color": "0xff36f9f6"},
},
{
"insert": "(",
"attributes": {"font_color": "0xffff7edb"},
},
{
"insert": "const",
"attributes": {"font_color": "0xfffede5d"},
},
{
"insert": " ",
"attributes": {"font_color": "0xffff7edb"},
},
{
"insert": "MyApp",
"attributes": {"font_color": "0xfffe4450"},
},
{
"insert": "());",
"attributes": {"font_color": "0xffff7edb"},
}
{'insert': " runApp(const MyApp());"},
]);
expect(node3.delta!.toJson(), [
{
"insert": "}",
"attributes": {"font_color": "0xffff7edb"},
}
{"insert": "}"},
]);
});
});
@@ -304,7 +259,7 @@ extension on WidgetTester {
(String, Uint8List?)? image,
}) async {
await initializeAppFlowy();
await tapGoButton();
await tapAnonymousSignInButton();
// create a new document
await createNewPageWithNameUnderParent();
@@ -14,7 +14,7 @@ void main() {
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document
await tester.createNewPageWithNameUnderParent();
@@ -30,7 +30,7 @@ void main() {
testWidgets('delete the readme page and restore it', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// delete the readme page
await tester.hoverOnPageName(
@@ -54,7 +54,7 @@ void main() {
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// delete the readme page
await tester.hoverOnPageName(
@@ -15,7 +15,7 @@ void main() {
group('insert inline document reference', () {
testWidgets('insert by slash menu', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
final name = await createDocumentToReference(tester);
@@ -42,7 +42,7 @@ void main() {
testWidgets('insert by `[[` character shortcut', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
final name = await createDocumentToReference(tester);
@@ -62,7 +62,7 @@ void main() {
testWidgets('insert by `+` character shortcut', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
final name = await createDocumentToReference(tester);
@@ -12,7 +12,7 @@ void main() {
'click + to add a block after current selection, and click + and option key to add a block before current selection',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
var editorState = tester.editor.getCurrentEditorState();
expect(editorState.getNodeAtPath([1])?.delta?.toPlainText(), isNotEmpty);
@@ -13,7 +13,7 @@ void main() {
(tester) async {
// combine the two tests into one to avoid the time-consuming process of initializing the app
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
final selection = Selection.single(
path: [0],
@@ -16,7 +16,7 @@ void main() {
group('cover image', () {
testWidgets('document cover tests', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
tester.expectToSeeNoDocumentCover();
@@ -53,7 +53,7 @@ void main() {
testWidgets('document icon tests', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
tester.expectToSeeDocumentIcon('⭐️');
@@ -86,7 +86,7 @@ void main() {
testWidgets('icon and cover at the same time', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
tester.expectToSeeDocumentIcon('⭐️');
tester.expectToSeeNoDocumentCover();
@@ -110,7 +110,7 @@ void main() {
testWidgets('shuffle icon', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.editor.tapGettingStartedIcon();
@@ -123,7 +123,7 @@ void main() {
testWidgets('change skin tone', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.editor.tapGettingStartedIcon();
@@ -20,7 +20,7 @@ void main() {
group('database view in document', () {
testWidgets('insert a referenced grid', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await insertReferenceDatabase(tester, ViewLayoutPB.Grid);
@@ -48,7 +48,7 @@ void main() {
testWidgets('insert a referenced board', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await insertReferenceDatabase(tester, ViewLayoutPB.Board);
@@ -64,7 +64,7 @@ void main() {
testWidgets('insert a referenced calendar', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await insertReferenceDatabase(tester, ViewLayoutPB.Calendar);
@@ -80,7 +80,7 @@ void main() {
testWidgets('create a grid inside a document', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await createInlineDatabase(tester, ViewLayoutPB.Grid);
@@ -96,7 +96,7 @@ void main() {
testWidgets('create a board inside a document', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await createInlineDatabase(tester, ViewLayoutPB.Board);
@@ -112,7 +112,7 @@ void main() {
testWidgets('create a calendar inside a document', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await createInlineDatabase(tester, ViewLayoutPB.Calendar);
@@ -32,7 +32,7 @@ void main() {
group('image block in document', () {
testWidgets('insert an image from local file', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document
await tester.createNewPageWithNameUnderParent(
@@ -80,7 +80,7 @@ void main() {
testWidgets('insert an image from network', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document
await tester.createNewPageWithNameUnderParent(
@@ -133,7 +133,7 @@ void main() {
testWidgets('insert an image from unsplash', (tester) async {
await runWithNetworkImages(() async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document
await tester.createNewPageWithNameUnderParent(
@@ -16,7 +16,7 @@ void main() {
group('inline math equation in document', () {
testWidgets('insert an inline math equation', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document
await tester.createNewPageWithNameUnderParent(
@@ -61,7 +61,7 @@ void main() {
testWidgets('remove the inline math equation format', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document
await tester.createNewPageWithNameUnderParent(
@@ -13,7 +13,7 @@ void main() {
group('inline page view in document', () {
testWidgets('insert a inline page - grid', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await insertInlinePage(tester, ViewLayoutPB.Grid);
@@ -24,7 +24,7 @@ void main() {
testWidgets('insert a inline page - board', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await insertInlinePage(tester, ViewLayoutPB.Board);
@@ -35,7 +35,7 @@ void main() {
testWidgets('insert a inline page - calendar', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await insertInlinePage(tester, ViewLayoutPB.Calendar);
@@ -46,7 +46,7 @@ void main() {
testWidgets('insert a inline page - document', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await insertInlinePage(tester, ViewLayoutPB.Document);
@@ -57,7 +57,7 @@ void main() {
testWidgets('insert a inline page and rename it', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
final pageName = await insertInlinePage(tester, ViewLayoutPB.Document);
@@ -76,7 +76,7 @@ void main() {
testWidgets('insert a inline page and delete it', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
final pageName = await insertInlinePage(tester, ViewLayoutPB.Grid);
@@ -20,7 +20,7 @@ void main() {
testWidgets('insert/edit/open link', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document
await tester.createNewPageWithNameUnderParent();
@@ -19,7 +19,7 @@ void main() {
group('outline block test', () {
testWidgets('insert an outline block', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(
name: 'outline_test',
@@ -35,7 +35,7 @@ void main() {
testWidgets('insert an outline block and check if headings are visible',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(
name: 'outline_test',
@@ -91,7 +91,7 @@ void main() {
testWidgets("control the depth of outline block", (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(
name: 'outline_test',
@@ -36,7 +36,7 @@ void main() {
testWidgets('convert > to toggle list, and click the icon to close it',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document
await tester.createNewPageWithNameUnderParent();
@@ -80,7 +80,7 @@ void main() {
(tester) async {
// if the toggle list is closed, press enter key will insert a new toggle list after it
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document
await tester.createNewPageWithNameUnderParent();
@@ -117,7 +117,7 @@ void main() {
testWidgets('press enter key when the toggle list is open', (tester) async {
// if the toggle list is open, press enter key will insert a new paragraph inside it
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document
await tester.createNewPageWithNameUnderParent();
@@ -152,7 +152,7 @@ void main() {
testWidgets('clear the format if toggle list if empty', (tester) async {
// if the toggle list is open, press enter key will insert a new paragraph inside it
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document
await tester.createNewPageWithNameUnderParent();
@@ -181,7 +181,7 @@ void main() {
(tester) async {
// if the toggle list is open, press enter key will insert a new paragraph inside it
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document
await tester.createNewPageWithNameUnderParent();
@@ -13,7 +13,7 @@ void main() {
group('edit document', () {
testWidgets('redo & undo', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document called Sample
const pageName = 'Sample';
@@ -67,7 +67,7 @@ void main() {
testWidgets('write a readme document', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new document called Sample
const pageName = 'Sample';
@@ -13,7 +13,7 @@ void main() {
group('Grid Calculations', () {
testWidgets('add calculation and update cell', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -47,7 +47,7 @@ void main() {
testWidgets('add calculations and remove row', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent(layout: ViewLayoutPB.Grid);
@@ -27,7 +27,7 @@ void main() {
const time = "23:59";
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
final dateTimeSettings =
await UserSettingsBackendService().getDateTimeSettings();
@@ -76,7 +76,7 @@ void main() {
testWidgets('Add reminder for tomorrow, and navigate to it',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.editor.tapLineOfEditorAt(0);
await tester.editor.getCurrentEditorState().insertNewLine();
@@ -11,7 +11,7 @@ void main() {
group('board add row test', () {
testWidgets('Add card from header', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.notifications);
@@ -14,7 +14,7 @@ void main() {
testWidgets('select language, language changed', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.expectToSeeHomePageWithGetStartedPage();
await tester.openSettings();
@@ -15,7 +15,7 @@ void main() {
group('Rename current view item', () {
testWidgets('by F2 shortcut', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await FlowyTestKeyboard.simulateKeyDownEvent(
[LogicalKeyboardKey.f2],
@@ -1,6 +1,6 @@
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/folder/personal_folder.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';
@@ -13,10 +13,10 @@ void main() {
group('sidebar expand test', () {
bool isExpanded({required FolderCategoryType type}) {
if (type == FolderCategoryType.personal) {
if (type == FolderCategoryType.private) {
return find
.descendant(
of: find.byType(PersonalFolder),
of: find.byType(PrivateSectionFolder),
matching: find.byType(ViewItem),
)
.evaluate()
@@ -27,22 +27,22 @@ void main() {
testWidgets('first time the personal folder is expanded', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// first time is expanded
expect(isExpanded(type: FolderCategoryType.personal), true);
expect(isExpanded(type: FolderCategoryType.private), true);
// collapse the personal folder
await tester.tapButton(
find.byTooltip(LocaleKeys.sideBar_clickToHidePersonal.tr()),
find.byTooltip(LocaleKeys.sideBar_clickToHidePrivate.tr()),
);
expect(isExpanded(type: FolderCategoryType.personal), false);
expect(isExpanded(type: FolderCategoryType.private), false);
// expand the personal folder
await tester.tapButton(
find.byTooltip(LocaleKeys.sideBar_clickToHidePersonal.tr()),
find.byTooltip(LocaleKeys.sideBar_clickToHidePrivate.tr()),
);
expect(isExpanded(type: FolderCategoryType.personal), true);
expect(isExpanded(type: FolderCategoryType.private), true);
});
});
}
@@ -1,5 +1,5 @@
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_popover/appflowy_popover.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
@@ -18,7 +18,7 @@ void main() {
'Toggle favorites for views creates / removes the favorite header along with favorite views',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// no favorite folder
expect(find.byType(FavoriteFolder), findsNothing);
@@ -74,7 +74,7 @@ void main() {
'renaming a favorite view updates name under favorite header',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
const name = 'test';
await tester.favoriteViewByName(gettingStarted);
@@ -100,7 +100,7 @@ void main() {
'deleting first level favorite view removes its instance from favorite header, deleting root level views leads to removal of all favorites that are its children',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
final names = [1, 2].map((e) => 'document_$e').toList();
for (var i = 0; i < names.length; i++) {
@@ -157,7 +157,7 @@ void main() {
'view selection is synced between favorites and personal folder',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent();
await tester.favoriteViewByName(gettingStarted);
@@ -177,7 +177,7 @@ void main() {
'context menu opens up for favorites',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.createNewPageWithNameUnderParent();
await tester.favoriteViewByName(gettingStarted);
@@ -14,7 +14,7 @@ void main() {
group('Icon', () {
testWidgets('Update page icon in sidebar', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create document, board, grid and calendar views
for (final value in ViewLayoutPB.values) {
@@ -42,7 +42,7 @@ void main() {
testWidgets('Update page icon in title bar', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create document, board, grid and calendar views
for (final value in ViewLayoutPB.values) {
@@ -20,7 +20,7 @@ void main() {
group('sidebar test', () {
testWidgets('create a new page', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// create a new page
await tester.tapNewPageButton();
@@ -36,7 +36,7 @@ void main() {
testWidgets('create a new document, grid, board and calendar',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
for (final layout in ViewLayoutPB.values) {
// create a new page
@@ -74,7 +74,7 @@ void main() {
testWidgets('create some nested pages, and move them', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
final names = [1, 2, 3, 4].map((e) => 'document_$e').toList();
for (var i = 0; i < names.length; i++) {
@@ -140,7 +140,7 @@ void main() {
testWidgets('unable to move a document into a database', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
const document = 'document';
await tester.createNewPageWithNameUnderParent(
@@ -183,7 +183,7 @@ void main() {
testWidgets('unable to create a new database inside the existing one',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
const grid = 'grid';
await tester.createNewPageWithNameUnderParent(
@@ -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();
}
@@ -1,3 +1,4 @@
import 'package:appflowy/util/font_family_extension.dart';
import 'package:appflowy/workspace/application/appearance_defaults.dart';
import 'package:appflowy/workspace/application/settings/prelude.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/settings_appearance.dart';
@@ -15,7 +16,7 @@ void main() {
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.expectToSeeHomePageWithGetStartedPage();
await tester.openSettings();
@@ -47,7 +48,7 @@ void main() {
testWidgets('reset the font family', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.expectToSeeHomePageWithGetStartedPage();
await tester.openSettings();
@@ -73,7 +74,7 @@ void main() {
await tester.openSettingsPage(SettingsPage.files);
await tester.openSettingsPage(SettingsPage.appearance);
final resetButton = find.byKey(ThemeFontFamilySetting.resetButtonkey);
final resetButton = find.byKey(ThemeFontFamilySetting.resetButtonKey);
await tester.tap(resetButton);
await tester.pumpAndSettle();
@@ -82,8 +83,10 @@ void main() {
await tester.openSettingsPage(SettingsPage.appearance);
expect(
find.textContaining(DefaultAppearanceSettings.kDefaultFontFamily),
findsOneWidget,
find.textContaining(
DefaultAppearanceSettings.kDefaultFontFamily.fontFamilyDisplayName,
),
findsNWidgets(2),
);
});
});
@@ -17,7 +17,7 @@ void main() {
testWidgets('cmd/ctrl+alt+e shortcut opens the emoji picker',
(tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
final Finder editor = find.byType(AppFlowyEditor);
await tester.tap(editor);
@@ -10,7 +10,7 @@ void main() {
group('Empty', () {
testWidgets('toggle theme mode', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
});
});
}
@@ -19,7 +19,7 @@ void main() {
testWidgets('toggle theme mode', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.expectToSeeHomePageWithGetStartedPage();
await tester.openSettings();
@@ -71,7 +71,7 @@ void main() {
testWidgets('show or hide home menu', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
await tester.expectToSeeHomePageWithGetStartedPage();
await tester.pumpAndSettle();
@@ -1,5 +1,6 @@
import 'dart:io';
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';
@@ -14,7 +15,7 @@ void main() {
group('import files', () {
testWidgets('import multiple markdown files', (tester) async {
final context = await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// expect to see a getting started page
tester.expectToSeePageName(gettingStarted);
@@ -44,5 +45,50 @@ void main() {
tester.expectToSeePageName('test1');
tester.expectToSeePageName('test2');
});
testWidgets('import markdown file with table', (tester) async {
final context = await tester.initializeAppFlowy();
await tester.tapAnonymousSignInButton();
// expect to see a getting started page
tester.expectToSeePageName(gettingStarted);
await tester.tapAddViewButton();
await tester.tapImportButton();
const testFileName = 'markdown_with_table.md';
final paths = <String>[];
final str = await rootBundle.loadString(
'assets/test/workspaces/markdowns/$testFileName',
);
final path = p.join(context.applicationDataDirectory, testFileName);
paths.add(path);
File(path).writeAsStringSync(str);
// mock get files
mockPickFilePaths(
paths: paths,
);
await tester.tapTextAndMarkdownButton();
tester.expectToSeePageName('markdown_with_table');
// expect to see all content of markdown file along with table
await tester.openPage('markdown_with_table');
final importedPageEditorState = tester.editor.getCurrentEditorState();
expect(
importedPageEditorState.getNodeAtPath([0])!.type,
HeadingBlockKeys.type,
);
expect(
importedPageEditorState.getNodeAtPath([2])!.type,
HeadingBlockKeys.type,
);
expect(
importedPageEditorState.getNodeAtPath([4])!.type,
TableBlockKeys.type,
);
});
});
}
@@ -14,7 +14,7 @@ void main() {
group('share markdown in document page', () {
testWidgets('click the share button in document page', (tester) async {
final context = await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// mock the file picker
final path = await mockSaveFilePath(
@@ -38,7 +38,7 @@ void main() {
'share the markdown after renaming the document name',
(tester) async {
final context = await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// expect to see a getting started page
tester.expectToSeePageName(gettingStarted);
@@ -5,9 +5,7 @@ import 'package:appflowy/startup/tasks/prelude.dart';
import 'package:appflowy/workspace/application/settings/prelude.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() {
@@ -18,85 +16,85 @@ void main() {
return;
}
testWidgets('switch to B from A, then switch to A again', (tester) async {
const userA = 'UserA';
const userB = 'UserB';
// testWidgets('switch to B from A, then switch to A again', (tester) async {
// const userA = 'UserA';
// const userB = 'UserB';
final initialPath = p.join(userA, appFlowyDataFolder);
final context = await tester.initializeAppFlowy(
pathExtension: initialPath,
);
// remove the last extension
final rootPath = context.applicationDataDirectory.replaceFirst(
initialPath,
'',
);
// final initialPath = p.join(userA, appFlowyDataFolder);
// final context = await tester.initializeAppFlowy(
// pathExtension: initialPath,
// );
// // remove the last extension
// final rootPath = context.applicationDataDirectory.replaceFirst(
// initialPath,
// '',
// );
await tester.tapGoButton();
await tester.expectToSeeHomePageWithGetStartedPage();
// await tester.tapGoButton();
// await tester.expectToSeeHomePageWithGetStartedPage();
// switch to user B
{
// set user name for userA
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.user);
await tester.enterUserName(userA);
// // switch to user B
// {
// // set user name for userA
// await tester.openSettings();
// await tester.openSettingsPage(SettingsPage.user);
// await tester.enterUserName(userA);
await tester.openSettingsPage(SettingsPage.files);
await tester.pumpAndSettle();
// await tester.openSettingsPage(SettingsPage.files);
// await tester.pumpAndSettle();
// mock the file_picker result
await mockGetDirectoryPath(
p.join(rootPath, userB),
);
await tester.tapCustomLocationButton();
await tester.pumpAndSettle();
await tester.expectToSeeHomePageWithGetStartedPage();
// // mock the file_picker result
// await mockGetDirectoryPath(
// p.join(rootPath, userB),
// );
// await tester.tapCustomLocationButton();
// await tester.pumpAndSettle();
// await tester.expectToSeeHomePageWithGetStartedPage();
// set user name for userB
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.user);
await tester.enterUserName(userB);
}
// // set user name for userB
// await tester.openSettings();
// await tester.openSettingsPage(SettingsPage.user);
// await tester.enterUserName(userB);
// }
// switch to the userA
{
await tester.openSettingsPage(SettingsPage.files);
await tester.pumpAndSettle();
// // switch to the userA
// {
// await tester.openSettingsPage(SettingsPage.files);
// await tester.pumpAndSettle();
// mock the file_picker result
await mockGetDirectoryPath(
p.join(rootPath, userA),
);
await tester.tapCustomLocationButton();
// // mock the file_picker result
// await mockGetDirectoryPath(
// p.join(rootPath, userA),
// );
// await tester.tapCustomLocationButton();
await tester.pumpAndSettle();
await tester.expectToSeeHomePageWithGetStartedPage();
tester.expectToSeeUserName(userA);
}
// await tester.pumpAndSettle();
// await tester.expectToSeeHomePageWithGetStartedPage();
// tester.expectToSeeUserName(userA);
// }
// switch to the userB again
{
await tester.openSettings();
await tester.openSettingsPage(SettingsPage.files);
await tester.pumpAndSettle();
// // switch to the userB again
// {
// await tester.openSettings();
// await tester.openSettingsPage(SettingsPage.files);
// await tester.pumpAndSettle();
// mock the file_picker result
await mockGetDirectoryPath(
p.join(rootPath, userB),
);
await tester.tapCustomLocationButton();
// // mock the file_picker result
// await mockGetDirectoryPath(
// p.join(rootPath, userB),
// );
// await tester.tapCustomLocationButton();
await tester.pumpAndSettle();
await tester.expectToSeeHomePageWithGetStartedPage();
tester.expectToSeeUserName(userB);
}
});
// await tester.pumpAndSettle();
// await tester.expectToSeeHomePageWithGetStartedPage();
// tester.expectToSeeUserName(userB);
// }
// });
testWidgets('reset to default location', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
// home and readme document
await tester.expectToSeeHomePageWithGetStartedPage();
@@ -22,7 +22,7 @@ void main() {
group('Tabs', () {
testWidgets('Open AppFlowy and open/navigate/close tabs', (tester) async {
await tester.initializeAppFlowy();
await tester.tapGoButton();
await tester.tapAnonymousSignInButton();
expect(
find.descendant(
@@ -0,0 +1,48 @@
// ignore_for_file: unused_import
import 'dart:io';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/editor/mobile_editor_screen.dart';
import 'package:appflowy/mobile/presentation/home/home.dart';
import 'package:appflowy/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart';
import 'package:appflowy/plugins/document/document_page.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/auth/af_cloud_mock_auth_service.dart';
import 'package:appflowy/user/application/auth/auth_service.dart';
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
import 'package:appflowy/workspace/application/settings/prelude.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart';
import 'package:appflowy_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('create new page', () {
testWidgets('create document', (tester) async {
await tester.initializeAppFlowy(
cloudType: AuthenticatorType.local,
);
// click the anonymousSignInButton
final anonymousSignInButton = find.byType(SignInAnonymousButtonV2);
expect(anonymousSignInButton, findsOneWidget);
await tester.tapButton(anonymousSignInButton);
// tap the create page button
final createPageButton = find.byKey(mobileCreateNewPageButtonKey);
await tester.tapButton(createPageButton);
expect(find.byType(MobileDocumentScreen), findsOneWidget);
});
});
}
@@ -0,0 +1,139 @@
// ignore_for_file: unused_import
import 'dart:io';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/application/page_style/document_page_style_bloc.dart';
import 'package:appflowy/mobile/presentation/base/app_bar/app_bar_actions.dart';
import 'package:appflowy/mobile/presentation/base/view_page/app_bar_buttons.dart';
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet_buttons.dart';
import 'package:appflowy/mobile/presentation/home/home.dart';
import 'package:appflowy/plugins/document/presentation/editor_page.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/cover/document_immersive_cover.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/cover/document_immersive_cover_bloc.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/page_style/_page_style_layout.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/auth/af_cloud_mock_auth_service.dart';
import 'package:appflowy/user/application/auth/auth_service.dart';
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
import 'package:appflowy/workspace/application/settings/prelude.dart';
import 'package:appflowy/workspace/application/view/view_ext.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/setting_appflowy_cloud.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/dir.dart';
import '../../shared/mock/mock_file_picker.dart';
import '../../shared/util.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('document page style', () {
double getCurrentEditorFontSize() {
final editorPage = find
.byType(AppFlowyEditorPage)
.evaluate()
.single
.widget as AppFlowyEditorPage;
return editorPage.styleCustomizer
.style()
.textStyleConfiguration
.text
.fontSize!;
}
double getCurrentEditorLineHeight() {
final editorPage = find
.byType(AppFlowyEditorPage)
.evaluate()
.single
.widget as AppFlowyEditorPage;
return editorPage.styleCustomizer
.style()
.textStyleConfiguration
.text
.height!;
}
testWidgets('change font size in page style settings', (tester) async {
await tester.launchInAnonymousMode();
// click the getting start page
await tester.openPage(gettingStarted);
// click the layout button
await tester.tapButton(find.byType(MobileViewPageLayoutButton));
expect(getCurrentEditorFontSize(), PageStyleFontLayout.normal.fontSize);
// change font size from normal to large
await tester.tapSvgButton(FlowySvgs.m_font_size_large_s);
expect(getCurrentEditorFontSize(), PageStyleFontLayout.large.fontSize);
// change font size from large to small
await tester.tapSvgButton(FlowySvgs.m_font_size_small_s);
expect(getCurrentEditorFontSize(), PageStyleFontLayout.small.fontSize);
});
testWidgets('change line height in page style settings', (tester) async {
await tester.launchInAnonymousMode();
// click the getting start page
await tester.openPage(gettingStarted);
// click the layout button
await tester.tapButton(find.byType(MobileViewPageLayoutButton));
expect(
getCurrentEditorLineHeight(),
PageStyleLineHeightLayout.normal.lineHeight,
);
// change line height from normal to large
await tester.tapSvgButton(FlowySvgs.m_layout_large_s);
expect(
getCurrentEditorLineHeight(),
PageStyleLineHeightLayout.large.lineHeight,
);
// change line height from large to small
await tester.tapSvgButton(FlowySvgs.m_layout_small_s);
expect(
getCurrentEditorLineHeight(),
PageStyleLineHeightLayout.small.lineHeight,
);
});
testWidgets('use built-in image as cover', (tester) async {
await tester.launchInAnonymousMode();
// click the getting start page
await tester.openPage(gettingStarted);
// click the layout button
await tester.tapButton(find.byType(MobileViewPageLayoutButton));
// toggle the preset button
await tester.tapSvgButton(FlowySvgs.m_page_style_presets_m);
// select the first preset
final firstBuiltInImage = find.byWidgetPredicate(
(widget) =>
widget is Image &&
widget.image is AssetImage &&
(widget.image as AssetImage).assetName ==
PageStyleCoverImageType.builtInImagePath('1'),
);
await tester.tap(firstBuiltInImage);
// click done button to exit the page style settings
await tester.tapButton(find.byType(BottomSheetDoneButton).first);
await tester.tapButton(find.byType(BottomSheetDoneButton).first);
// check the cover
final builtInCover = find.descendant(
of: find.byType(DocumentImmersiveCover),
matching: firstBuiltInImage,
);
expect(builtInCover, findsOneWidget);
});
});
}
@@ -11,7 +11,6 @@ import 'package:appflowy/user/application/auth/auth_service.dart';
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
import 'package:appflowy/workspace/application/settings/prelude.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/uuid.dart';
@@ -28,12 +27,10 @@ void main() {
group('anonymous sign in on mobile', () {
testWidgets('anon user and then sign in', (tester) async {
await tester.initializeAppFlowy(
cloudType: AuthenticatorType.local,
);
await tester.initializeAppFlowy();
// click the anonymousSignInButton
final anonymousSignInButton = find.byType(SignInAnonymousButton);
final anonymousSignInButton = find.byType(SignInAnonymousButtonV2);
expect(anonymousSignInButton, findsOneWidget);
await tester.tapButton(anonymousSignInButton);
@@ -1,8 +1,10 @@
import 'package:integration_test/integration_test.dart';
import 'mobile/home_page/create_new_page_test.dart' as create_new_page_test;
import 'mobile/sign_in/anonymous_sign_in_test.dart' as anonymous_sign_in_test;
Future<void> runIntegrationOnMobile() async {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
anonymous_sign_in_test.main();
create_new_page_test.main();
}
@@ -1,29 +1,37 @@
import 'package:flutter/material.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
import 'package:appflowy/workspace/presentation/settings/pages/settings_account_view.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/setting_appflowy_cloud.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/setting_supabase_cloud.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'base.dart';
import 'expectation.dart';
import 'util.dart';
extension AppFlowyAuthTest on WidgetTester {
Future<void> tapGoogleLoginInButton() async {
await tapButton(find.byKey(const Key('signInWithGoogleButton')));
}
/// Requires being on the SettingsPage.account of the SettingsDialog
Future<void> logout() async {
await tapButton(find.byType(SettingLogoutButton));
final scrollable = find.findSettingsScrollable();
await scrollUntilVisible(
find.byType(SignInOutButton),
100,
scrollable: scrollable,
);
expectToSeeText(LocaleKeys.button_ok.tr());
await tapButtonWithName(LocaleKeys.button_ok.tr());
await tapButton(find.byType(SignInOutButton));
expectToSeeText(LocaleKeys.button_confirm.tr());
await tapButtonWithName(LocaleKeys.button_confirm.tr());
}
Future<void> tapSignInAsGuest() async {
await tapButton(find.byType(SignInAnonymousButton));
await tapButton(find.byType(SignInAnonymousButtonV2));
}
void expectToSeeGoogleLoginButton() {
@@ -1,6 +1,9 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/gestures.dart';
import 'package:flutter/services.dart';
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/env/cloud_env_test.dart';
import 'package:appflowy/startup/entry_point.dart';
@@ -13,16 +16,12 @@ import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widget
import 'package:appflowy/workspace/application/settings/prelude.dart';
import 'package:flowy_infra/uuid.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
class FlowyTestContext {
FlowyTestContext({
required this.applicationDataDirectory,
});
FlowyTestContext({required this.applicationDataDirectory});
final String applicationDataDirectory;
}
@@ -75,7 +74,7 @@ extension AppFlowyTestBase on WidgetTester {
if (cloudType != null) {
switch (cloudType) {
case AuthenticatorType.local:
await useLocal();
await useLocalServer();
break;
case AuthenticatorType.supabase:
await useTestSupabaseCloud();
@@ -118,7 +117,7 @@ extension AppFlowyTestBase on WidgetTester {
Future<void> waitUntilSignInPageShow() async {
if (isAuthEnabled) {
final finder = find.byType(SignInAnonymousButton);
final finder = find.byType(SignInAnonymousButtonV2);
await pumpUntilFound(finder, timeout: const Duration(seconds: 30));
expect(finder, findsOneWidget);
} else {
@@ -180,40 +179,21 @@ extension AppFlowyTestBase on WidgetTester {
buttons: buttons,
warnIfMissed: warnIfMissed,
);
await pumpAndSettle(Duration(milliseconds: milliseconds));
await pumpAndSettle(
Duration(milliseconds: milliseconds),
EnginePhase.sendSemanticsUpdate,
const Duration(seconds: 5),
);
}
Future<void> tapButtonWithName(
String tr, {
int milliseconds = 500,
}) async {
Finder button = find.text(
tr,
findRichText: true,
skipOffstage: false,
);
Future<void> tapButtonWithName(String tr, {int milliseconds = 500}) async {
Finder button = find.text(tr, findRichText: true, skipOffstage: false);
if (button.evaluate().isEmpty) {
button = find.byWidgetPredicate(
(widget) => widget is FlowyText && widget.text == tr,
);
}
await tapButton(
button,
milliseconds: milliseconds,
);
return;
}
Future<void> tapButtonWithTooltip(
String tr, {
int milliseconds = 500,
}) async {
final button = find.byTooltip(tr);
await tapButton(
button,
milliseconds: milliseconds,
);
return;
await tapButton(button, milliseconds: milliseconds);
}
Future<void> doubleTapAt(
@@ -228,34 +208,8 @@ extension AppFlowyTestBase on WidgetTester {
await pumpAndSettle(Duration(milliseconds: milliseconds));
}
Future<void> doubleTapButton(
Finder finder, {
int? pointer,
int buttons = kPrimaryButton,
bool warnIfMissed = true,
int milliseconds = 500,
}) async {
await tap(
finder,
pointer: pointer,
buttons: buttons,
warnIfMissed: warnIfMissed,
);
await pump(kDoubleTapMinTime);
await tap(
finder,
buttons: buttons,
pointer: pointer,
warnIfMissed: warnIfMissed,
);
await pumpAndSettle(Duration(milliseconds: milliseconds));
}
Future<void> wait(int milliseconds) async {
await pumpAndSettle(Duration(milliseconds: milliseconds));
return;
}
}
@@ -267,10 +221,6 @@ extension AppFlowyFinderTestBase on CommonFinders {
}
}
Future<void> useLocal() async {
await useLocalServer();
}
Future<void> useTestSupabaseCloud() async {
await useSupabaseCloud(
url: TestEnv.supabaseUrl,
@@ -4,6 +4,7 @@ import 'package:appflowy/core/config/kv.dart';
import 'package:appflowy/core/config/kv_keys.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/presentation.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/base/emoji_picker_button.dart';
import 'package:appflowy/plugins/document/presentation/share/share_button.dart';
import 'package:appflowy/shared/feature_flags.dart';
@@ -20,12 +21,14 @@ import 'package:appflowy/workspace/presentation/home/menu/view/view_more_action_
import 'package:appflowy/workspace/presentation/notifications/widgets/flowy_tab.dart';
import 'package:appflowy/workspace/presentation/notifications/widgets/notification_button.dart';
import 'package:appflowy/workspace/presentation/notifications/widgets/notification_tab_bar.dart';
import 'package:appflowy/workspace/presentation/settings/shared/settings_body.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/settings_language_view.dart';
import 'package:appflowy/workspace/presentation/widgets/view_title_bar.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/widget/buttons/primary_button.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -36,14 +39,14 @@ import 'util.dart';
extension CommonOperations on WidgetTester {
/// Tap the GetStart button on the launch page.
Future<void> tapGoButton() async {
Future<void> tapAnonymousSignInButton() async {
// local version
final goButton = find.byType(GoButton);
if (goButton.evaluate().isNotEmpty) {
await tapButton(goButton);
} else {
// cloud version
final anonymousButton = find.byType(SignInAnonymousButton);
final anonymousButton = find.byType(SignInAnonymousButtonV2);
await tapButton(anonymousButton);
}
@@ -71,27 +74,6 @@ extension CommonOperations on WidgetTester {
await tapButton(newPageButton);
}
/// Tap the create document button.
///
/// Must call [tapAddViewButton] first.
Future<void> tapCreateDocumentButton() async {
await tapButtonWithName(LocaleKeys.document_menuName.tr());
}
/// Tap the create grid button.
///
/// Must call [tapAddViewButton] first.
Future<void> tapCreateGridButton() async {
await tapButtonWithName(LocaleKeys.grid_menuName.tr());
}
/// Tap the create grid button.
///
/// Must call [tapAddViewButton] first.
Future<void> tapCreateCalendarButton() async {
await tapButtonWithName(LocaleKeys.calendar_menuName.tr());
}
/// Tap the import button.
///
/// Must call [tapAddViewButton] first.
@@ -180,15 +162,9 @@ extension CommonOperations on WidgetTester {
}) async {
final pageNames = findPageName(name, layout: layout);
if (useLast) {
await hoverOnWidget(
pageNames.last,
onHover: onHover,
);
await hoverOnWidget(pageNames.last, onHover: onHover);
} else {
await hoverOnWidget(
pageNames.first,
onHover: onHover,
);
await hoverOnWidget(pageNames.first, onHover: onHover);
}
}
@@ -496,9 +472,7 @@ extension CommonOperations on WidgetTester {
await pumpAndSettle();
}
Future<void> openNotificationHub({
int tabIndex = 0,
}) async {
Future<void> openNotificationHub({int tabIndex = 0}) async {
final finder = find.descendant(
of: find.byType(NotificationButton),
matching: find.byWidgetPredicate(
@@ -520,6 +494,16 @@ extension CommonOperations on WidgetTester {
}
}
Future<void> toggleCommandPalette() async {
// Press CMD+P or CTRL+P to open the command palette
await simulateKeyEvent(
LogicalKeyboardKey.keyP,
isControlPressed: !Platform.isMacOS,
isMetaPressed: Platform.isMacOS,
);
await pumpAndSettle();
}
Future<void> openCollaborativeWorkspaceMenu() async {
if (!FeatureFlag.collaborativeWorkspace.isOn) {
throw UnsupportedError('Collaborative workspace is not enabled');
@@ -528,16 +512,7 @@ extension CommonOperations on WidgetTester {
final workspace = find.byType(SidebarWorkspace);
expect(workspace, findsOneWidget);
// click it
await tapButton(workspace);
}
Future<void> closeCollaborativeWorkspaceMenu() async {
if (!FeatureFlag.collaborativeWorkspace.isOn) {
throw UnsupportedError('Collaborative workspace is not enabled');
}
await tapAt(Offset.zero);
await pumpAndSettle();
await tapButton(workspace, milliseconds: 2000);
}
Future<void> createCollaborativeWorkspace(String name) async {
@@ -560,10 +535,47 @@ extension CommonOperations on WidgetTester {
// input the workspace name
await enterText(find.byType(TextField), name);
await pumpAndSettle();
await tapButtonWithName(LocaleKeys.button_ok.tr());
}
// For mobile platform to launch the app in anonymous mode
Future<void> launchInAnonymousMode() async {
assert(
[TargetPlatform.android, TargetPlatform.iOS]
.contains(defaultTargetPlatform),
'This method is only supported on mobile platforms',
);
await initializeAppFlowy();
final anonymousSignInButton = find.byType(SignInAnonymousButtonV2);
expect(anonymousSignInButton, findsOneWidget);
await tapButton(anonymousSignInButton);
await pumpUntilFound(find.byType(MobileHomeScreen));
}
Future<void> tapSvgButton(FlowySvgData svg) async {
final button = find.byWidgetPredicate(
(widget) => widget is FlowySvg && widget.svg.path == svg.path,
);
await tapButton(button);
}
}
extension SettingsFinder on CommonFinders {
Finder findSettingsScrollable() => find
.descendant(
of: find
.descendant(
of: find.byType(SettingsBody),
matching: find.byType(SingleChildScrollView),
)
.first,
matching: find.byType(Scrollable),
)
.first;
}
extension ViewLayoutPBTest on ViewLayoutPB {
@@ -1,8 +1,9 @@
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:appflowy/core/config/kv_keys.dart';
import 'package:archive/archive_io.dart';
import 'package:flutter/services.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
@@ -51,11 +52,7 @@ class TestWorkspaceService {
Future<void> setUpAll() async {
final root = await workspace.root;
final path = root.path;
SharedPreferences.setMockInitialValues(
{
KVKeys.pathLocation: path,
},
);
SharedPreferences.setMockInitialValues({KVKeys.pathLocation: path});
}
/// Workspaces that are checked into source are compressed. [TestWorkspaceService.setUp()] decompresses the file into an ephemeral directory that will be ignored by source control.
@@ -29,10 +29,6 @@ import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/discl
import 'package:appflowy/plugins/database/grid/presentation/widgets/filter/filter_menu_item.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/footer/grid_footer.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/header/desktop_field_cell.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/header/field_editor.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/header/field_type_list.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/header/type_option/date/date_time_format.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/header/type_option/number.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/row/row.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/sort/create_sort_list.dart';
import 'package:appflowy/plugins/database/grid/presentation/widgets/sort/order_panel.dart';
@@ -54,9 +50,13 @@ import 'package:appflowy/plugins/database/widgets/cell_editor/checklist_cell_edi
import 'package:appflowy/plugins/database/widgets/cell_editor/checklist_progress_bar.dart';
import 'package:appflowy/plugins/database/widgets/cell_editor/date_editor.dart';
import 'package:appflowy/plugins/database/widgets/cell_editor/extension.dart';
import 'package:appflowy/plugins/database/widgets/cell_editor/select_option_editor.dart';
import 'package:appflowy/plugins/database/widgets/cell_editor/select_option_cell_editor.dart';
import 'package:appflowy/plugins/database/widgets/cell_editor/select_option_text_field.dart';
import 'package:appflowy/plugins/database/widgets/database_layout_ext.dart';
import 'package:appflowy/plugins/database/widgets/field/field_editor.dart';
import 'package:appflowy/plugins/database/widgets/field/field_type_list.dart';
import 'package:appflowy/plugins/database/widgets/field/type_option_editor/date/date_time_format.dart';
import 'package:appflowy/plugins/database/widgets/field/type_option_editor/number.dart';
import 'package:appflowy/plugins/database/widgets/row/accessory/cell_accessory.dart';
import 'package:appflowy/plugins/database/widgets/row/row_action.dart';
import 'package:appflowy/plugins/database/widgets/row/row_banner.dart';
@@ -71,7 +71,6 @@ import 'package:appflowy/plugins/database/widgets/setting/setting_property_list.
import 'package:appflowy/util/field_type_extension.dart';
import 'package:appflowy/workspace/presentation/widgets/date_picker/widgets/clear_date_button.dart';
import 'package:appflowy/workspace/presentation/widgets/date_picker/widgets/date_type_option_button.dart';
import 'package:appflowy/workspace/presentation/widgets/date_picker/widgets/end_time_button.dart';
import 'package:appflowy/workspace/presentation/widgets/date_picker/widgets/reminder_selector.dart';
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
@@ -98,7 +97,7 @@ import 'mock/mock_file_picker.dart';
extension AppFlowyDatabaseTest on WidgetTester {
Future<void> openV020database() async {
final context = await initializeAppFlowy();
await tapGoButton();
await tapAnonymousSignInButton();
// expect to see a readme page
expectToSeePageName(gettingStarted);
@@ -343,16 +342,6 @@ extension AppFlowyDatabaseTest on WidgetTester {
return w.isToday;
}
Future<void> toggleDateRange() async {
final findDateEditor = find.byType(EndTimeButton);
final findToggle = find.byType(Toggle);
final finder = find.descendant(
of: findDateEditor,
matching: findToggle,
);
await tapButton(finder);
}
Future<void> tapChangeDateTimeFormatButton() async {
await tapButton(find.byType(DateTypeOptionButton));
}
@@ -403,9 +392,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
}
/// The [SelectOptionCellEditor] must be opened first.
Future<void> createOption({
required String name,
}) async {
Future<void> createOption({required String name}) async {
final findEditor = find.byType(SelectOptionCellEditor);
expect(findEditor, findsOneWidget);
@@ -419,9 +406,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
await pumpAndSettle();
}
Future<void> selectOption({
required String name,
}) async {
Future<void> selectOption({required String name}) async {
final option = find.byWidgetPredicate(
(widget) => widget is SelectOptionTagCell && widget.option.name == name,
);
@@ -440,11 +425,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
(widget.name == name || widget.option?.name == name),
);
final cell = find.descendant(
of: findRow.at(rowIndex),
matching: option,
);
final cell = find.descendant(of: findRow.at(rowIndex), matching: option);
expect(cell, findsOneWidget);
}
@@ -458,11 +439,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
(widget) => widget is SelectOptionTag,
);
final cell = find.descendant(
of: findRow.at(rowIndex),
matching: options,
);
final cell = find.descendant(of: findRow.at(rowIndex), matching: options);
expect(cell, matcher);
}
@@ -470,21 +447,16 @@ extension AppFlowyDatabaseTest on WidgetTester {
final findRow = find.byType(GridRow);
final findCell = finderForFieldType(FieldType.Checklist);
final cell = find.descendant(
of: findRow.at(rowIndex),
matching: findCell,
);
final cell = find.descendant(of: findRow.at(rowIndex), matching: findCell);
await tapButton(cell);
}
void assertChecklistEditorVisible({required bool visible}) {
final editor = find.byType(ChecklistCellEditor);
if (visible) {
expect(editor, findsOneWidget);
} else {
expect(editor, findsNothing);
return expect(editor, findsOneWidget);
}
expect(editor, findsNothing);
}
Future<void> createNewChecklistTask({
@@ -519,7 +491,6 @@ extension AppFlowyDatabaseTest on WidgetTester {
required bool isChecked,
}) {
final task = find.byType(ChecklistItem).at(index);
final widget = this.widget<ChecklistItem>(task);
assert(
widget.task.data.name == name && widget.task.isSelected == isChecked,
@@ -591,27 +562,16 @@ extension AppFlowyDatabaseTest on WidgetTester {
}
}
Future<void> editTitleInRowDetailPage(String title) async {
final titleField = find.byType(EditableTextCell);
await enterText(titleField, title);
await pumpAndSettle();
}
Future<void> hoverRowBanner() async {
final banner = find.byType(RowBanner);
expect(banner, findsOneWidget);
await startGesture(
getCenter(banner),
kind: PointerDeviceKind.mouse,
);
await startGesture(getCenter(banner), kind: PointerDeviceKind.mouse);
await pumpAndSettle();
}
Future<void> openEmojiPicker() async {
await tapButton(find.byType(AddEmojiButton));
}
Future<void> openEmojiPicker() async =>
tapButton(find.byType(AddEmojiButton));
Future<void> tapDateCellInRowDetailPage() async {
final findDateCell = find.byType(EditableDateCell);
@@ -630,25 +590,12 @@ extension AppFlowyDatabaseTest on WidgetTester {
await pumpAndSettle();
}
Future<void> duplicateRowInRowDetailPage() async {
final duplicateButton = find.byType(RowDetailPageDuplicateButton);
await tapButton(duplicateButton);
}
Future<void> deleteRowInRowDetailPage() async {
final deleteButton = find.byType(RowDetailPageDeleteButton);
await tapButton(deleteButton);
}
Future<TestGesture> hoverOnFieldInRowDetail({required int index}) async {
final fieldButtons = find.byType(FieldCellButton);
final button = find
.descendant(of: find.byType(RowDetailPage), matching: fieldButtons)
.at(index);
return startGesture(
getCenter(button),
kind: PointerDeviceKind.mouse,
);
return startGesture(getCenter(button), kind: PointerDeviceKind.mouse);
}
Future<void> reorderFieldInRowDetail({required double offset}) async {
@@ -657,11 +604,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
(widget) => widget is ReorderableDragStartListener && widget.enabled,
)
.first;
await drag(
thumb,
Offset(0, offset),
kind: PointerDeviceKind.mouse,
);
await drag(thumb, Offset(0, offset), kind: PointerDeviceKind.mouse);
await pumpAndSettle();
}
@@ -681,8 +624,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
Future<void> tapDeletePropertyInFieldEditor() async {
final deleteButton = find.byWidgetPredicate(
(widget) =>
widget is FieldActionCell && widget.action == FieldAction.delete,
(w) => w is FieldActionCell && w.action == FieldAction.delete,
);
await tapButton(deleteButton);
@@ -693,11 +635,6 @@ extension AppFlowyDatabaseTest on WidgetTester {
await tapButton(confirmButton);
}
Future<void> scrollGridByOffset(Offset offset) async {
await drag(find.byType(GridPage), offset);
await pumpAndSettle();
}
Future<void> scrollRowDetailByOffset(Offset offset) async {
await drag(find.byType(RowDetailPage), offset);
await pumpAndSettle();
@@ -756,8 +693,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
/// Should call [tapGridFieldWithName] first.
Future<void> tapDeletePropertyButton() async {
final field = find.byWidgetPredicate(
(widget) =>
widget is FieldActionCell && widget.action == FieldAction.delete,
(w) => w is FieldActionCell && w.action == FieldAction.delete,
);
await tapButton(field);
}
@@ -765,9 +701,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
/// A SimpleDialog must be shown first, e.g. when deleting a field.
Future<void> tapDialogOkButton() async {
final field = find.byWidgetPredicate(
(widget) =>
widget is PrimaryTextButton &&
widget.label == LocaleKeys.button_ok.tr(),
(w) => w is PrimaryTextButton && w.label == LocaleKeys.button_ok.tr(),
);
await tapButton(field);
}
@@ -775,8 +709,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
/// Should call [tapGridFieldWithName] first.
Future<void> tapDuplicatePropertyButton() async {
final field = find.byWidgetPredicate(
(widget) =>
widget is FieldActionCell && widget.action == FieldAction.duplicate,
(w) => w is FieldActionCell && w.action == FieldAction.duplicate,
);
await tapButton(field);
}
@@ -798,45 +731,34 @@ extension AppFlowyDatabaseTest on WidgetTester {
/// Should call [tapGridFieldWithName] first.
Future<void> tapHidePropertyButton() async {
final field = find.byWidgetPredicate(
(widget) =>
widget is FieldActionCell &&
widget.action == FieldAction.toggleVisibility,
(w) => w is FieldActionCell && w.action == FieldAction.toggleVisibility,
);
await tapButton(field);
}
Future<void> tapHidePropertyButtonInFieldEditor() async {
final button = find.byWidgetPredicate(
(widget) =>
widget is FieldActionCell &&
widget.action == FieldAction.toggleVisibility,
(w) => w is FieldActionCell && w.action == FieldAction.toggleVisibility,
);
await tapButton(button);
}
Future<void> tapRowDetailPageRowActionButton() async {
await tapButton(find.byType(RowActionButton));
}
Future<void> tapRowDetailPageRowActionButton() async =>
tapButton(find.byType(RowActionButton));
Future<void> tapRowDetailPageCreatePropertyButton() async {
await tapButton(find.byType(CreateRowFieldButton));
}
Future<void> tapRowDetailPageCreatePropertyButton() async =>
tapButton(find.byType(CreateRowFieldButton));
Future<void> tapRowDetailPageDeleteRowButton() async {
await tapButton(find.byType(RowDetailPageDeleteButton));
}
Future<void> tapRowDetailPageDeleteRowButton() async =>
tapButton(find.byType(RowDetailPageDeleteButton));
Future<void> tapRowDetailPageDuplicateRowButton() async {
await tapButton(find.byType(RowDetailPageDuplicateButton));
}
Future<void> tapRowDetailPageDuplicateRowButton() async =>
tapButton(find.byType(RowDetailPageDuplicateButton));
Future<void> tapSwitchFieldTypeButton() async {
await tapButton(find.byType(SwitchFieldButton));
}
Future<void> tapSwitchFieldTypeButton() async =>
tapButton(find.byType(SwitchFieldButton));
Future<void> tapEscButton() async {
await sendKeyEvent(LogicalKeyboardKey.escape);
}
Future<void> tapEscButton() async => sendKeyEvent(LogicalKeyboardKey.escape);
/// Must call [tapSwitchFieldTypeButton] first.
Future<void> selectFieldType(FieldType fieldType) async {
@@ -851,15 +773,13 @@ extension AppFlowyDatabaseTest on WidgetTester {
}
// Use in edit mode of FieldEditor
void expectEmptyTypeOptionEditor() {
expect(
find.descendant(
of: find.byType(FieldTypeOptionEditor),
matching: find.byType(TypeOptionSeparator),
),
findsNothing,
);
}
void expectEmptyTypeOptionEditor() => expect(
find.descendant(
of: find.byType(FieldTypeOptionEditor),
matching: find.byType(TypeOptionSeparator),
),
findsNothing,
);
/// Each field has its own cell, so we can find the corresponding cell by
/// the field type after create a new field.
@@ -868,10 +788,6 @@ extension AppFlowyDatabaseTest on WidgetTester {
expect(finder, findsWidgets);
}
Future<void> assertNumberOfFieldsInGridPage(int num) async {
expect(find.byType(GridFieldCell), findsNWidgets(num));
}
Future<void> assertNumberOfRowsInGridPage(int num) async {
expect(
find.byType(GridRow, skipOffstage: false),
@@ -884,14 +800,11 @@ extension AppFlowyDatabaseTest on WidgetTester {
}
/// Check the field type of the [FieldCellButton] is the same as the name.
Future<void> assertFieldTypeWithFieldName(
String name,
FieldType fieldType,
) async {
Future<void> assertFieldTypeWithFieldName(String name, FieldType type) async {
final field = find.byWidgetPredicate(
(widget) =>
widget is FieldCellButton &&
widget.field.fieldType == fieldType &&
widget.field.fieldType == type &&
widget.field.name == name,
);
@@ -936,11 +849,6 @@ extension AppFlowyDatabaseTest on WidgetTester {
await pumpAndSettle(const Duration(milliseconds: 200));
}
Future<void> findFieldEditor(dynamic matcher) async {
final finder = find.byType(FieldEditor);
expect(finder, matcher);
}
Future<void> findDateEditor(dynamic matcher) async {
final finder = find.byType(DateCellEditor);
expect(finder, matcher);
@@ -994,41 +902,29 @@ extension AppFlowyDatabaseTest on WidgetTester {
await tapButton(find.byType(SortButton));
}
Future<void> tapCreateFilterByFieldType(
FieldType fieldType,
String title,
) async {
Future<void> tapCreateFilterByFieldType(FieldType type, String title) async {
final findFilter = find.byWidgetPredicate(
(widget) =>
widget is GridFilterPropertyCell &&
widget.fieldInfo.fieldType == fieldType &&
widget.fieldInfo.fieldType == type &&
widget.fieldInfo.name == title,
);
await tapButton(findFilter);
}
Future<void> tapFilterButtonInGrid(String filterName) async {
Future<void> tapFilterButtonInGrid(String name) async {
final findFilter = find.byType(FilterMenuItem);
final button = find.descendant(
of: findFilter,
matching: find.text(filterName),
);
final button = find.descendant(of: findFilter, matching: find.text(name));
await tapButton(button);
}
Future<void> tapCreateSortByFieldType(
FieldType fieldType,
String title,
) async {
Future<void> tapCreateSortByFieldType(FieldType type, String title) async {
final findSort = find.byWidgetPredicate(
(widget) =>
widget is GridSortPropertyCell &&
widget.fieldInfo.fieldType == fieldType &&
widget.fieldInfo.fieldType == type &&
widget.fieldInfo.name == title,
);
await tapButton(findSort);
}
@@ -1085,10 +981,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
of: fromSortItem,
matching: find.byType(ReorderableDragStartListener),
);
await drag(
dragElement,
getCenter(toSortItem) - getCenter(fromSortItem),
);
await drag(dragElement, getCenter(toSortItem) - getCenter(fromSortItem));
await pumpAndSettle(const Duration(milliseconds: 200));
}
@@ -1166,15 +1059,6 @@ extension AppFlowyDatabaseTest on WidgetTester {
await tapButton(findCell);
}
Future<void> tapCheckedButtonOnCheckboxFilter() async {
final button = find.descendant(
of: find.byType(HoverButton),
matching: find.text(LocaleKeys.grid_checkboxFilter_isChecked.tr()),
);
await tapButton(button);
}
Future<void> tapUnCheckedButtonOnCheckboxFilter() async {
final button = find.descendant(
of: find.byType(HoverButton),
@@ -1193,15 +1077,6 @@ extension AppFlowyDatabaseTest on WidgetTester {
await tapButton(button);
}
Future<void> tapUnCompletedButtonOnChecklistFilter() async {
final button = find.descendant(
of: find.byType(HoverButton),
matching: find.text(LocaleKeys.grid_checklistFilter_isIncomplted.tr()),
);
await tapButton(button);
}
/// Should call [tapDatabaseSettingButton] first.
Future<void> tapViewPropertiesButton() async {
final findSettingItem = find.byType(DatabaseSettingsList);
@@ -1252,16 +1127,8 @@ extension AppFlowyDatabaseTest on WidgetTester {
await tapButton(button);
}
Future<void> tapFirstDayOfWeek() async {
await tapButton(find.byType(FirstDayOfWeek));
}
Future<void> tapFirstDayOfWeekStartFromSunday() async {
final finder = find.byWidgetPredicate(
(widget) => widget is StartFromButton && widget.dayIndex == 0,
);
await tapButton(finder);
}
Future<void> tapFirstDayOfWeek() async =>
tapButton(find.byType(FirstDayOfWeek));
Future<void> tapFirstDayOfWeekStartFromMonday() async {
final finder = find.byWidgetPredicate(
@@ -1277,20 +1144,14 @@ extension AppFlowyDatabaseTest on WidgetTester {
void assertFirstDayOfWeekStartFromMonday() {
final finder = find.byWidgetPredicate(
(widget) =>
widget is StartFromButton &&
widget.dayIndex == 1 &&
widget.isSelected == true,
(w) => w is StartFromButton && w.dayIndex == 1 && w.isSelected == true,
);
expect(finder, findsOneWidget);
}
void assertFirstDayOfWeekStartFromSunday() {
final finder = find.byWidgetPredicate(
(widget) =>
widget is StartFromButton &&
widget.dayIndex == 0 &&
widget.isSelected == true,
(w) => w is StartFromButton && w.dayIndex == 0 && w.isSelected == true,
);
expect(finder, findsOneWidget);
}
@@ -1307,11 +1168,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
),
)
.first;
await scrollUntilVisible(
todayCell,
300,
scrollable: scrollable,
);
await scrollUntilVisible(todayCell, 300, scrollable: scrollable);
await pumpAndSettle(const Duration(milliseconds: 300));
}
@@ -1351,12 +1208,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
String? title,
}) {
final findDayCell = find.byWidgetPredicate(
(widget) =>
widget is CalendarDayCard &&
isSameDay(
widget.date,
date,
),
(widget) => widget is CalendarDayCard && isSameDay(widget.date, date),
);
Finder findEvents = find.descendant(
of: findDayCell,
@@ -1390,13 +1242,11 @@ extension AppFlowyDatabaseTest on WidgetTester {
await tapButton(cards.at(index));
}
void assertEventEditorOpen() {
expect(find.byType(CalendarEventEditor), findsOneWidget);
}
void assertEventEditorOpen() =>
expect(find.byType(CalendarEventEditor), findsOneWidget);
Future<void> dismissEventEditor() async {
await simulateKeyEvent(LogicalKeyboardKey.escape);
}
Future<void> dismissEventEditor() async =>
simulateKeyEvent(LogicalKeyboardKey.escape);
Future<void> editEventTitle(String title) async {
final textField = find.descendant(
@@ -1507,10 +1357,9 @@ extension AppFlowyDatabaseTest on WidgetTester {
matching: find.byType(TextField),
);
if (isVisible) {
expect(textField, findsOneWidget);
} else {
expect(textField, findsNothing);
return expect(textField, findsOneWidget);
}
expect(textField, findsNothing);
}
Future<void> enterNewGroupName(String name, {required bool submit}) async {
@@ -1612,21 +1461,14 @@ extension AppFlowyDatabaseTest on WidgetTester {
await tapButton(okButton);
}
void assertCurrentDatabaseTagIs(DatabaseLayoutPB layout) {
switch (layout) {
case DatabaseLayoutPB.Board:
expect(find.byType(BoardPage), findsOneWidget);
break;
case DatabaseLayoutPB.Calendar:
expect(find.byType(CalendarPage), findsOneWidget);
break;
case DatabaseLayoutPB.Grid:
expect(find.byType(GridPage), findsOneWidget);
break;
default:
throw Exception('Unknown database layout type: $layout');
}
}
void assertCurrentDatabaseTagIs(DatabaseLayoutPB layout) => switch (layout) {
DatabaseLayoutPB.Board =>
expect(find.byType(BoardPage), findsOneWidget),
DatabaseLayoutPB.Calendar =>
expect(find.byType(CalendarPage), findsOneWidget),
DatabaseLayoutPB.Grid => expect(find.byType(GridPage), findsOneWidget),
_ => throw Exception('Unknown database layout type: $layout'),
};
Future<void> selectDatabaseLayoutType(DatabaseLayoutPB layout) async {
final findLayoutCell = find.byType(DatabaseViewLayoutCell);
@@ -1634,11 +1476,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
(widget) => widget is FlowyText && widget.text == layout.layoutName,
);
final button = find.descendant(
of: findLayoutCell,
matching: findText,
);
final button = find.descendant(of: findLayoutCell, matching: findText);
await tapButton(button);
}
@@ -1660,8 +1498,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
await tapButton(
find.byWidgetPredicate(
(widget) =>
widget is NumberFormatCell && widget.format == NumberFormatPB.USD,
(w) => w is NumberFormatCell && w.format == NumberFormatPB.USD,
),
);
}
@@ -1675,8 +1512,7 @@ extension AppFlowyDatabaseTest on WidgetTester {
String fieldName,
) async {
final field = find.byWidgetPredicate(
(widget) =>
widget is DatabasePropertyCell && widget.fieldInfo.name == fieldName,
(w) => w is DatabasePropertyCell && w.fieldInfo.name == fieldName,
);
final toggleVisibilityButton =
find.descendant(of: field, matching: find.byType(FlowyIconButton));
@@ -1684,18 +1520,12 @@ extension AppFlowyDatabaseTest on WidgetTester {
}
}
Finder finderForDatabaseLayoutType(DatabaseLayoutPB layout) {
switch (layout) {
case DatabaseLayoutPB.Board:
return find.byType(BoardPage);
case DatabaseLayoutPB.Calendar:
return find.byType(CalendarPage);
case DatabaseLayoutPB.Grid:
return find.byType(GridPage);
default:
throw Exception('Unknown database layout type: $layout');
}
}
Finder finderForDatabaseLayoutType(DatabaseLayoutPB layout) => switch (layout) {
DatabaseLayoutPB.Board => find.byType(BoardPage),
DatabaseLayoutPB.Calendar => find.byType(CalendarPage),
DatabaseLayoutPB.Grid => find.byType(GridPage),
_ => throw Exception('Unknown database layout type: $layout'),
};
Finder finderForFieldType(FieldType fieldType) {
switch (fieldType) {
Loaded 100 of 1640 files, more files were not shown because too many files have changed in this diff. Show more