@nextsparkjs/core 0.1.0-beta.39 → 0.1.0-beta.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/styles/classes.json +1 -1
  2. package/dist/templates/contents/themes/starter/tests/cypress/e2e/uat/entities/tasks/tasks-crud.bdd.md +278 -0
  3. package/dist/templates/contents/themes/starter/tests/cypress/e2e/uat/entities/tasks/tasks-crud.cy.ts +22 -14
  4. package/dist/templates/contents/themes/starter/tests/cypress/src/components/DevKeyringPOM.ts +160 -0
  5. package/dist/templates/contents/themes/starter/tests/cypress/src/components/EntityForm.ts +375 -0
  6. package/dist/templates/contents/themes/starter/tests/cypress/src/components/EntityList.ts +389 -0
  7. package/dist/templates/contents/themes/starter/tests/cypress/src/components/TeamSwitcherPOM.ts +450 -0
  8. package/dist/templates/contents/themes/starter/tests/cypress/src/components/index.ts +13 -0
  9. package/dist/templates/contents/themes/starter/tests/cypress/src/core/BlockEditorBasePOM.ts +576 -0
  10. package/dist/templates/contents/themes/starter/tests/cypress/src/core/index.ts +2 -0
  11. package/dist/templates/contents/themes/starter/tests/cypress/{e2e/uat/entities/tasks → src/entities}/TasksPOM.ts +1 -1
  12. package/dist/templates/contents/themes/starter/tests/cypress/src/entities/index.ts +10 -0
  13. package/dist/templates/contents/themes/starter/tests/cypress/src/features/BillingPOM.ts +385 -0
  14. package/dist/templates/contents/themes/starter/tests/cypress/src/features/DashboardPOM.ts +245 -0
  15. package/dist/templates/contents/themes/starter/tests/cypress/src/features/DevtoolsPOM.ts +750 -0
  16. package/dist/templates/contents/themes/starter/tests/cypress/src/features/ScheduledActionsPOM.ts +463 -0
  17. package/dist/templates/contents/themes/starter/tests/cypress/src/features/SettingsPOM.ts +362 -0
  18. package/dist/templates/contents/themes/starter/tests/cypress/src/features/SuperadminPOM.ts +331 -0
  19. package/dist/templates/contents/themes/starter/tests/cypress/src/features/index.ts +18 -0
  20. package/dist/templates/contents/themes/starter/tests/cypress/src/index.ts +88 -0
  21. package/dist/templates/contents/themes/starter/tests/cypress/src/session-helpers.ts +332 -88
  22. package/dist/templates/contents/themes/starter/tests/cypress.config.ts +4 -1
  23. package/package.json +1 -1
  24. package/scripts/test/jest-theme.mjs +7 -3
  25. package/templates/contents/themes/starter/tests/cypress/e2e/uat/entities/tasks/tasks-crud.bdd.md +278 -0
  26. package/templates/contents/themes/starter/tests/cypress/e2e/uat/entities/tasks/tasks-crud.cy.ts +22 -14
  27. package/templates/contents/themes/starter/tests/cypress/src/components/DevKeyringPOM.ts +160 -0
  28. package/templates/contents/themes/starter/tests/cypress/src/components/EntityForm.ts +375 -0
  29. package/templates/contents/themes/starter/tests/cypress/src/components/EntityList.ts +389 -0
  30. package/templates/contents/themes/starter/tests/cypress/src/components/TeamSwitcherPOM.ts +450 -0
  31. package/templates/contents/themes/starter/tests/cypress/src/components/index.ts +13 -0
  32. package/templates/contents/themes/starter/tests/cypress/src/core/BlockEditorBasePOM.ts +576 -0
  33. package/templates/contents/themes/starter/tests/cypress/src/core/index.ts +2 -0
  34. package/templates/contents/themes/starter/tests/cypress/{e2e/uat/entities/tasks → src/entities}/TasksPOM.ts +1 -1
  35. package/templates/contents/themes/starter/tests/cypress/src/entities/index.ts +10 -0
  36. package/templates/contents/themes/starter/tests/cypress/src/features/BillingPOM.ts +385 -0
  37. package/templates/contents/themes/starter/tests/cypress/src/features/DashboardPOM.ts +245 -0
  38. package/templates/contents/themes/starter/tests/cypress/src/features/DevtoolsPOM.ts +750 -0
  39. package/templates/contents/themes/starter/tests/cypress/src/features/ScheduledActionsPOM.ts +463 -0
  40. package/templates/contents/themes/starter/tests/cypress/src/features/SettingsPOM.ts +362 -0
  41. package/templates/contents/themes/starter/tests/cypress/src/features/SuperadminPOM.ts +331 -0
  42. package/templates/contents/themes/starter/tests/cypress/src/features/index.ts +18 -0
  43. package/templates/contents/themes/starter/tests/cypress/src/index.ts +88 -0
  44. package/templates/contents/themes/starter/tests/cypress/src/session-helpers.ts +332 -88
  45. package/templates/contents/themes/starter/tests/cypress.config.ts +4 -1
  46. package/dist/templates/contents/themes/starter/tests/cypress/e2e/_utils/selectors/pages-editor.bdd.md +0 -207
  47. package/dist/templates/contents/themes/starter/tests/cypress/e2e/_utils/selectors/pages-editor.cy.ts +0 -211
  48. package/dist/templates/contents/themes/starter/tests/cypress/e2e/_utils/selectors/posts-editor.bdd.md +0 -184
  49. package/dist/templates/contents/themes/starter/tests/cypress/e2e/_utils/selectors/posts-editor.cy.ts +0 -350
  50. package/dist/templates/contents/themes/starter/tests/cypress/e2e/_utils/selectors/public.cy.ts +0 -112
  51. package/dist/templates/contents/themes/starter/tests/cypress/e2e/_utils/selectors/taxonomies.cy.ts +0 -126
  52. package/templates/contents/themes/starter/tests/cypress/e2e/_utils/selectors/pages-editor.bdd.md +0 -207
  53. package/templates/contents/themes/starter/tests/cypress/e2e/_utils/selectors/pages-editor.cy.ts +0 -211
  54. package/templates/contents/themes/starter/tests/cypress/e2e/_utils/selectors/posts-editor.bdd.md +0 -184
  55. package/templates/contents/themes/starter/tests/cypress/e2e/_utils/selectors/posts-editor.cy.ts +0 -350
  56. package/templates/contents/themes/starter/tests/cypress/e2e/_utils/selectors/public.cy.ts +0 -112
  57. package/templates/contents/themes/starter/tests/cypress/e2e/_utils/selectors/taxonomies.cy.ts +0 -126
