Skip to content

Commit 66eb015

Browse files
committed
test: add editor editing BDD coverage
1 parent ac6dd52 commit 66eb015

7 files changed

Lines changed: 1394 additions & 2 deletions

File tree

.eslintignore.web

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ cypress/e2e/
1111
cypress/support/
1212
playwright/
1313
playwright.config.ts
14+
playwright.bdd.config.ts
1415
playwright-snapshot.config.ts
1516
deploy/*.test.ts
1617
deploy/*.integration.test.ts

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Test results
22
test-results/
3+
playwright/.features-gen/
34

45
# Logs
56
logs

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
"test:e2e:database": "playwright test playwright/e2e/database --headed",
4444
"test:e2e:page": "playwright test playwright/e2e/page --headed",
4545
"test:e2e:chat": "playwright test playwright/e2e/chat --headed",
46+
"test:e2e:bdd": "bddgen test -c playwright.bdd.config.ts && playwright test -c playwright.bdd.config.ts",
47+
"test:e2e:bdd:headed": "bddgen test -c playwright.bdd.config.ts && playwright test -c playwright.bdd.config.ts --headed",
4648
"coverage": "cross-env COVERAGE=true pnpm run test:unit",
4749
"generate-tokens": "node scripts/system-token/convert-tokens.cjs",
4850
"generate-protobuf": "pbjs -t static-module -w es6 -o ./src/proto/messages.js ./src/proto/messages.proto && pbts -o ./src/proto/messages.d.ts ./src/proto/messages.js",
@@ -250,6 +252,7 @@
250252
"jest-node-exports-resolver": "^1.1.6",
251253
"pino": "^9.2.0",
252254
"pino-pretty": "^11.2.1",
255+
"playwright-bdd": "8.5.1",
253256
"postcss": "^8.5.10",
254257
"prettier": "2.8.4",
255258
"prettier-plugin-tailwindcss": "^0.2.2",

playwright.bdd.config.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { defineConfig, devices } from '@playwright/test';
2+
import { defineBddConfig } from 'playwright-bdd';
3+
import * as dotenv from 'dotenv';
4+
5+
dotenv.config();
6+
7+
const testDir = defineBddConfig({
8+
features: 'playwright/bdd/features/**/*.feature',
9+
steps: 'playwright/bdd/steps/**/*.ts',
10+
outputDir: 'playwright/.features-gen',
11+
});
12+
13+
export default defineConfig({
14+
testDir,
15+
testMatch: '**/*.spec.js',
16+
fullyParallel: true,
17+
forbidOnly: !!process.env.CI,
18+
retries: process.env.CI ? 1 : 0,
19+
workers: process.env.CI ? 1 : undefined,
20+
reporter: process.env.CI
21+
? [['list'], ['html'], ['github'], ['json', { outputFile: 'playwright-report/report.json' }]]
22+
: 'list',
23+
timeout: 120000,
24+
use: {
25+
baseURL: process.env.BASE_URL || 'http://localhost:3000',
26+
viewport: { width: 1440, height: 900 },
27+
trace: 'on-first-retry',
28+
screenshot: 'only-on-failure',
29+
video: 'off',
30+
actionTimeout: 15000,
31+
navigationTimeout: 15000,
32+
bypassCSP: true,
33+
permissions: ['clipboard-read', 'clipboard-write'],
34+
},
35+
projects: [
36+
{
37+
name: 'chromium',
38+
use: {
39+
...devices['Desktop Chrome'],
40+
viewport: { width: 1440, height: 900 },
41+
launchOptions: {
42+
args: ['--disable-gpu-sandbox', '--no-sandbox', '--disable-dev-shm-usage', '--force-device-scale-factor=1'],
43+
},
44+
},
45+
},
46+
],
47+
expect: {
48+
timeout: 15000,
49+
},
50+
});
Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
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: Type plain text into the editor
8+
When I type "Hello AppFlowy" in the editor
9+
Then the editor contains "Hello AppFlowy"
10+
11+
Scenario: Replace selected text with typed text
12+
When I type "Hello World" in the editor
13+
And I select the last word
14+
And I type "AppFlowy" in the editor
15+
Then the editor contains "Hello AppFlowy"
16+
And the editor does not contain "Hello World"
17+
18+
Scenario: Delete the previous word
19+
When I type "Hello World Test" in the editor
20+
And I delete the previous word
21+
Then the editor contains "Hello World"
22+
And the editor does not contain "Hello World Test"
23+
24+
Scenario: Split a paragraph with Enter
25+
When I type "SplitHere" in the editor
26+
And I move the caret left 4 characters
27+
And I press "Enter"
28+
Then the editor contains "Split"
29+
And the editor contains "Here"
30+
31+
Scenario: Insert a soft break with Shift Enter
32+
When I type "Line 1" in the editor
33+
And I press "Shift+Enter"
34+
And I type "Line 2" in the editor
35+
Then the document has 1 "paragraph" block
36+
And the editor contains "Line 1"
37+
And the editor contains "Line 2"
38+
39+
Scenario: Undo and redo typed content
40+
When I type "Redo Me" in the editor
41+
Then the editor contains "Redo Me"
42+
When I undo the editor change
43+
Then the editor does not contain "Redo Me"
44+
When I redo the editor change
45+
Then the editor contains "Redo Me"
46+
47+
Scenario: Multi-step undo and redo restores document state
48+
When I type "1. " in the editor
49+
Then editor block 0 has type "numbered_list"
50+
When I undo the editor change
51+
Then editor block 0 has type "paragraph"
52+
When I redo the editor change
53+
Then editor block 0 has type "numbered_list"
54+
When I type "Apple" in the editor
55+
And I press "Enter"
56+
And I type "Banana" in the editor
57+
And I press "Enter"
58+
And I type "Cherry" in the editor
59+
Then the editor has at least 3 top-level blocks
60+
When I undo the editor change 30 times
61+
Then the editor has exactly 1 top-level block
62+
And editor block 0 contains ""
63+
When I redo the editor change 30 times
64+
Then the editor has at least 3 top-level blocks
65+
And editor block 0 has type "numbered_list"
66+
And editor block 0 contains "Apple"
67+
And editor block 1 contains "Banana"
68+
And editor block 2 contains "Cherry"
69+
When I undo the editor change 30 times
70+
And I type "Fresh start" in the editor
71+
And I redo the editor change 10 times
72+
Then the editor has exactly 1 top-level block
73+
And editor block 0 contains "Fresh start"
74+
75+
Scenario Outline: Markdown prefixes convert text blocks
76+
When I type "<input>" in the editor
77+
Then a "<block_type>" block contains "<content>"
78+
And the editor does not contain "<input>"
79+
80+
Examples:
81+
| input | block_type | content |
82+
| # Heading 1 | heading | Heading 1 |
83+
| ## Heading 2 | heading | Heading 2 |
84+
| - Bullet Item | bulleted_list | Bullet Item |
85+
| 1. Numbered Item | numbered_list | Numbered Item |
86+
| [] Todo Item | todo_list | Todo Item |
87+
| > Toggle Item | toggle_list | Toggle Item |
88+
| ### Heading 3 | heading | Heading 3 |
89+
| * Star Bullet | bulleted_list | Star Bullet |
90+
| + Plus Bullet | bulleted_list | Plus Bullet |
91+
92+
Scenario: Markdown divider prefix creates a divider block
93+
When I type "---" in the editor
94+
Then the document has 1 "divider" block
95+
96+
Scenario: Quote markdown prefix converts to a quote block
97+
When I type quote markdown text "Quote Text" in the editor
98+
Then a "quote" block contains "Quote Text"
99+
100+
Scenario Outline: Inline markdown marks convert to styled text
101+
When I type "<input>" in the editor
102+
Then "<format>" formatting contains "<content>"
103+
And the editor does not contain "<input>"
104+
105+
Examples:
106+
| input | format | content |
107+
| Normal **Bold Text** Normal | bold | Bold Text |
108+
| Normal *Italic Text* Normal | italic | Italic Text |
109+
| Normal ~~Strike Text~~ Normal | strikethrough | Strike Text |
110+
111+
Scenario: Markdown inline code converts to styled text
112+
When I type "Normal `Inline Code` Normal" in the editor
113+
Then inline code contains "Inline Code"
114+
And the editor does not contain "`Inline Code`"
115+
116+
Scenario Outline: Selected text formatting shortcuts apply marks
117+
When I type "<content>" in the editor
118+
And I select all editor content
119+
And I apply the "<format>" formatting shortcut
120+
Then "<format>" formatting contains "<content>"
121+
122+
Examples:
123+
| format | content |
124+
| bold | Bold Shortcut |
125+
| italic | Italic Shortcut |
126+
| underline | Underline Text |
127+
| strikethrough | Strike Shortcut |
128+
| code | Code Shortcut |
129+
130+
Scenario: Slash menu opens and dismisses
131+
When I open the slash menu
132+
Then the slash menu is visible
133+
And the slash menu command "heading1" is visible
134+
And the slash menu command "todoList" is visible
135+
When I press "Escape"
136+
Then the slash menu is hidden
137+
138+
Scenario Outline: Slash commands create text blocks
139+
When I choose slash command "<command>"
140+
And I type "<content>" in the editor
141+
Then a "<block_type>" block contains "<content>"
142+
143+
Examples:
144+
| command | block_type | content |
145+
| heading1 | heading | Slash Heading |
146+
| bulletedList | bulleted_list | Slash Bullet |
147+
| numberedList | numbered_list | Slash Number |
148+
| todoList | todo_list | Slash Todo |
149+
| quote | quote | Slash Quote |
150+
| code | code | const value = 1 |
151+
152+
Scenario: Keyboard Enter selects a filtered slash command
153+
When I open the slash menu
154+
And I search the slash menu for "quote"
155+
Then the slash menu has 1 visible command
156+
And I press "Enter"
157+
Then editor block 0 has type "quote"
158+
159+
Scenario Outline: Slash trigger on non-empty line inserts a new block below
160+
When I type "Hello world" in the editor
161+
And I type slash in the editor
162+
And I search the slash menu for "<search>"
163+
And I select slash command "<command>"
164+
Then editor block 0 has type "paragraph"
165+
And editor block 0 contains "Hello world"
166+
And editor block 1 has type "<block_type>"
167+
And the editor has exactly 2 top-level blocks
168+
169+
Examples:
170+
| search | command | block_type |
171+
| heading | heading1 | heading |
172+
| quote | quote | quote |
173+
174+
Scenario: Slash divider command creates a divider block
175+
When I choose slash command "divider"
176+
Then the document has 1 "divider" block
177+
178+
Scenario: Slash table command creates a simple table block
179+
When I choose slash command "simpleTable"
180+
Then the document has 1 "simple_table" block
181+
182+
Scenario: Indent and outdent a bulleted list item
183+
When I type "- Parent Item" in the editor
184+
And I press "Enter"
185+
And I type "Child Item" in the editor
186+
Then a "bulleted_list" block contains "Child Item"
187+
When I press "Tab"
188+
Then "Child Item" is nested under "Parent Item" in "bulleted_list"
189+
When I press "Shift+Tab"
190+
Then "Child Item" is not nested under "Parent Item" in "bulleted_list"
191+
192+
Scenario: Toggle a todo item with the checkbox
193+
When I type "[] Checkbox Todo" in the editor
194+
Then a "todo_list" block contains "Checkbox Todo"
195+
When I toggle the todo item checkbox
196+
Then the todo item "Checkbox Todo" is checked
197+
When I toggle the todo item checkbox
198+
Then the todo item "Checkbox Todo" is not checked
199+
200+
Scenario: Toggle list collapse hides and shows child content
201+
When I type "> Parent Toggle" in the editor
202+
And I press "Enter"
203+
And I type "Hidden Child" in the editor
204+
Then the editor visibly contains "Hidden Child"
205+
When I toggle the toggle list icon
206+
Then the editor does not visibly contain "Hidden Child"
207+
When I toggle the toggle list icon
208+
Then the editor visibly contains "Hidden Child"
209+
210+
Scenario: Toggle list shortcut collapses and expands the block
211+
When I type "> Keyboard Toggle" in the editor
212+
Then the first toggle list is expanded
213+
When I press the toggle block shortcut
214+
Then the first toggle list is collapsed
215+
When I press the toggle block shortcut
216+
Then the first toggle list is expanded
217+
218+
Scenario: Empty toggle list clears back to paragraph
219+
When I type "> " in the editor
220+
And I press "Enter"
221+
Then editor block 0 has type "paragraph"
222+
223+
Scenario Outline: Toolbar converts selected blocks
224+
When I type "Toolbar Block" in the editor
225+
And I select all editor content
226+
And I apply the "<action>" block toolbar action
227+
Then editor block 0 has type "<block_type>"
228+
229+
Examples:
230+
| action | block_type |
231+
| heading1 | heading |
232+
| bulletedList | bulleted_list |
233+
| numberedList | numbered_list |
234+
| quote | quote |
235+
236+
Scenario Outline: Alignment shortcuts update paragraph alignment
237+
When I type "Aligned text" in the editor
238+
And I apply the "<alignment>" alignment shortcut
239+
Then editor block 0 has alignment "<alignment>"
240+
241+
Examples:
242+
| alignment |
243+
| left |
244+
| center |
245+
| right |
246+
247+
Scenario: Toolbar applies a link to selected text
248+
When I type "appflowy" in the editor
249+
And I select all editor content
250+
And I apply link "https://appflowy.io" from the toolbar
251+
Then link mark "appflowy" has href "https://appflowy.io"
252+
253+
Scenario: Paste HTML preserves heading, bold text, and links
254+
When I paste html content:
255+
"""
256+
<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>
257+
"""
258+
Then a "heading" block contains "User Installation"
259+
And "bold" formatting contains "User Installation"
260+
And link mark "Windows/Mac/Linux" has href "https://appflowy.io/download"
261+
And link mark "Docs" has href "https://appflowy.io/docs"
262+
263+
Scenario: Paste markdown headings creates heading blocks
264+
When I paste markdown text:
265+
"""
266+
# I'm h1
267+
## I'm h2
268+
### I'm h3
269+
"""
270+
Then the document has 3 "heading" block
271+
And a "heading" block contains "I'm h1"
272+
And a "heading" block contains "I'm h2"
273+
And a "heading" block contains "I'm h3"
274+
275+
Scenario: Paste plain text into the editor
276+
When I paste plain text:
277+
"""
278+
First pasted line
279+
Second pasted line
280+
"""
281+
Then the editor contains "First pasted line"
282+
And the editor contains "Second pasted line"
283+
284+
Scenario: Escape exits selection editing mode
285+
When I type "Exit editing mode" in the editor
286+
And I select all editor content
287+
Then the selection toolbar is visible
288+
When I press "Escape"
289+
Then the selection toolbar is hidden

0 commit comments

Comments
 (0)