@@ -2,6 +2,92 @@ import type {Expect, Locator, Page} from '@playwright/test';
2
2
3
3
import type { DataTransferType , MarkdownEditorMode } from 'src' ;
4
4
5
+ type YfmTableCellMenuType = 'row' | 'column' ;
6
+ type YfmTableActionKind =
7
+ | 'remove-table'
8
+ | 'remove-column'
9
+ | 'remove-row'
10
+ | 'add-column-before'
11
+ | 'add-column-after'
12
+ | 'add-row-before'
13
+ | 'add-row-after' ;
14
+
15
+ class YfmTable {
16
+ readonly buttonPlusRowLocator ;
17
+ readonly buttonPlusColumnLocator ;
18
+ private readonly tableWrapperLocator ;
19
+
20
+ private readonly rowButtonLocator ;
21
+ private readonly columnButtonLocator ;
22
+ private readonly cellMenus : Readonly < Record < YfmTableCellMenuType , Locator > > ;
23
+ private readonly cellMenuActions : Readonly < Record < YfmTableActionKind , Locator > > ;
24
+
25
+ constructor ( page : Page ) {
26
+ this . tableWrapperLocator = page . getByTestId ( 'g-md-yfm-table-wrapper' ) ;
27
+ this . buttonPlusRowLocator = page . getByTestId ( 'g-md-yfm-table-plus-row' ) ;
28
+ this . buttonPlusColumnLocator = page . getByTestId ( 'g-md-yfm-table-plus-column' ) ;
29
+
30
+ this . rowButtonLocator = page . getByTestId ( 'g-md-yfm-table-row-btn' ) ;
31
+ this . columnButtonLocator = page . getByTestId ( 'g-md-yfm-table-column-btn' ) ;
32
+ this . cellMenus = {
33
+ row : page . getByTestId ( 'g-md-yfm-table-row-menu' ) ,
34
+ column : page . getByTestId ( 'g-md-yfm-table-column-menu' ) ,
35
+ } ;
36
+ this . cellMenuActions = {
37
+ 'add-column-after' : page . getByTestId ( 'g-md-yfm-table-action-add-column-after' ) ,
38
+ 'add-column-before' : page . getByTestId ( 'g-md-yfm-table-action-add-column-before' ) ,
39
+ 'add-row-after' : page . getByTestId ( 'g-md-yfm-table-action-add-row-after' ) ,
40
+ 'add-row-before' : page . getByTestId ( 'g-md-yfm-table-action-add-row-before' ) ,
41
+ 'remove-column' : page . getByTestId ( 'g-md-yfm-table-action-remove-column' ) ,
42
+ 'remove-row' : page . getByTestId ( 'g-md-yfm-table-action-remove-row' ) ,
43
+ 'remove-table' : page . getByTestId ( 'g-md-yfm-table-action-remove-table' ) ,
44
+ } ;
45
+ }
46
+
47
+ getMenuLocator ( type : YfmTableCellMenuType ) {
48
+ return this . cellMenus [ type ] ;
49
+ }
50
+
51
+ async getTable ( locator ?: Locator ) {
52
+ return locator ?. locator ( this . tableWrapperLocator ) ?? this . tableWrapperLocator ;
53
+ }
54
+
55
+ async getRows ( table ?: Locator ) {
56
+ return ( table || ( await this . getTable ( ) ) ) . first ( ) . locator ( 'table > tbody > tr' ) ;
57
+ }
58
+
59
+ async getCells ( table ?: Locator ) {
60
+ return ( table || ( await this . getTable ( ) ) ) . first ( ) . locator ( 'table > tbody > tr > td' ) ;
61
+ }
62
+
63
+ async getRowButtons ( table ?: Locator ) {
64
+ return ( table || ( await this . getTable ( ) ) ) . first ( ) . locator ( this . rowButtonLocator ) ;
65
+ }
66
+
67
+ async getColumnButtons ( table ?: Locator ) {
68
+ return ( table || ( await this . getTable ( ) ) ) . first ( ) . locator ( this . columnButtonLocator ) ;
69
+ }
70
+
71
+ async doCellAction ( menuType : YfmTableCellMenuType , kind : YfmTableActionKind ) {
72
+ const menu = this . cellMenus [ menuType ] ;
73
+ await menu . waitFor ( { state : 'visible' } ) ;
74
+ await menu . locator ( this . cellMenuActions [ kind ] ) . click ( ) ;
75
+ await menu . waitFor ( { state : 'hidden' } ) ;
76
+ }
77
+
78
+ async clickPlusRow ( locator ?: Locator ) {
79
+ const btnLoc = this . buttonPlusRowLocator ;
80
+ const loc = locator ?. locator ( btnLoc ) ?? btnLoc ;
81
+ await loc . click ( ) ;
82
+ }
83
+
84
+ async clickPlusColumn ( locator ?: Locator ) {
85
+ const btnLoc = this . buttonPlusColumnLocator ;
86
+ const loc = locator ?. locator ( btnLoc ) ?? btnLoc ;
87
+ await loc . click ( ) ;
88
+ }
89
+ }
90
+
5
91
class MarkdownEditorLocators {
6
92
readonly commandMenu ;
7
93
readonly component ;
@@ -44,6 +130,7 @@ type VisibleState = 'attached' | 'detached' | 'visible' | 'hidden' | undefined;
44
130
45
131
export class MarkdownEditorPage {
46
132
readonly locators ;
133
+ readonly yfmTable ;
47
134
protected readonly page : Page ;
48
135
protected readonly expect : Expect ;
49
136
@@ -52,6 +139,7 @@ export class MarkdownEditorPage {
52
139
this . expect = expect ;
53
140
54
141
this . locators = new MarkdownEditorLocators ( page ) ;
142
+ this . yfmTable = new YfmTable ( page ) ;
55
143
}
56
144
57
145
/**
@@ -107,17 +195,28 @@ export class MarkdownEditorPage {
107
195
throw new Error ( `MarkdownEditorPage.getMode(): unknown editor mode "${ mode } "` ) ;
108
196
}
109
197
198
+ async openCommandMenu ( search = '' ) {
199
+ await this . pressSequentially ( '/' + search ) ;
200
+ await this . locators . commandMenu . waitFor ( { state : 'visible' } ) ;
201
+ }
202
+
110
203
/**
111
204
* Finds an element in the command menu by its text
112
205
*/
113
206
getByTextInCommandMenu ( text : string ) : Locator {
114
207
return this . locators . commandMenu . getByText ( text ) ;
115
208
}
116
209
210
+ async selectFromCommandMenu ( searchText : string , commandText : string ) {
211
+ await this . openCommandMenu ( searchText ) ;
212
+ await this . getByTextInCommandMenu ( commandText ) . click ( ) ;
213
+ await this . locators . commandMenu . waitFor ( { state : 'detached' } ) ;
214
+ }
215
+
117
216
/**
118
217
* Finds an element by selector within the contenteditable area
119
218
*/
120
- getBySelectorInContenteditable ( selector : string ) : Locator {
219
+ getBySelectorInContenteditable ( selector : string | Locator ) : Locator {
121
220
return this . locators . contenteditable . locator ( selector ) ;
122
221
}
123
222
@@ -207,6 +306,14 @@ export class MarkdownEditorPage {
207
306
}
208
307
}
209
308
309
+ async hideToolbarMoreMenu ( ) {
310
+ const visible = await this . locators . toolbarMoreMenu . isVisible ( ) ;
311
+ if ( visible ) {
312
+ await this . clickToolbarMoreActionButton ( ) ;
313
+ await this . locators . toolbarMoreMenu . waitFor ( { state : 'hidden' } ) ;
314
+ }
315
+ }
316
+
210
317
async hoverToolbarMoreAction ( label : string ) {
211
318
await this . locators . toolbarMoreMenu . waitFor ( { state : 'visible' } ) ;
212
319
await this . getToolbarButton ( label ) . hover ( { force : true } ) ;
@@ -227,6 +334,8 @@ export class MarkdownEditorPage {
227
334
228
335
await this . expect ( button ) . toBeEnabled ( ) ;
229
336
await button . click ( ) ;
337
+
338
+ if ( inPopup ) await this . locators . toolbarMoreMenu . waitFor ( { state : 'detached' } ) ;
230
339
}
231
340
232
341
/**
0 commit comments