Skip to content

Commit dfba7be

Browse files
authored
test: add editor editing BDD coverage (#344)
* test: add editor editing BDD coverage * test: consolidate editor BDD workflows * chore: update image * chore: fix test
1 parent ac6dd52 commit dfba7be

11 files changed

Lines changed: 1504 additions & 14 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: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
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

Comments
 (0)