@@ -0,0 +1,750 @@
1
+ /**
2
+ * DevtoolsPOM - Page Object Model for DevTools (/devtools)
3
+ *
4
+ * Provides methods for:
5
+ * - Navigation to /devtools pages (home, style, tests, config)
6
+ * - Sidebar interaction
7
+ * - Access control assertions
8
+ * - Page content validation
9
+ *
10
+ * @version 3.0 - Uses centralized selectors from cySelector()
11
+ *
12
+ * @example
13
+ * const devtools = new DevtoolsPOM()
14
+ * devtools.visitHome()
15
+ * .assertOnDevtoolsHome()
16
+ * .clickStyleGallery()
17
+ */
18
+
19
+ import { BasePOM } from '../core/BasePOM'
20
+ import { cySelector } from '../selectors'
21
+
22
+ export class DevtoolsPOM extends BasePOM {
23
+ // ============================================
24
+ // SELECTORS using centralized cySelector()
25
+ // ============================================
26
+
27
+ get selectors() {
28
+ return {
29
+ // Layout & Navigation
30
+ mobileHeader: cySelector('devtools.navigation.mobileHeader'),
31
+ sidebarCollapseToggle: cySelector('devtools.navigation.collapseToggle'),
32
+
33
+ // Navigation items
34
+ navHome: cySelector('devtools.navigation.navItem', { section: 'home' }),
35
+ navStyleGallery: cySelector('devtools.navigation.navItem', { section: 'stylegallery' }),
36
+ navTestCases: cySelector('devtools.navigation.navItem', { section: 'testcases' }),
37
+ navConfig: cySelector('devtools.navigation.navItem', { section: 'config' }),
38
+
39
+ // Exit navigation
40
+ exitToDashboard: cySelector('devtools.navigation.exitToDashboard'),
41
+ goToAdmin: cySelector('devtools.navigation.goToSuperadmin'),
42
+
43
+ // Home Page
44
+ homePage: cySelector('devtools.home.page'),
45
+ homeStyleLink: cySelector('devtools.home.styleLink'),
46
+ homeTestsLink: cySelector('devtools.home.testsLink'),
47
+ homeConfigLink: cySelector('devtools.home.configLink'),
48
+
49
+ // Style Gallery Page
50
+ stylePage: cySelector('devtools.style.page'),
51
+ styleTabComponents: cySelector('devtools.style.tabComponents'),
52
+ styleTabFieldTypes: cySelector('devtools.style.tabFieldTypes'),
53
+ styleTabTheme: cySelector('devtools.style.tabTheme'),
54
+ styleTabGuidelines: cySelector('devtools.style.tabGuidelines'),
55
+ styleComponentGallery: cySelector('devtools.style.componentGallery'),
56
+ styleFieldTypes: cySelector('devtools.style.fieldTypes'),
57
+ styleThemePreview: cySelector('devtools.style.themePreview'),
58
+
59
+ // Test Cases Page
60
+ testsPage: cySelector('devtools.tests.page'),
61
+ testsViewer: cySelector('devtools.tests.viewer'),
62
+ testsTree: cySelector('devtools.tests.tree'),
63
+ testsLoading: cySelector('devtools.tests.loading'),
64
+ testsFileLoading: cySelector('devtools.tests.fileLoading'),
65
+ testsEmptyState: cySelector('devtools.tests.emptyState'),
66
+ testsContent: cySelector('devtools.tests.content'),
67
+ testsError: cySelector('devtools.tests.error'),
68
+ testsMarkdownContent: cySelector('devtools.tests.markdownContent'),
69
+
70
+ // Dynamic selectors for file tree
71
+ testsFolder: (name: string) => cySelector('devtools.tests.folder', { name }),
72
+ testsFile: (name: string) => cySelector('devtools.tests.file', { name }),
73
+
74
+ // Config Viewer Page
75
+ configPage: cySelector('devtools.config.page'),
76
+ configViewer: cySelector('devtools.config.viewer'),
77
+ configTabTheme: cySelector('devtools.config.tabTheme'),
78
+ configTabEntities: cySelector('devtools.config.tabEntities'),
79
+ configThemeContent: cySelector('devtools.config.themeContent'),
80
+ configEntitiesContent: cySelector('devtools.config.entitiesContent'),
81
+ configCopyTheme: cySelector('devtools.config.copyTheme'),
82
+ configCopyEntities: cySelector('devtools.config.copyEntities'),
83
+
84
+ // Additional tests selectors
85
+ testsNotFound: cySelector('devtools.tests.notFound'),
86
+ testsBackToList: cySelector('devtools.tests.backToList'),
87
+
88
+ // Test Coverage Dashboard (new)
89
+ testsDashboard: cySelector('devtools.tests.dashboard'),
90
+ testsDashboardButton: cySelector('devtools.tests.dashboardButton'),
91
+ testsDashboardStats: cySelector('devtools.tests.dashboardStats'),
92
+ testsDashboardStatFeatures: cySelector('devtools.tests.dashboardStatFeatures'),
93
+ testsDashboardStatFlows: cySelector('devtools.tests.dashboardStatFlows'),
94
+ testsDashboardStatFiles: cySelector('devtools.tests.dashboardStatFiles'),
95
+ testsDashboardStatTags: cySelector('devtools.tests.dashboardStatTags'),
96
+ testsDashboardGaps: cySelector('devtools.tests.dashboardGaps'),
97
+ testsDashboardGapItem: (slug: string) => cySelector('devtools.tests.dashboardGapItem', { slug }),
98
+
99
+ // Sidebar
100
+ sidebar: cySelector('devtools.navigation.sidebar'),
101
+
102
+ // API Tester selectors (new feature)
103
+ apiTester: '[data-cy="api-tester"]',
104
+ apiTesterBackBtn: '[data-cy="api-tester-back-btn"]',
105
+ apiTesterEndpointInfo: '[data-cy="api-tester-endpoint-info"]',
106
+ apiTesterMethodSelector: '[data-cy="api-tester-method-selector"]',
107
+ apiTesterMethodBadge: (method: string) => `[data-cy="api-tester-method-${method.toLowerCase()}"]`,
108
+ apiTesterUrlPreview: '[data-cy="api-tester-url-preview"]',
109
+ apiTesterPathParams: '[data-cy="api-tester-path-params"]',
110
+ apiTesterPathParam: (name: string) => `[data-cy="api-tester-path-param-${name}"]`,
111
+ apiTesterPathParamInput: (name: string) => `[data-cy="api-tester-path-param-${name}-input"]`,
112
+ apiTesterQueryEditor: '[data-cy="api-tester-query-editor"]',
113
+ apiTesterQueryRow: (index: number) => `[data-cy="api-tester-query-row-${index}"]`,
114
+ apiTesterQueryKey: (index: number) => `[data-cy="api-tester-query-row-${index}-key"]`,
115
+ apiTesterQueryValue: (index: number) => `[data-cy="api-tester-query-row-${index}-value"]`,
116
+ apiTesterQueryDelete: (index: number) => `[data-cy="api-tester-query-row-${index}-delete"]`,
117
+ apiTesterQueryAddBtn: '[data-cy="api-tester-query-add-btn"]',
118
+ apiTesterHeadersEditor: '[data-cy="api-tester-headers-editor"]',
119
+ apiTesterAuth: '[data-cy="api-tester-auth"]',
120
+ apiTesterAuthType: '[data-cy="api-tester-auth-type"]',
121
+ apiTesterAuthSession: '[data-cy="api-tester-auth-session"]',
122
+ apiTesterAuthApiKey: '[data-cy="api-tester-auth-apikey"]',
123
+ apiTesterApiKeyInput: '[data-cy="api-tester-apikey-input"]',
124
+ apiTesterPayload: '[data-cy="api-tester-payload"]',
125
+ apiTesterPayloadTextarea: '[data-cy="api-tester-payload-textarea"]',
126
+ apiTesterPayloadError: '[data-cy="api-tester-payload-error"]',
127
+ apiTesterSendBtn: '[data-cy="api-tester-send-btn"]',
128
+ apiTesterCancelBtn: '[data-cy="api-tester-cancel-btn"]',
129
+ apiTesterResponse: '[data-cy="api-tester-response"]',
130
+ apiTesterResponseIdle: '[data-cy="api-tester-response-idle"]',
131
+ apiTesterResponseLoading: '[data-cy="api-tester-response-loading"]',
132
+ apiTesterResponseError: '[data-cy="api-tester-response-error"]',
133
+ apiTesterResponseStatus: '[data-cy="api-tester-response-status"]',
134
+ apiTesterResponseTime: '[data-cy="api-tester-response-time"]',
135
+ apiTesterResponseTabBody: '[data-cy="api-tester-response-tab-body"]',
136
+ apiTesterResponseTabHeaders: '[data-cy="api-tester-response-tab-headers"]',
137
+ apiTesterResponseBody: '[data-cy="api-tester-response-body"]',
138
+ apiTesterResponseHeaders: '[data-cy="api-tester-response-headers"]',
139
+ }
140
+ }
141
+
142
+ // ============================================
143
+ // FACTORY METHOD
144
+ // ============================================
145
+
146
+ static create(): DevtoolsPOM {
147
+ return new DevtoolsPOM()
148
+ }
149
+
150
+ // ============================================
151
+ // NAVIGATION
152
+ // ============================================
153
+
154
+ /**
155
+ * Visit /devtools home page
156
+ */
157
+ visitHome() {
158
+ cy.visit('/devtools')
159
+ return this
160
+ }
161
+
162
+ /**
163
+ * Visit /devtools/style (Style Gallery)
164
+ */
165
+ visitStyleGallery() {
166
+ cy.visit('/devtools/style')
167
+ return this
168
+ }
169
+
170
+ /**
171
+ * Visit /devtools/tests (Test Cases Viewer)
172
+ */
173
+ visitTestCases() {
174
+ cy.visit('/devtools/tests')
175
+ return this
176
+ }
177
+
178
+ /**
179
+ * Visit /devtools/config (Config Viewer)
180
+ */
181
+ visitConfig() {
182
+ cy.visit('/devtools/config')
183
+ return this
184
+ }
185
+
186
+ /**
187
+ * Attempt to visit /devtools (for access control tests)
188
+ * Uses failOnStatusCode: false to capture redirects
189
+ */
190
+ attemptToVisitDevtools() {
191
+ cy.visit('/devtools', { failOnStatusCode: false })
192
+ return this
193
+ }
194
+
195
+ // ============================================
196
+ // SIDEBAR NAVIGATION ACTIONS
197
+ // ============================================
198
+
199
+ /**
200
+ * Click on Home navigation item in sidebar
201
+ */
202
+ clickNavHome() {
203
+ cy.get(this.selectors.navHome).click()
204
+ return this
205
+ }
206
+
207
+ /**
208
+ * Click on Style Gallery navigation item in sidebar
209
+ */
210
+ clickNavStyleGallery() {
211
+ cy.get(this.selectors.navStyleGallery).click()
212
+ return this
213
+ }
214
+
215
+ /**
216
+ * Click on Test Cases navigation item in sidebar
217
+ */
218
+ clickNavTestCases() {
219
+ cy.get(this.selectors.navTestCases).click()
220
+ return this
221
+ }
222
+
223
+ /**
224
+ * Click on Config navigation item in sidebar
225
+ */
226
+ clickNavConfig() {
227
+ cy.get(this.selectors.navConfig).click()
228
+ return this
229
+ }
230
+
231
+ /**
232
+ * Click on "Exit to Dashboard" link
233
+ */
234
+ clickExitToDashboard() {
235
+ cy.get(this.selectors.exitToDashboard).click()
236
+ return this
237
+ }
238
+
239
+ /**
240
+ * Click on "Go to Admin" link
241
+ */
242
+ clickGoToAdmin() {
243
+ cy.get(this.selectors.goToAdmin).click()
244
+ return this
245
+ }
246
+
247
+ // ============================================
248
+ // HOME PAGE QUICK LINKS
249
+ // ============================================
250
+
251
+ /**
252
+ * Click on Style Gallery quick link (home page)
253
+ */
254
+ clickHomeStyleLink() {
255
+ cy.get(this.selectors.homeStyleLink).click()
256
+ return this
257
+ }
258
+
259
+ /**
260
+ * Click on Test Cases quick link (home page)
261
+ */
262
+ clickHomeTestsLink() {
263
+ cy.get(this.selectors.homeTestsLink).click()
264
+ return this
265
+ }
266
+
267
+ /**
268
+ * Click on Config Viewer quick link (home page)
269
+ */
270
+ clickHomeConfigLink() {
271
+ cy.get(this.selectors.homeConfigLink).click()
272
+ return this
273
+ }
274
+
275
+ // ============================================
276
+ // CONFIG VIEWER ACTIONS
277
+ // ============================================
278
+
279
+ /**
280
+ * Click on Theme tab in config viewer
281
+ */
282
+ clickConfigTabTheme() {
283
+ cy.get(this.selectors.configTabTheme).click()
284
+ return this
285
+ }
286
+
287
+ /**
288
+ * Click on Entities tab in config viewer
289
+ */
290
+ clickConfigTabEntities() {
291
+ cy.get(this.selectors.configTabEntities).click()
292
+ return this
293
+ }
294
+
295
+ /**
296
+ * Click copy button for theme config
297
+ */
298
+ clickCopyThemeConfig() {
299
+ cy.get(this.selectors.configCopyTheme).click()
300
+ return this
301
+ }
302
+
303
+ /**
304
+ * Click copy button for entities config
305
+ */
306
+ clickCopyEntitiesConfig() {
307
+ cy.get(this.selectors.configCopyEntities).click()
308
+ return this
309
+ }
310
+
311
+ // ============================================
312
+ // WAITS
313
+ // ============================================
314
+
315
+ /**
316
+ * Wait for /devtools home page to load
317
+ */
318
+ waitForHomePage() {
319
+ cy.get(this.selectors.homePage, { timeout: 10000 }).should('be.visible')
320
+ return this
321
+ }
322
+
323
+ /**
324
+ * Wait for style gallery page to load
325
+ */
326
+ waitForStylePage() {
327
+ cy.get(this.selectors.stylePage, { timeout: 10000 }).should('be.visible')
328
+ return this
329
+ }
330
+
331
+ /**
332
+ * Wait for test cases page to load
333
+ */
334
+ waitForTestsPage() {
335
+ cy.get(this.selectors.testsPage, { timeout: 10000 }).should('be.visible')
336
+ return this
337
+ }
338
+
339
+ /**
340
+ * Wait for config page to load
341
+ */
342
+ waitForConfigPage() {
343
+ cy.get(this.selectors.configPage, { timeout: 10000 }).should('be.visible')
344
+ return this
345
+ }
346
+
347
+ // ============================================
348
+ // ASSERTIONS - URL
349
+ // ============================================
350
+
351
+ /**
352
+ * Assert user is on /devtools home page
353
+ */
354
+ assertOnDevtoolsHome() {
355
+ cy.url().should('eq', Cypress.config().baseUrl + '/devtools')
356
+ return this
357
+ }
358
+
359
+ /**
360
+ * Assert user is on /devtools/style
361
+ */
362
+ assertOnStyleGallery() {
363
+ cy.url().should('include', '/devtools/style')
364
+ return this
365
+ }
366
+
367
+ /**
368
+ * Assert user is on /devtools/tests
369
+ */
370
+ assertOnTestCases() {
371
+ cy.url().should('include', '/devtools/tests')
372
+ return this
373
+ }
374
+
375
+ /**
376
+ * Assert user is on /devtools/config
377
+ */
378
+ assertOnConfig() {
379
+ cy.url().should('include', '/devtools/config')
380
+ return this
381
+ }
382
+
383
+ /**
384
+ * Assert user was redirected to /dashboard (blocked from /devtools)
385
+ */
386
+ assertRedirectedToDashboard() {
387
+ cy.url().should('include', '/dashboard')
388
+ cy.url().should('not.include', '/devtools')
389
+ return this
390
+ }
391
+
392
+ /**
393
+ * Assert user is on /superadmin (superadmin panel)
394
+ */
395
+ assertOnSuperadmin() {
396
+ cy.url().should('include', '/superadmin')
397
+ return this
398
+ }
399
+
400
+ // ============================================
401
+ // ASSERTIONS - PAGE CONTENT
402
+ // ============================================
403
+
404
+ /**
405
+ * Assert home page container is visible
406
+ */
407
+ assertHomePageVisible() {
408
+ cy.get(this.selectors.homePage).should('be.visible')
409
+ return this
410
+ }
411
+
412
+ /**
413
+ * Assert all home page quick links are visible
414
+ */
415
+ assertHomeQuickLinksVisible() {
416
+ cy.get(this.selectors.homeStyleLink).should('be.visible')
417
+ cy.get(this.selectors.homeTestsLink).should('be.visible')
418
+ cy.get(this.selectors.homeConfigLink).should('be.visible')
419
+ return this
420
+ }
421
+
422
+ /**
423
+ * Assert style gallery page is visible
424
+ */
425
+ assertStylePageVisible() {
426
+ cy.get(this.selectors.stylePage).should('be.visible')
427
+ return this
428
+ }
429
+
430
+ /**
431
+ * Assert all style gallery sections are visible by clicking through tabs
432
+ * Tabs work one at a time - Components is default, need to click others
433
+ */
434
+ assertStyleSectionsVisible() {
435
+ // Components tab is active by default
436
+ cy.get(this.selectors.styleComponentGallery).should('be.visible')
437
+
438
+ // Click Field Types tab and verify
439
+ cy.get(this.selectors.styleTabFieldTypes).click()
440
+ cy.get(this.selectors.styleFieldTypes).should('be.visible')
441
+
442
+ // Click Theme tab and verify
443
+ cy.get(this.selectors.styleTabTheme).click()
444
+ cy.get(this.selectors.styleThemePreview).should('be.visible')
445
+
446
+ // Click back to Components tab (restore default state)
447
+ cy.get(this.selectors.styleTabComponents).click()
448
+ return this
449
+ }
450
+
451
+ /**
452
+ * Click Style Gallery Components tab
453
+ */
454
+ clickStyleTabComponents() {
455
+ cy.get(this.selectors.styleTabComponents).click()
456
+ return this
457
+ }
458
+
459
+ /**
460
+ * Click Style Gallery Field Types tab
461
+ */
462
+ clickStyleTabFieldTypes() {
463
+ cy.get(this.selectors.styleTabFieldTypes).click()
464
+ return this
465
+ }
466
+
467
+ /**
468
+ * Click Style Gallery Theme tab
469
+ */
470
+ clickStyleTabTheme() {
471
+ cy.get(this.selectors.styleTabTheme).click()
472
+ return this
473
+ }
474
+
475
+ /**
476
+ * Assert test cases page is visible
477
+ */
478
+ assertTestsPageVisible() {
479
+ cy.get(this.selectors.testsPage).should('be.visible')
480
+ return this
481
+ }
482
+
483
+ /**
484
+ * Assert test cases viewer (file tree) is visible
485
+ */
486
+ assertTestsViewerVisible() {
487
+ cy.get(this.selectors.testsViewer).should('be.visible')
488
+ cy.get(this.selectors.testsTree).should('be.visible')
489
+ return this
490
+ }
491
+
492
+ /**
493
+ * Assert config page is visible
494
+ */
495
+ assertConfigPageVisible() {
496
+ cy.get(this.selectors.configPage).should('be.visible')
497
+ return this
498
+ }
499
+
500
+ /**
501
+ * Assert config viewer tabs are visible
502
+ */
503
+ assertConfigTabsVisible() {
504
+ cy.get(this.selectors.configViewer).should('be.visible')
505
+ cy.get(this.selectors.configTabTheme).should('be.visible')
506
+ cy.get(this.selectors.configTabEntities).should('be.visible')
507
+ return this
508
+ }
509
+
510
+ // ============================================
511
+ // ASSERTIONS - NAVIGATION
512
+ // ============================================
513
+
514
+ /**
515
+ * Assert all sidebar navigation items are visible
516
+ */
517
+ assertSidebarNavigationVisible() {
518
+ cy.get(this.selectors.navHome).should('be.visible')
519
+ cy.get(this.selectors.navStyleGallery).should('be.visible')
520
+ cy.get(this.selectors.navTestCases).should('be.visible')
521
+ cy.get(this.selectors.navConfig).should('be.visible')
522
+ return this
523
+ }
524
+
525
+ /**
526
+ * Assert exit links (Dashboard, Admin) are visible
527
+ */
528
+ assertExitLinksVisible() {
529
+ cy.get(this.selectors.exitToDashboard).should('be.visible')
530
+ cy.get(this.selectors.goToAdmin).should('be.visible')
531
+ return this
532
+ }
533
+
534
+ // ============================================
535
+ // API TESTER METHODS (New Feature)
536
+ // ============================================
537
+
538
+ /**
539
+ * Visit /devtools/api (API endpoint list)
540
+ */
541
+ visitApiList() {
542
+ cy.visit('/devtools/api')
543
+ return this
544
+ }
545
+
546
+ /**
547
+ * Visit specific API endpoint detail page
548
+ * @param path - API path without /api prefix (e.g., '/v1/customers')
549
+ */
550
+ visitApiEndpoint(path: string) {
551
+ cy.visit(`/devtools/api${path}`)
552
+ return this
553
+ }
554
+
555
+ /**
556
+ * Click on an endpoint link in the API list
557
+ * Uses the first endpoint from Core category as default
558
+ */
559
+ clickFirstEndpoint() {
560
+ cy.get('[data-cy^="devtools-api-route-"]').first().click()
561
+ return this
562
+ }
563
+
564
+ /**
565
+ * Select HTTP method in API tester
566
+ */
567
+ selectMethod(method: string) {
568
+ cy.get(this.selectors.apiTesterMethodBadge(method)).click()
569
+ return this
570
+ }
571
+
572
+ /**
573
+ * Fill path parameter input
574
+ */
575
+ fillPathParam(paramName: string, value: string) {
576
+ cy.get(this.selectors.apiTesterPathParamInput(paramName)).clear().type(value)
577
+ return this
578
+ }
579
+
580
+ /**
581
+ * Add query parameter
582
+ */
583
+ addQueryParam(key: string, value: string) {
584
+ cy.get(this.selectors.apiTesterQueryAddBtn).click()
585
+ const index = 0 // Assuming first param for simplicity
586
+ cy.get(this.selectors.apiTesterQueryKey(index)).type(key)
587
+ cy.get(this.selectors.apiTesterQueryValue(index)).type(value)
588
+ return this
589
+ }
590
+
591
+ /**
592
+ * Fill request payload (JSON)
593
+ */
594
+ fillPayload(json: string) {
595
+ cy.get(this.selectors.apiTesterPayloadTextarea).clear().type(json, { parseSpecialCharSequences: false })
596
+ return this
597
+ }
598
+
599
+ /**
600
+ * Select authentication type
601
+ */
602
+ selectAuthType(type: 'session' | 'apiKey') {
603
+ if (type === 'session') {
604
+ cy.get(this.selectors.apiTesterAuthSession).click()
605
+ } else {
606
+ cy.get(this.selectors.apiTesterAuthApiKey).click()
607
+ }
608
+ return this
609
+ }
610
+
611
+ /**
612
+ * Fill API key input
613
+ */
614
+ fillApiKey(apiKey: string) {
615
+ cy.get(this.selectors.apiTesterApiKeyInput).type(apiKey)
616
+ return this
617
+ }
618
+
619
+ /**
620
+ * Click Send Request button
621
+ */
622
+ clickSendRequest() {
623
+ cy.get(this.selectors.apiTesterSendBtn).click()
624
+ return this
625
+ }
626
+
627
+ /**
628
+ * Click Cancel button (during request)
629
+ */
630
+ clickCancelRequest() {
631
+ cy.get(this.selectors.apiTesterCancelBtn).click()
632
+ return this
633
+ }
634
+
635
+ /**
636
+ * Wait for response to appear
637
+ */
638
+ waitForResponse() {
639
+ cy.get(this.selectors.apiTesterResponse, { timeout: 10000 }).should('be.visible')
640
+ return this
641
+ }
642
+
643
+ /**
644
+ * Assert API tester page is visible
645
+ */
646
+ assertApiTesterVisible() {
647
+ cy.get(this.selectors.apiTester).should('be.visible')
648
+ return this
649
+ }
650
+
651
+ /**
652
+ * Assert endpoint info card is visible
653
+ */
654
+ assertEndpointInfoVisible() {
655
+ cy.get(this.selectors.apiTesterEndpointInfo).should('be.visible')
656
+ return this
657
+ }
658
+
659
+ /**
660
+ * Assert method selector shows specific method
661
+ */
662
+ assertMethodExists(method: string) {
663
+ cy.get(this.selectors.apiTesterMethodBadge(method)).should('exist')
664
+ return this
665
+ }
666
+
667
+ /**
668
+ * Assert URL preview contains text
669
+ */
670
+ assertUrlPreviewContains(text: string) {
671
+ cy.get(this.selectors.apiTesterUrlPreview).should('contain', text)
672
+ return this
673
+ }
674
+
675
+ /**
676
+ * Assert payload editor is visible
677
+ */
678
+ assertPayloadEditorVisible() {
679
+ cy.get(this.selectors.apiTesterPayload).should('be.visible')
680
+ return this
681
+ }
682
+
683
+ /**
684
+ * Assert payload editor is NOT visible
685
+ */
686
+ assertPayloadEditorNotVisible() {
687
+ cy.get(this.selectors.apiTesterPayload).should('not.exist')
688
+ return this
689
+ }
690
+
691
+ /**
692
+ * Assert JSON validation error is shown
693
+ */
694
+ assertPayloadErrorShown() {
695
+ cy.get(this.selectors.apiTesterPayloadError).should('be.visible')
696
+ return this
697
+ }
698
+
699
+ /**
700
+ * Assert response status code badge is visible and has correct color
701
+ */
702
+ assertResponseStatus(statusCode: number) {
703
+ cy.get(this.selectors.apiTesterResponseStatus).should('contain', statusCode.toString())
704
+ return this
705
+ }
706
+
707
+ /**
708
+ * Assert response time is visible
709
+ */
710
+ assertResponseTimeVisible() {
711
+ cy.get(this.selectors.apiTesterResponseTime).should('be.visible')
712
+ return this
713
+ }
714
+
715
+ /**
716
+ * Click Response Body tab
717
+ */
718
+ clickResponseBodyTab() {
719
+ cy.get(this.selectors.apiTesterResponseTabBody).click()
720
+ return this
721
+ }
722
+
723
+ /**
724
+ * Click Response Headers tab
725
+ */
726
+ clickResponseHeadersTab() {
727
+ cy.get(this.selectors.apiTesterResponseTabHeaders).click()
728
+ return this
729
+ }
730
+
731
+ /**
732
+ * Assert response body contains text
733
+ */
734
+ assertResponseBodyContains(text: string) {
735
+ cy.get(this.selectors.apiTesterResponseBody).should('contain', text)
736
+ return this
737
+ }
738
+
739
+ /**
740
+ * Assert back button navigates to /devtools/api
741
+ */
742
+ clickBackToList() {
743
+ cy.get(this.selectors.apiTesterBackBtn).click()
744
+ cy.url().should('include', '/devtools/api')
745
+ cy.url().should('not.include', '/devtools/api/')
746
+ return this
747
+ }
748
+ }
749
+
750
+ export default DevtoolsPOM