|
| 1 | +Feature: Editor editing |
| 2 | + Migrated from appflowy-editor edit, command, IME, shortcut, paste, and undo tests. |
| 3 | + |
| 4 | + Background: |
| 5 | + Given a blank document page is open |
| 6 | + |
| 7 | + Scenario: Basic text input, replacement, and deletion |
| 8 | + When I type "Hello AppFlowy" in the editor |
| 9 | + Then the editor contains "Hello AppFlowy" |
| 10 | + When I start a new editor paragraph |
| 11 | + And I type "Hello World" in the editor |
| 12 | + And I select the last word |
| 13 | + And I type "AppFlowy" in the editor |
| 14 | + Then the editor contains "Hello AppFlowy" |
| 15 | + And the editor does not contain "Hello World" |
| 16 | + When I type " Test" in the editor |
| 17 | + And I delete the previous word |
| 18 | + Then the editor does not contain "Hello AppFlowy Test" |
| 19 | + |
| 20 | + Scenario: Split a paragraph with Enter |
| 21 | + When I type "SplitHere" in the editor |
| 22 | + And I move the caret left 4 characters |
| 23 | + And I press "Enter" |
| 24 | + Then the editor contains "Split" |
| 25 | + And the editor contains "Here" |
| 26 | + |
| 27 | + Scenario: Insert a soft break with Shift Enter |
| 28 | + When I type "Line 1" in the editor |
| 29 | + And I press "Shift+Enter" |
| 30 | + And I type "Line 2" in the editor |
| 31 | + Then the document has 1 "paragraph" block |
| 32 | + And the editor contains "Line 1" |
| 33 | + And the editor contains "Line 2" |
| 34 | + |
| 35 | + Scenario: Undo and redo typed content |
| 36 | + When I type "Redo Me" in the editor |
| 37 | + Then the editor contains "Redo Me" |
| 38 | + When I undo the editor change |
| 39 | + Then the editor does not contain "Redo Me" |
| 40 | + When I redo the editor change |
| 41 | + Then the editor contains "Redo Me" |
| 42 | + |
| 43 | + Scenario: Multi-step undo and redo restores document state |
| 44 | + When I type "1. " in the editor |
| 45 | + Then editor block 0 has type "numbered_list" |
| 46 | + When I undo the editor change |
| 47 | + Then editor block 0 has type "paragraph" |
| 48 | + When I redo the editor change |
| 49 | + Then editor block 0 has type "numbered_list" |
| 50 | + When I type "Apple" in the editor |
| 51 | + And I press "Enter" |
| 52 | + And I type "Banana" in the editor |
| 53 | + And I press "Enter" |
| 54 | + And I type "Cherry" in the editor |
| 55 | + Then the editor has at least 3 top-level blocks |
| 56 | + When I undo the editor change 30 times |
| 57 | + Then the editor has exactly 1 top-level block |
| 58 | + And editor block 0 contains "" |
| 59 | + When I redo the editor change 30 times |
| 60 | + Then the editor has at least 3 top-level blocks |
| 61 | + And editor block 0 has type "numbered_list" |
| 62 | + And editor block 0 contains "Apple" |
| 63 | + And editor block 1 contains "Banana" |
| 64 | + And editor block 2 contains "Cherry" |
| 65 | + When I undo the editor change 30 times |
| 66 | + And I type "Fresh start" in the editor |
| 67 | + And I redo the editor change 10 times |
| 68 | + Then the editor has exactly 1 top-level block |
| 69 | + And editor block 0 contains "Fresh start" |
| 70 | + |
| 71 | + Scenario Outline: Markdown prefixes convert text blocks |
| 72 | + When I type "<input>" in the editor |
| 73 | + Then a "<block_type>" block contains "<content>" |
| 74 | + And the editor does not contain "<input>" |
| 75 | + |
| 76 | + Examples: |
| 77 | + | input | block_type | content | |
| 78 | + | # Heading 1 | heading | Heading 1 | |
| 79 | + | ## Heading 2 | heading | Heading 2 | |
| 80 | + | - Bullet Item | bulleted_list | Bullet Item | |
| 81 | + | 1. Numbered Item | numbered_list | Numbered Item | |
| 82 | + | [] Todo Item | todo_list | Todo Item | |
| 83 | + | > Toggle Item | toggle_list | Toggle Item | |
| 84 | + | ### Heading 3 | heading | Heading 3 | |
| 85 | + | * Star Bullet | bulleted_list | Star Bullet | |
| 86 | + | + Plus Bullet | bulleted_list | Plus Bullet | |
| 87 | + |
| 88 | + Scenario: Markdown divider prefix creates a divider block |
| 89 | + When I type "---" in the editor |
| 90 | + Then the document has 1 "divider" block |
| 91 | + |
| 92 | + Scenario: Quote markdown prefix converts to a quote block |
| 93 | + When I type quote markdown text "Quote Text" in the editor |
| 94 | + Then a "quote" block contains "Quote Text" |
| 95 | + |
| 96 | + Scenario: Inline markdown converts text marks |
| 97 | + When I type "Normal **Bold Text** Normal" in the editor |
| 98 | + Then "bold" formatting contains "Bold Text" |
| 99 | + And the editor does not contain "Normal **Bold Text** Normal" |
| 100 | + When I start a new editor paragraph |
| 101 | + And I type "Normal *Italic Text* Normal" in the editor |
| 102 | + Then "italic" formatting contains "Italic Text" |
| 103 | + And the editor does not contain "Normal *Italic Text* Normal" |
| 104 | + When I start a new editor paragraph |
| 105 | + And I type "Normal ~~Strike Text~~ Normal" in the editor |
| 106 | + Then "strikethrough" formatting contains "Strike Text" |
| 107 | + And the editor does not contain "Normal ~~Strike Text~~ Normal" |
| 108 | + When I start a new editor paragraph |
| 109 | + And I type "Normal `Inline Code` Normal" in the editor |
| 110 | + Then inline code contains "Inline Code" |
| 111 | + And the editor does not contain "`Inline Code`" |
| 112 | + |
| 113 | + Scenario Outline: Selected text formatting shortcuts apply marks |
| 114 | + When I type "<content>" in the editor |
| 115 | + And I select all editor content |
| 116 | + And I apply the "<format>" formatting shortcut |
| 117 | + Then "<format>" formatting contains "<content>" |
| 118 | + |
| 119 | + Examples: |
| 120 | + | format | content | |
| 121 | + | bold | Bold Shortcut | |
| 122 | + | italic | Italic Shortcut | |
| 123 | + | underline | Underline Text | |
| 124 | + | strikethrough | Strike Shortcut | |
| 125 | + | code | Code Shortcut | |
| 126 | + |
| 127 | + Scenario: Slash menu opens and dismisses |
| 128 | + When I open the slash menu |
| 129 | + Then the slash menu is visible |
| 130 | + And the slash menu command "heading1" is visible |
| 131 | + And the slash menu command "todoList" is visible |
| 132 | + When I press "Escape" |
| 133 | + Then the slash menu is hidden |
| 134 | + |
| 135 | + Scenario: Keyboard Enter selects a filtered slash command |
| 136 | + When I open the slash menu |
| 137 | + And I search the slash menu for "quote" |
| 138 | + Then the slash menu has 1 visible command |
| 139 | + And I press "Enter" |
| 140 | + Then editor block 0 has type "quote" |
| 141 | + |
| 142 | + Scenario Outline: Slash commands create text blocks |
| 143 | + When I choose slash command "<command>" |
| 144 | + And I type "<content>" in the editor |
| 145 | + Then a "<block_type>" block contains "<content>" |
| 146 | + |
| 147 | + Examples: |
| 148 | + | command | block_type | content | |
| 149 | + | heading1 | heading | Slash Heading | |
| 150 | + | bulletedList | bulleted_list | Slash Bullet | |
| 151 | + | numberedList | numbered_list | Slash Number | |
| 152 | + | todoList | todo_list | Slash Todo | |
| 153 | + | quote | quote | Slash Quote | |
| 154 | + | code | code | const value = 1 | |
| 155 | + |
| 156 | + Scenario Outline: Slash trigger on non-empty line inserts a new block below |
| 157 | + When I type "Hello world" in the editor |
| 158 | + And I type slash in the editor |
| 159 | + And I search the slash menu for "<search>" |
| 160 | + And I select slash command "<command>" |
| 161 | + Then editor block 0 has type "paragraph" |
| 162 | + And editor block 0 contains "Hello world" |
| 163 | + And editor block 1 has type "<block_type>" |
| 164 | + And the editor has exactly 2 top-level blocks |
| 165 | + |
| 166 | + Examples: |
| 167 | + | search | command | block_type | |
| 168 | + | heading | heading1 | heading | |
| 169 | + | quote | quote | quote | |
| 170 | + |
| 171 | + Scenario: Slash divider command creates a divider block |
| 172 | + When I choose slash command "divider" |
| 173 | + Then the document has 1 "divider" block |
| 174 | + |
| 175 | + Scenario: Slash table command creates a simple table block |
| 176 | + When I choose slash command "simpleTable" |
| 177 | + Then the document has 1 "simple_table" block |
| 178 | + |
| 179 | + Scenario: Indent and outdent a bulleted list item |
| 180 | + When I type "- Parent Item" in the editor |
| 181 | + And I press "Enter" |
| 182 | + And I type "Child Item" in the editor |
| 183 | + Then a "bulleted_list" block contains "Child Item" |
| 184 | + When I press "Tab" |
| 185 | + Then "Child Item" is nested under "Parent Item" in "bulleted_list" |
| 186 | + When I press "Shift+Tab" |
| 187 | + Then "Child Item" is not nested under "Parent Item" in "bulleted_list" |
| 188 | + |
| 189 | + Scenario: Toggle a todo item with the checkbox |
| 190 | + When I type "[] Checkbox Todo" in the editor |
| 191 | + Then a "todo_list" block contains "Checkbox Todo" |
| 192 | + When I toggle the todo item checkbox |
| 193 | + Then the todo item "Checkbox Todo" is checked |
| 194 | + When I toggle the todo item checkbox |
| 195 | + Then the todo item "Checkbox Todo" is not checked |
| 196 | + |
| 197 | + Scenario: Toggle list interactions collapse and expand content |
| 198 | + When I type "> Parent Toggle" in the editor |
| 199 | + And I press "Enter" |
| 200 | + And I type "Hidden Child" in the editor |
| 201 | + Then the editor visibly contains "Hidden Child" |
| 202 | + When I toggle the toggle list icon |
| 203 | + Then the editor does not visibly contain "Hidden Child" |
| 204 | + And the first toggle list is collapsed |
| 205 | + When I press the toggle block shortcut |
| 206 | + Then the first toggle list is expanded |
| 207 | + And the editor visibly contains "Hidden Child" |
| 208 | + When I press the toggle block shortcut |
| 209 | + Then the first toggle list is collapsed |
| 210 | + And the editor does not visibly contain "Hidden Child" |
| 211 | + When I toggle the toggle list icon |
| 212 | + Then the first toggle list is expanded |
| 213 | + And the editor visibly contains "Hidden Child" |
| 214 | + |
| 215 | + Scenario: Empty toggle list clears back to paragraph |
| 216 | + When I type "> " in the editor |
| 217 | + And I press "Enter" |
| 218 | + Then editor block 0 has type "paragraph" |
| 219 | + |
| 220 | + Scenario: Toolbar and alignment actions update the selected block |
| 221 | + When I type "Toolbar Block" in the editor |
| 222 | + And I apply the "left" alignment shortcut |
| 223 | + Then editor block 0 has alignment "left" |
| 224 | + When I apply the "center" alignment shortcut |
| 225 | + Then editor block 0 has alignment "center" |
| 226 | + When I apply the "right" alignment shortcut |
| 227 | + Then editor block 0 has alignment "right" |
| 228 | + When I select all editor content |
| 229 | + And I apply the "heading1" block toolbar action |
| 230 | + Then editor block 0 has type "heading" |
| 231 | + When I select all editor content |
| 232 | + And I apply the "bulletedList" block toolbar action |
| 233 | + Then editor block 0 has type "bulleted_list" |
| 234 | + When I select all editor content |
| 235 | + And I apply the "numberedList" block toolbar action |
| 236 | + Then editor block 0 has type "numbered_list" |
| 237 | + When I select all editor content |
| 238 | + And I apply the "quote" block toolbar action |
| 239 | + Then editor block 0 has type "quote" |
| 240 | + |
| 241 | + Scenario: Toolbar applies a link to selected text |
| 242 | + When I type "appflowy" in the editor |
| 243 | + And I select all editor content |
| 244 | + And I apply link "https://appflowy.io" from the toolbar |
| 245 | + Then link mark "appflowy" has href "https://appflowy.io" |
| 246 | + |
| 247 | + Scenario: Paste rich HTML, markdown headings, and plain text |
| 248 | + When I paste html content: |
| 249 | + """ |
| 250 | + <meta charset="utf-8"><h2><strong>User Installation</strong></h2><ul><li><a href="https://appflowy.io/download">Windows/Mac/Linux</a></li><li><a href="https://appflowy.io/docs">Docs</a></li></ul> |
| 251 | + """ |
| 252 | + Then a "heading" block contains "User Installation" |
| 253 | + And "bold" formatting contains "User Installation" |
| 254 | + And link mark "Windows/Mac/Linux" has href "https://appflowy.io/download" |
| 255 | + And link mark "Docs" has href "https://appflowy.io/docs" |
| 256 | + When I paste markdown text: |
| 257 | + """ |
| 258 | + # I'm h1 |
| 259 | + ## I'm h2 |
| 260 | + ### I'm h3 |
| 261 | + """ |
| 262 | + Then a "heading" block contains "I'm h1" |
| 263 | + And a "heading" block contains "I'm h2" |
| 264 | + And a "heading" block contains "I'm h3" |
| 265 | + When I paste plain text: |
| 266 | + """ |
| 267 | + First pasted line |
| 268 | + Second pasted line |
| 269 | + """ |
| 270 | + Then the editor contains "First pasted line" |
| 271 | + And the editor contains "Second pasted line" |
| 272 | + |
| 273 | + Scenario: Escape exits selection editing mode |
| 274 | + When I type "Exit editing mode" in the editor |
| 275 | + And I select all editor content |
| 276 | + Then the selection toolbar is visible |
| 277 | + When I press "Escape" |
| 278 | + Then the selection toolbar is hidden |
0 commit comments