1
1
import { Locator , Page } from "@playwright/test" ;
2
2
3
- export abstract class AbstractPage {
4
- protected page : Page ;
3
+ export abstract class BaseComponent {
4
+ constructor ( protected page : Page , protected rootLocator ?: Locator ) {
5
+
6
+ }
7
+
8
+ protected searcher ( ) : Page | Locator {
9
+ if ( this . rootLocator ) {
10
+ return this . rootLocator ;
11
+ } else {
12
+ return this . page ;
13
+ }
14
+ }
15
+ }
16
+
17
+ export abstract class BasePage extends BaseComponent {
18
+ constructor ( page : Page ) {
19
+ super ( page ) ;
20
+ }
21
+ }
22
+
23
+ export class MainMenuComponent extends BaseComponent {
24
+ private readonly workPackages : Locator ;
5
25
6
26
constructor ( page : Page ) {
7
- this . page = page ;
27
+ super ( page ) ;
28
+ this . workPackages = page . locator ( "#main-menu-work-packages" ) ;
8
29
}
9
30
31
+ async clickOnWorkPackagesItm ( ) : Promise < AllOpenWpPage > {
32
+ await this . workPackages . click ( ) ;
33
+ return new AllOpenWpPage ( this . page ) ;
34
+ }
10
35
}
11
36
12
- export class OverviewPage extends AbstractPage {
37
+ export class OverviewPage extends BasePage {
38
+ public readonly mainMenu : MainMenuComponent ;
39
+
40
+ constructor ( page : Page ) {
41
+ super ( page ) ;
42
+ this . mainMenu = new MainMenuComponent ( page ) ;
43
+ }
44
+
45
+ }
46
+
47
+ export class NewTaskPage extends BasePage {
48
+ private readonly subjectTb : Locator ;
49
+ private readonly estimatedTimeTb : Locator ;
50
+ private readonly saveBtn : Locator ;
51
+
52
+ constructor ( page : Page ) {
53
+ super ( page ) ;
54
+ this . subjectTb = page . getByLabel ( 'Subject' , { exact : true } ) ;
55
+ this . estimatedTimeTb = page . getByLabel ( 'Estimated time' , { exact : true } )
56
+ this . saveBtn = page . getByRole ( 'button' , { name : 'Save' } ) ;
57
+ }
58
+
59
+ async fillSubject ( subject : string ) : Promise < NewTaskPage > {
60
+ await this . subjectTb . fill ( subject ) ;
61
+ return this ;
62
+ }
63
+
64
+ async fillEstimatedTime ( estimatedTime : string ) : Promise < NewTaskPage > {
65
+ // await page.locator('#wp-new-inline-edit--field-assignee').getByRole('combobox').click();
66
+ await this . estimatedTimeTb . fill ( estimatedTime ) ;
67
+ return this ;
68
+ }
69
+
70
+ async clickOnSaveBtn ( ) : Promise < OverviewPage > {
71
+ await this . saveBtn . click ( ) ;
72
+ return new OverviewPage ( this . page ) ;
73
+ }
13
74
14
75
}
15
76
16
- export class OpenProjectPage extends AbstractPage {
77
+
78
+ export class FilterComponent extends BaseComponent {
79
+
80
+ private readonly filterByTextTb : Locator ;
81
+
82
+ constructor ( page : Page ) {
83
+ super ( page ) ;
84
+ this . filterByTextTb = page . getByPlaceholder ( 'Subject, description, comments, ...' ) ;
85
+ }
86
+
87
+ async fillFilterByText ( filterText : string ) : Promise < FilterComponent > {
88
+ const responsePromise = this . page . waitForResponse ( '**/queries/**' ) ;
89
+ await this . filterByTextTb . fill ( filterText ) ;
90
+ const response = await responsePromise
91
+ return this ;
92
+ }
93
+
94
+ }
95
+
96
+ export class Table extends BaseComponent {
97
+ constructor ( page : Page , rootLocator : Locator ) {
98
+ super ( page , rootLocator ) ;
99
+ }
100
+
101
+ async containsText ( text : string ) : Promise < boolean > {
102
+ return await this . searcher ( ) . locator ( 'text=' + text ) . first ( ) . isVisible ( ) ;
103
+ }
104
+ }
105
+
106
+ export class ApplicationMenu extends BaseComponent {
107
+
108
+ private readonly signOutBtn : Locator ;
109
+
110
+ constructor ( page : Page , rootLocator : Locator ) {
111
+ super ( page , rootLocator ) ;
112
+ this . signOutBtn = this . searcher ( ) . getByRole ( 'link' , { name : 'Sign out' } ) ;
113
+ }
114
+
115
+ async clickOnSignOutBtn ( ) : Promise < LoginPage > {
116
+ await this . signOutBtn . click ( ) ;
117
+ return new LoginPage ( this . page ) ;
118
+ }
119
+ }
120
+
121
+
122
+ export class OpenProjectPage extends BasePage {
17
123
18
124
private readonly selectAProjectToggle : Locator ;
125
+ private readonly applicationMenuLnk : Locator ;
126
+ private readonly applicationMenuRoot : Locator ;
127
+
128
+
19
129
20
130
constructor ( page : Page ) {
21
131
super ( page ) ;
22
132
this . selectAProjectToggle = page . locator ( "#projects-menu i" ) ;
133
+ this . applicationMenuLnk = page . locator ( "a[title='OpenProject Admin']" ) . locator ( ".op-app-menu--item-title" ) ;
134
+ this . applicationMenuRoot = page . locator ( "#user-menu" ) ;
23
135
}
24
136
25
137
async clickOnSelectAProjectToggle ( ) : Promise < OpenProjectPage > {
@@ -28,10 +140,15 @@ export class OpenProjectPage extends AbstractPage {
28
140
}
29
141
30
142
async clickOnProjectName ( projectName : string ) : Promise < OverviewPage > {
31
- await this . page . locator ( `#ui-id-5 >> text= ${ projectName } ` ) . click ( )
143
+ await this . page . locator ( '.project-search-results' ) . getByRole ( 'link' , { name : projectName } ) . click ( ) ;
32
144
return new OverviewPage ( this . page ) ;
33
145
}
34
146
147
+ async clickOnUserMenu ( ) : Promise < ApplicationMenu > {
148
+ await this . applicationMenuLnk . click ( ) ;
149
+ return new ApplicationMenu ( this . page , this . applicationMenuRoot ) ;
150
+ }
151
+
35
152
async doSelectProject ( projectName : string ) : Promise < OverviewPage > {
36
153
await this . clickOnSelectAProjectToggle ( ) ;
37
154
await this . clickOnProjectName ( projectName ) ;
@@ -40,7 +157,47 @@ export class OpenProjectPage extends AbstractPage {
40
157
41
158
}
42
159
43
- export class LoginPage extends AbstractPage {
160
+
161
+ export class AllOpenWpPage extends OpenProjectPage {
162
+
163
+ private readonly createNewWpBtn : Locator ;
164
+ private readonly taskBtn : Locator ;
165
+ private readonly activateFilterBtn : Locator ;
166
+ private readonly deactivateFilterBtn : Locator ;
167
+ public readonly table : Table ;
168
+
169
+
170
+ constructor ( page : Page ) {
171
+ super ( page ) ;
172
+ this . createNewWpBtn = page . locator ( 'wp-create-button' ) . getByLabel ( 'Create new work package' ) ;
173
+ this . taskBtn = page . locator ( '#types-context-menu' ) . getByLabel ( 'Task' , { exact : true } ) ;
174
+ this . activateFilterBtn = page . getByRole ( 'button' , { name : 'Activate Filter' } ) ;
175
+ this . deactivateFilterBtn = page . getByRole ( 'button' , { name : 'Deactivate Filter' } ) ;
176
+ this . table = new Table ( page , page . locator ( '.work-package-table' ) ) ;
177
+ }
178
+
179
+ async clickOnCreateNewWorkPackageBtn ( ) : Promise < NewTaskPage > {
180
+ await this . createNewWpBtn . click ( ) ;
181
+ await this . taskBtn . click ( ) ;
182
+ return new NewTaskPage ( this . page ) ;
183
+ }
184
+
185
+ async clickOnActivateFilterBtn ( ) : Promise < FilterComponent > {
186
+ await this . activateFilterBtn . click ( ) ;
187
+ return new FilterComponent ( this . page ) ;
188
+ }
189
+
190
+ async clickOnDeactivateFilterBtn ( ) : Promise < AllOpenWpPage > {
191
+ await this . deactivateFilterBtn . click ( ) ;
192
+ return new AllOpenWpPage ( this . page ) ;
193
+ }
194
+
195
+
196
+ }
197
+
198
+
199
+
200
+ export class LoginPage extends BasePage {
44
201
/**
45
202
* @param {import('playwright').Page } page
46
203
*/
0 commit comments