@@ -47,57 +47,70 @@ export class MarkdownEditorPage {
47
47
this . locators = new MarkdownEditorLocators ( page ) ;
48
48
}
49
49
50
- /** Returns the current editor mode */
50
+ /**
51
+ * Checks that the current editor mode matches the expected one
52
+ */
53
+ async assertMode ( mode : MarkdownEditorMode ) {
54
+ await this . expect . poll ( ( ) => this . getMode ( ) ) . toBe ( mode ) ;
55
+ }
56
+
57
+ /**
58
+ * Asserts that the toolbar button is disabled
59
+ */
60
+ async assertToolbarButtonDisabled ( label : string ) {
61
+ const button = this . getToolbarButton ( label ) ;
62
+ await this . expect ( button ) . toHaveClass ( / d i s a b l e d / ) ;
63
+ }
64
+
65
+ /**
66
+ * Asserts that the toolbar button is enabled
67
+ */
68
+ async assertToolbarButtonEnabled ( label : string ) {
69
+ const button = this . getToolbarButton ( label ) ;
70
+ await this . expect ( button ) . not . toHaveClass ( / d i s a b l e d / ) ;
71
+ }
72
+
73
+ /**
74
+ * Returns the current editor mode
75
+ */
51
76
async getMode ( ) : Promise < MarkdownEditorMode > {
52
77
const value = await this . locators . editor . getAttribute ( 'data-mode' ) ;
53
78
const mode = value as MarkdownEditorMode | null ;
54
79
if ( mode === 'wysiwyg' || mode === 'markup' ) return mode ;
55
80
throw new Error ( `MarkdownEditorPage.getMode(): unknown editor mode "${ mode } "` ) ;
56
81
}
57
82
58
- /** Finds a command menu item by text */
83
+ /**
84
+ * Finds an element in the command menu by its text
85
+ */
59
86
getByTextInCommandMenu ( text : string ) : Locator {
60
87
return this . locators . commandMenu . getByText ( text ) ;
61
88
}
62
89
63
- /** Finds an element inside the editable area by selector */
90
+ /**
91
+ * Finds an element by selector within the contenteditable area
92
+ */
64
93
getBySelectorInContenteditable ( selector : string ) : Locator {
65
94
return this . locators . contenteditable . locator ( selector ) ;
66
95
}
67
96
68
- /** Finds a command menu item by text */
97
+ /**
98
+ * Finds an element by text within the contenteditable area
99
+ */
69
100
getByTextInContenteditable ( text : string ) : Locator {
70
101
return this . locators . contenteditable . getByText ( text ) ;
71
102
}
72
103
73
- /** Opens the settings popup if it's not already open */
74
- async openSettingsPopup ( ) {
75
- if ( await this . locators . settingsContent . isVisible ( ) ) return ;
76
-
77
- await this . locators . settingsButton . click ( ) ;
78
- await this . locators . settingsContent . waitFor ( { state : 'visible' } ) ;
79
- }
80
-
81
- /** Asserts that the current mode matches the expected one */
82
- async assertMode ( mode : MarkdownEditorMode ) {
83
- await this . expect . poll ( ( ) => this . getMode ( ) ) . toBe ( mode ) ;
84
- }
85
-
86
- /** Clicks the toolbar "more actions" button. */
87
- async clickToolbarMoreActionButton ( ) {
88
- await this . locators . toolbarMoreActionButton . click ( ) ;
104
+ /**
105
+ * Returns a locator for the toolbar button by its aria-label
106
+ */
107
+ getToolbarButton ( label : string ) : Locator {
108
+ return this . page . getByLabel ( label ) ;
89
109
}
90
110
91
- /** Switches the editor to the specified mode */
92
- async switchMode ( mode : MarkdownEditorMode ) {
93
- if ( ( await this . getMode ( ) ) === mode ) return ;
94
-
95
- await this . openSettingsPopup ( ) ;
96
- await this . locators . settingsContent . getByTestId ( `g-md-settings-mode-${ mode } ` ) . click ( ) ;
97
- await this . assertMode ( mode ) ;
98
- }
99
-
100
- /** Returns the current preview visibility state */
111
+ /**
112
+ * Returns the current visibility state of the preview
113
+ */
101
114
async getPreview ( ) : Promise < VisibleState > {
102
115
const previewContent = await this . locators . previewContent ;
103
116
if ( await previewContent . isVisible ( ) ) {
@@ -111,7 +124,20 @@ export class MarkdownEditorPage {
111
124
return undefined ;
112
125
}
113
126
114
- /** Toggles or sets the preview visibility state */
127
+ /**
128
+ * Switches the editor to the specified mode
129
+ */
130
+ async switchMode ( mode : MarkdownEditorMode ) {
131
+ if ( ( await this . getMode ( ) ) === mode ) return ;
132
+
133
+ await this . openSettingsPopup ( ) ;
134
+ await this . locators . settingsContent . getByTestId ( `g-md-settings-mode-${ mode } ` ) . click ( ) ;
135
+ await this . assertMode ( mode ) ;
136
+ }
137
+
138
+ /**
139
+ * Toggles or sets the preview visibility state
140
+ */
115
141
async switchPreview ( state ?: VisibleState ) {
116
142
const currentState = await this . getPreview ( ) ;
117
143
const revertState = currentState === 'visible' ? 'hidden' : 'visible' ;
@@ -129,28 +155,76 @@ export class MarkdownEditorPage {
129
155
} ) ;
130
156
}
131
157
132
- /** Removes focus from the editable area */
158
+ /**
159
+ * Opens the settings popup if it is not already open
160
+ */
161
+ async openSettingsPopup ( ) {
162
+ if ( await this . locators . settingsContent . isVisible ( ) ) return ;
163
+
164
+ await this . locators . settingsButton . click ( ) ;
165
+ await this . locators . settingsContent . waitFor ( { state : 'visible' } ) ;
166
+ }
167
+
168
+ /**
169
+ * Clicks the "more actions" button on the toolbar
170
+ */
171
+ async clickToolbarMoreActionButton ( ) {
172
+ await this . locators . toolbarMoreActionButton . click ( ) ;
173
+ }
174
+
175
+ /**
176
+ * Clicks a toolbar button using its aria-label
177
+ */
178
+ async clickToolbarButton ( label : string ) {
179
+ const button = this . getToolbarButton ( label ) ;
180
+
181
+ await this . expect ( button ) . toBeEnabled ( ) ;
182
+ await button . click ( ) ;
183
+ }
184
+
185
+ /**
186
+ * Clears all content from the contenteditable area
187
+ */
188
+ async clearContent ( ) {
189
+ await this . press ( 'ControlOrMeta+A' ) ;
190
+ await this . press ( 'Backspace' ) ;
191
+ }
192
+
193
+ /**
194
+ * Removes focus from the contenteditable area
195
+ */
133
196
async blur ( ) {
134
197
await this . locators . contenteditable . blur ( ) ;
135
198
}
136
199
137
- /** Presses a key in the editable area */
200
+ /**
201
+ * Presses a key within the contenteditable area
202
+ */
138
203
async press ( key : string ) {
139
204
await this . locators . contenteditable . press ( key ) ;
140
205
}
141
206
142
- /** Presses each character in sequence in the editable area */
207
+ /**
208
+ * Presses each character sequentially in the contenteditable area
209
+ */
143
210
async pressSequentially ( key : string ) {
144
211
await this . locators . contenteditable . pressSequentially ( key ) ;
145
212
}
146
213
147
- /** Clears all content from the editable area */
148
- async clearContent ( ) {
149
- await this . press ( 'ControlOrMeta+A' ) ;
150
- await this . press ( 'Backspace' ) ;
214
+ /**
215
+ * Simulates input rule behavior by typing a sequence in WYSIWYG mode.
216
+ * Clears the editor and types each character
217
+ */
218
+ async inputRule ( sequence : string ) {
219
+ await this . switchMode ( 'wysiwyg' ) ;
220
+ await this . clearContent ( ) ;
221
+ await this . pressSequentially ( sequence ) ;
222
+ await this . press ( 'Space' ) ;
151
223
}
152
224
153
- /** Pastes data into the editable area */
225
+ /**
226
+ * Pastes data into the contenteditable area
227
+ */
154
228
async paste ( value : PasteData | string ) {
155
229
const data : PasteData = typeof value === 'string' ? { 'text/plain' : value } : value ;
156
230
@@ -166,12 +240,16 @@ export class MarkdownEditorPage {
166
240
} , data ) ;
167
241
}
168
242
169
- /** Fills the editable area with the given text */
243
+ /**
244
+ * Fills the contenteditable area with the provided text
245
+ */
170
246
async fill ( text : string ) {
171
247
this . locators . contenteditable . fill ( text ) ;
172
248
}
173
249
174
- /** Selects text inside the editable area */
250
+ /**
251
+ * Selects text within the contenteditable area
252
+ */
175
253
async selectTextIn ( selector ?: string ) {
176
254
let loc = this . locators . contenteditable ;
177
255
if ( selector ) loc = loc . locator ( selector ) ;
0 commit comments