@nextsparkjs/theme-default 0.1.0-beta.52 → 0.1.0-beta.54

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextsparkjs/theme-default",
3
- "version": "0.1.0-beta.52",
3
+ "version": "0.1.0-beta.54",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./config/theme.config.ts",
@@ -17,8 +17,8 @@
17
17
  "react-dom": "^19.0.0",
18
18
  "react-markdown": "^10.1.0",
19
19
  "zod": "^4.0.0",
20
- "@nextsparkjs/core": "0.1.0-beta.52",
21
- "@nextsparkjs/testing": "0.1.0-beta.52"
20
+ "@nextsparkjs/core": "0.1.0-beta.54",
21
+ "@nextsparkjs/testing": "0.1.0-beta.54"
22
22
  },
23
23
  "nextspark": {
24
24
  "type": "theme",
@@ -2,8 +2,8 @@
2
2
  feature: Dashboard Topnav UI Selectors Validation
3
3
  priority: high
4
4
  tags: [selectors, topnav, dashboard, ui-validation]
5
- grepTags: [ui-selectors, dashboard, topnav, SEL_TNAV_001, SEL_TNAV_002, SEL_TNAV_003, SEL_TNAV_004, SEL_TNAV_005, SEL_TNAV_006]
6
- coverage: 6
5
+ grepTags: [ui-selectors, dashboard, topnav, SEL_TNAV_001, SEL_TNAV_002, SEL_TNAV_003, SEL_TNAV_004, SEL_TNAV_005, SEL_TNAV_006, SEL_TNAV_007]
6
+ coverage: 7
7
7
  ---
8
8
 
9
9
  # Dashboard Topnav UI Selectors Validation
@@ -263,6 +263,53 @@ Then deberia encontrar el indicador de estado de carga del usuario
263
263
 
264
264
  ---
265
265
 
266
+ ## @test SEL_TNAV_007: Settings Menu
267
+
268
+ ### Metadata
269
+ - **Priority:** Medium
270
+ - **Type:** Selector Validation
271
+ - **Tags:** topnav, settings-menu, dropdown
272
+ - **Grep:** `@ui-selectors` `@dashboard` `@topnav` `@SEL_TNAV_007`
273
+ - **Status:** Active (3 passing, 0 skipped)
274
+
275
+ ```gherkin:en
276
+ Scenario: Settings menu opens and shows links
277
+
278
+ Given I am logged in as a developer user
279
+ And the settings menu is enabled in theme config
280
+ And I navigate to the dashboard
281
+ Then I should find the settings menu trigger
282
+ When I click on the settings menu trigger
283
+ Then I should see the settings menu content
284
+ And I should find settings menu links (e.g., patterns)
285
+ ```
286
+
287
+ ```gherkin:es
288
+ Scenario: Menu de configuracion se abre y muestra links
289
+
290
+ Given estoy logueado como usuario developer
291
+ And el menu de configuracion esta habilitado en la config del tema
292
+ And navego al dashboard
293
+ Then deberia encontrar el trigger del menu de configuracion
294
+ When hago click en el trigger del menu de configuracion
295
+ Then deberia ver el contenido del menu de configuracion
296
+ And deberia encontrar links del menu de configuracion (ej. patrones)
297
+ ```
298
+
299
+ ### Expected Results
300
+ | Test ID | Selector Path | POM Accessor | data-cy Value | Status |
301
+ |---------|---------------|--------------|---------------|--------|
302
+ | SEL_TNAV_007_01 | dashboard.topnav.settingsMenu.trigger | dashboard.selectors.topnavSettingsMenuTrigger | topnav-settings-menu-trigger | Implemented |
303
+ | SEL_TNAV_007_02 | dashboard.topnav.settingsMenu.content | dashboard.selectors.topnavSettingsMenuContent | topnav-settings-menu | Implemented |
304
+ | SEL_TNAV_007_03 | dashboard.topnav.settingsMenu.link(index) | dashboard.selectors.topnavSettingsMenuLink(0) | topnav-settings-link-0 | Implemented |
305
+
306
+ ### Notes
307
+ - Settings menu must be enabled in theme config (TOPBAR_CONFIG.settingsMenu)
308
+ - Links are dynamically generated from config
309
+ - Common links include: Patterns
310
+
311
+ ---
312
+
266
313
  ## Related Components
267
314
 
268
315
  | Component | File | Selectors |
@@ -21,6 +21,7 @@
21
21
  * - SEL_TNAV_004: User Menu (5 selectors)
22
22
  * - SEL_TNAV_005: Quick Create (3 selectors)
23
23
  * - SEL_TNAV_006: Loading State (1 skipped - transient state)
24
+ * - SEL_TNAV_007: Settings Menu (3 selectors)
24
25
  *
25
26
  * NOTE: Public navbar tests (logo, signin, signup) are in public.cy.ts
26
27
  */
@@ -149,8 +150,28 @@ describe('Dashboard Topnav Selectors Validation', { tags: ['@ui-selectors', '@da
149
150
  // NOTE: Only visible during auth loading - transient state
150
151
  // ============================================
151
152
  describe('SEL_TNAV_006: Loading State', { tags: '@SEL_TNAV_006' }, () => {
152
- it.skip('should find user loading state (only visible during auth loading)', () => {
153
+ it.skip('SEL_TNAV_006_01: should find user loading state (only visible during auth loading)', { tags: '@SEL_TNAV_006_01' }, () => {
153
154
  cy.get(dashboard.selectors.topnavUserLoading).should('exist')
154
155
  })
155
156
  })
157
+
158
+ // ============================================
159
+ // SEL_TNAV_007: SETTINGS MENU (3 selectors)
160
+ // NOTE: settingsMenu must be enabled in theme config
161
+ // ============================================
162
+ describe('SEL_TNAV_007: Settings Menu', { tags: '@SEL_TNAV_007' }, () => {
163
+ it('SEL_TNAV_007_01: should find settings menu trigger', { tags: '@SEL_TNAV_007_01' }, () => {
164
+ cy.get(dashboard.selectors.topnavSettingsMenuTrigger).should('exist')
165
+ })
166
+
167
+ it('SEL_TNAV_007_02: should find settings menu content when opened', { tags: '@SEL_TNAV_007_02' }, () => {
168
+ cy.get(dashboard.selectors.topnavSettingsMenuTrigger).click()
169
+ cy.get(dashboard.selectors.topnavSettingsMenuContent).should('be.visible')
170
+ })
171
+
172
+ it('SEL_TNAV_007_03: should find settings menu link when opened', { tags: '@SEL_TNAV_007_03' }, () => {
173
+ cy.get(dashboard.selectors.topnavSettingsMenuTrigger).click()
174
+ cy.get(dashboard.selectors.topnavSettingsMenuLink(0)).should('exist')
175
+ })
176
+ })
156
177
  })
@@ -0,0 +1,388 @@
1
+ ---
2
+ feature: Patterns UI Selectors Validation
3
+ priority: high
4
+ tags: [selectors, patterns, ui-validation]
5
+ grepTags: [ui-selectors, patterns, feat-patterns, SEL_PAT_001, SEL_PAT_002, SEL_PAT_003, SEL_PAT_004, SEL_PAT_005, SEL_PAT_006, SEL_PAT_007, SEL_PAT_008]
6
+ coverage: 8
7
+ ---
8
+
9
+ # Patterns UI Selectors Validation
10
+
11
+ > Validates that patterns-specific selectors exist in the DOM. This is a lightweight test that ONLY checks selector presence, not functionality. Validates KEY DIFFERENCES from standard entity editor: no slug input and no patterns tab in block picker.
12
+
13
+ **Login:** Uses Developer via `loginAsDefaultDeveloper()`.
14
+
15
+ **Dependencies:**
16
+ - Sample patterns must exist (from seed data)
17
+ - At least one pattern must have usages (for reports tests)
18
+
19
+ ## @test SEL_PAT_001: Patterns List Page Selectors
20
+
21
+ ### Metadata
22
+ - **Priority:** High
23
+ - **Type:** Selector Validation
24
+ - **Tags:** patterns, list, page
25
+ - **Grep:** `@ui-selectors` `@patterns` `@feat-patterns` `@SEL_PAT_001`
26
+ - **Status:** Active (5 passing, 0 skipped)
27
+
28
+ ```gherkin:en
29
+ Scenario: Patterns list page has complete selector coverage
30
+
31
+ Given I am logged in as a developer user
32
+ And I navigate to the patterns list page
33
+ Then I should find the page container
34
+ And I should find the page title
35
+ And I should find the add button
36
+ And I should find the search container
37
+ And I should find the table container
38
+ ```
39
+
40
+ ```gherkin:es
41
+ Scenario: Pagina de lista de patrones tiene cobertura completa de selectores
42
+
43
+ Given estoy logueado como usuario developer
44
+ And navego a la pagina de lista de patrones
45
+ Then deberia encontrar el contenedor de pagina
46
+ And deberia encontrar el titulo de pagina
47
+ And deberia encontrar el boton de agregar
48
+ And deberia encontrar el contenedor de busqueda
49
+ And deberia encontrar el contenedor de tabla
50
+ ```
51
+
52
+ ### Expected Results
53
+ | Test ID | Selector Path | Status |
54
+ |---------|---------------|--------|
55
+ | SEL_PAT_001_01 | patterns.selectors.page | Implemented |
56
+ | SEL_PAT_001_02 | patterns.selectors.title | Implemented |
57
+ | SEL_PAT_001_03 | patterns.selectors.addBtn | Implemented |
58
+ | SEL_PAT_001_04 | patterns.selectors.searchContainer | Implemented |
59
+ | SEL_PAT_001_05 | patterns.selectors.table | Implemented |
60
+
61
+ ---
62
+
63
+ ## @test SEL_PAT_002: Patterns List Table Actions
64
+
65
+ ### Metadata
66
+ - **Priority:** High
67
+ - **Type:** Selector Validation
68
+ - **Tags:** patterns, list, actions, table
69
+ - **Grep:** `@ui-selectors` `@patterns` `@feat-patterns` `@SEL_PAT_002`
70
+ - **Status:** Active (4 passing, 0 skipped)
71
+
72
+ ```gherkin:en
73
+ Scenario: Patterns list table has all row action selectors
74
+
75
+ Given I am logged in as a developer user
76
+ And I navigate to the patterns list page
77
+ And at least one pattern exists in the database
78
+ Then I should find the row menu for the first pattern
79
+ When I click the row menu
80
+ Then I should find the edit action
81
+ And I should find the delete action
82
+ And I should find the usages quick action
83
+ ```
84
+
85
+ ```gherkin:es
86
+ Scenario: Tabla de lista de patrones tiene todos los selectores de acciones de fila
87
+
88
+ Given estoy logueado como usuario developer
89
+ And navego a la pagina de lista de patrones
90
+ And al menos un patron existe en la base de datos
91
+ Then deberia encontrar el menu de fila del primer patron
92
+ When hago click en el menu de fila
93
+ Then deberia encontrar la accion de editar
94
+ And deberia encontrar la accion de eliminar
95
+ And deberia encontrar la accion rapida de usos
96
+ ```
97
+
98
+ ### Expected Results
99
+ | Test ID | Selector Path | Status |
100
+ |---------|---------------|--------|
101
+ | SEL_PAT_002_01 | patterns.selectors.rowMenu(id) | Implemented |
102
+ | SEL_PAT_002_02 | patterns.selectors.rowAction('edit', id) | Implemented |
103
+ | SEL_PAT_002_03 | patterns.selectors.rowAction('delete', id) | Implemented |
104
+ | SEL_PAT_002_04 | patterns.selectors.rowAction('usages', id) | Implemented |
105
+
106
+ ---
107
+
108
+ ## @test SEL_PAT_003: Patterns Editor Header - KEY DIFFERENCES
109
+
110
+ ### Metadata
111
+ - **Priority:** High
112
+ - **Type:** Selector Validation
113
+ - **Tags:** patterns, editor, header, differences
114
+ - **Grep:** `@ui-selectors` `@patterns` `@feat-patterns` `@SEL_PAT_003`
115
+ - **Status:** Active (5 passing, 0 skipped)
116
+
117
+ ```gherkin:en
118
+ Scenario: Patterns editor header validates key differences from standard editor
119
+
120
+ Given I am logged in as a developer user
121
+ And I navigate to create a new pattern
122
+ And the editor is loaded
123
+ Then I should find the header container
124
+ And I should find the title input
125
+ And I should NOT find the slug input (patterns-specific)
126
+ And I should find the save button
127
+ And I should find the view mode toggle
128
+ ```
129
+
130
+ ```gherkin:es
131
+ Scenario: Header del editor de patrones valida diferencias clave del editor estandar
132
+
133
+ Given estoy logueado como usuario developer
134
+ And navego a crear un nuevo patron
135
+ And el editor esta cargado
136
+ Then deberia encontrar el contenedor del header
137
+ And deberia encontrar el input de titulo
138
+ And NO deberia encontrar el input de slug (especifico de patrones)
139
+ And deberia encontrar el boton de guardar
140
+ And deberia encontrar el toggle de modo de vista
141
+ ```
142
+
143
+ ### Expected Results
144
+ | Test ID | Selector Path | Assertion | Status |
145
+ |---------|---------------|-----------|--------|
146
+ | SEL_PAT_003_01 | blockEditor.header.container | should exist | Implemented |
147
+ | SEL_PAT_003_02 | blockEditor.header.titleInput | should exist | Implemented |
148
+ | SEL_PAT_003_03 | blockEditor.header.slugInput | should NOT exist | **KEY DIFFERENCE** |
149
+ | SEL_PAT_003_04 | blockEditor.header.saveButton | should exist | Implemented |
150
+ | SEL_PAT_003_05 | blockEditor.header.viewToggle | should exist | Implemented |
151
+
152
+ ### Notes
153
+ - **KEY DIFFERENCE:** Patterns do not have slugs, so the slug input should NOT exist.
154
+
155
+ ---
156
+
157
+ ## @test SEL_PAT_004: Patterns Editor Block Picker - KEY DIFFERENCES
158
+
159
+ ### Metadata
160
+ - **Priority:** High
161
+ - **Type:** Selector Validation
162
+ - **Tags:** patterns, editor, block-picker, differences
163
+ - **Grep:** `@ui-selectors` `@patterns` `@feat-patterns` `@SEL_PAT_004`
164
+ - **Status:** Active (5 passing, 0 skipped)
165
+
166
+ ```gherkin:en
167
+ Scenario: Patterns block picker validates key differences from standard editor
168
+
169
+ Given I am logged in as a developer user
170
+ And I navigate to create a new pattern
171
+ And the editor is loaded
172
+ Then I should find the block picker container
173
+ And I should find the blocks tab
174
+ And I should NOT find the patterns tab (patterns-specific)
175
+ And I should find the config tab
176
+ And I should find the search input
177
+ ```
178
+
179
+ ```gherkin:es
180
+ Scenario: Block picker de patrones valida diferencias clave del editor estandar
181
+
182
+ Given estoy logueado como usuario developer
183
+ And navego a crear un nuevo patron
184
+ And el editor esta cargado
185
+ Then deberia encontrar el contenedor del block picker
186
+ And deberia encontrar la pestana de bloques
187
+ And NO deberia encontrar la pestana de patrones (especifico de patrones)
188
+ And deberia encontrar la pestana de configuracion
189
+ And deberia encontrar el input de busqueda
190
+ ```
191
+
192
+ ### Expected Results
193
+ | Test ID | Selector Path | Assertion | Status |
194
+ |---------|---------------|-----------|--------|
195
+ | SEL_PAT_004_01 | blockEditor.blockPicker.container | should exist | Implemented |
196
+ | SEL_PAT_004_02 | blockEditor.blockPicker.tabBlocks | should exist | Implemented |
197
+ | SEL_PAT_004_03 | blockEditor.blockPicker.tabPatterns | should NOT exist | **KEY DIFFERENCE** |
198
+ | SEL_PAT_004_04 | blockEditor.blockPicker.tabConfig | should exist | Implemented |
199
+ | SEL_PAT_004_05 | blockEditor.blockPicker.searchInput | should exist | Implemented |
200
+
201
+ ### Notes
202
+ - **KEY DIFFERENCE:** Patterns cannot contain other patterns (to prevent recursion), so the patterns tab should NOT exist.
203
+
204
+ ---
205
+
206
+ ## @test SEL_PAT_005: Patterns Reports Page
207
+
208
+ ### Metadata
209
+ - **Priority:** Medium
210
+ - **Type:** Selector Validation
211
+ - **Tags:** patterns, reports, usages
212
+ - **Grep:** `@ui-selectors` `@patterns` `@feat-patterns` `@SEL_PAT_005`
213
+ - **Status:** Active (4 passing, 0 skipped)
214
+
215
+ ```gherkin:en
216
+ Scenario: Pattern usages report page has complete structure
217
+
218
+ Given I am logged in as a developer user
219
+ And I navigate to the patterns list page
220
+ And I click the usages action on the first pattern
221
+ Then I should find the report container
222
+ And I should find the back button
223
+ And I should find the page title
224
+ And I should find the edit button
225
+ ```
226
+
227
+ ```gherkin:es
228
+ Scenario: Pagina de reporte de usos de patrones tiene estructura completa
229
+
230
+ Given estoy logueado como usuario developer
231
+ And navego a la pagina de lista de patrones
232
+ And hago click en la accion de usos del primer patron
233
+ Then deberia encontrar el contenedor del reporte
234
+ And deberia encontrar el boton de volver
235
+ And deberia encontrar el titulo de pagina
236
+ And deberia encontrar el boton de editar
237
+ ```
238
+
239
+ ### Expected Results
240
+ | Test ID | Selector Path | Status |
241
+ |---------|---------------|--------|
242
+ | SEL_PAT_005_01 | patterns.patternSelectors.usageReport.container | Implemented |
243
+ | SEL_PAT_005_02 | patterns.selectors.backButton | Implemented |
244
+ | SEL_PAT_005_03 | patterns.selectors.headerTitle | Implemented |
245
+ | SEL_PAT_005_04 | patterns.selectors.editButton | Implemented |
246
+
247
+ ---
248
+
249
+ ## @test SEL_PAT_006: Pattern Usage Stats
250
+
251
+ ### Metadata
252
+ - **Priority:** Medium
253
+ - **Type:** Selector Validation
254
+ - **Tags:** patterns, reports, stats
255
+ - **Grep:** `@ui-selectors` `@patterns` `@feat-patterns` `@SEL_PAT_006`
256
+ - **Status:** Active (3 passing, 0 skipped)
257
+
258
+ ```gherkin:en
259
+ Scenario: Pattern usage stats have all required selectors
260
+
261
+ Given I am logged in as a developer user
262
+ And I navigate to a pattern's usages page
263
+ Then I should find the stats container
264
+ And I should find the total usage card
265
+ And I should find usage by type cards (if usages exist)
266
+ ```
267
+
268
+ ```gherkin:es
269
+ Scenario: Estadisticas de uso de patron tienen todos los selectores requeridos
270
+
271
+ Given estoy logueado como usuario developer
272
+ And navego a la pagina de usos de un patron
273
+ Then deberia encontrar el contenedor de estadisticas
274
+ And deberia encontrar la tarjeta de uso total
275
+ And deberia encontrar las tarjetas de uso por tipo (si existen usos)
276
+ ```
277
+
278
+ ### Expected Results
279
+ | Test ID | Selector Path | Status |
280
+ |---------|---------------|--------|
281
+ | SEL_PAT_006_01 | patterns.patternSelectors.usageStats.container | Implemented |
282
+ | SEL_PAT_006_02 | patterns.patternSelectors.usageStats.total | Implemented |
283
+ | SEL_PAT_006_03 | patterns.patternSelectors.usageStats.byType(type) | Conditional |
284
+
285
+ ---
286
+
287
+ ## @test SEL_PAT_007: Pattern Usage Report Controls
288
+
289
+ ### Metadata
290
+ - **Priority:** Medium
291
+ - **Type:** Selector Validation
292
+ - **Tags:** patterns, reports, controls, pagination
293
+ - **Grep:** `@ui-selectors` `@patterns` `@feat-patterns` `@SEL_PAT_007`
294
+ - **Status:** Active (6 passing, 0 skipped)
295
+
296
+ ```gherkin:en
297
+ Scenario: Pattern usage report controls have all required selectors
298
+
299
+ Given I am logged in as a developer user
300
+ And I navigate to a pattern's usages page
301
+ Then I should find the report container
302
+ And I should find the filter select
303
+ And I should find the pagination container
304
+ And I should find the prev page button
305
+ And I should find the next page button
306
+ And I should find the results info
307
+ ```
308
+
309
+ ```gherkin:es
310
+ Scenario: Controles de reporte de uso de patron tienen todos los selectores requeridos
311
+
312
+ Given estoy logueado como usuario developer
313
+ And navego a la pagina de usos de un patron
314
+ Then deberia encontrar el contenedor del reporte
315
+ And deberia encontrar el select de filtro
316
+ And deberia encontrar el contenedor de paginacion
317
+ And deberia encontrar el boton de pagina anterior
318
+ And deberia encontrar el boton de pagina siguiente
319
+ And deberia encontrar la info de resultados
320
+ ```
321
+
322
+ ### Expected Results
323
+ | Test ID | Selector Path | Status |
324
+ |---------|---------------|--------|
325
+ | SEL_PAT_007_01 | patterns.patternSelectors.usageReport.container | Implemented |
326
+ | SEL_PAT_007_02 | patterns.patternSelectors.usageReport.filterSelect | Implemented |
327
+ | SEL_PAT_007_03 | patterns.patternSelectors.usageReport.pagination | Implemented |
328
+ | SEL_PAT_007_04 | patterns.patternSelectors.usageReport.prevPage | Implemented |
329
+ | SEL_PAT_007_05 | patterns.patternSelectors.usageReport.nextPage | Implemented |
330
+ | SEL_PAT_007_06 | patterns.patternSelectors.usageReport.resultsInfo | Implemented |
331
+
332
+ ---
333
+
334
+ ## @test SEL_PAT_008: Pattern Usage Table
335
+
336
+ ### Metadata
337
+ - **Priority:** Medium
338
+ - **Type:** Selector Validation
339
+ - **Tags:** patterns, reports, table
340
+ - **Grep:** `@ui-selectors` `@patterns` `@feat-patterns` `@SEL_PAT_008`
341
+ - **Status:** Partial (1 passing, 2 skipped)
342
+
343
+ ```gherkin:en
344
+ Scenario: Pattern usage table has all required selectors
345
+
346
+ Given I am logged in as a developer user
347
+ And I navigate to a pattern's usages page
348
+ Then I should find the usage table container (or empty state)
349
+ And I should find usage rows (if pattern has usages)
350
+ And I should find view links in usage rows (if pattern has usages)
351
+ ```
352
+
353
+ ```gherkin:es
354
+ Scenario: Tabla de usos de patron tiene todos los selectores requeridos
355
+
356
+ Given estoy logueado como usuario developer
357
+ And navego a la pagina de usos de un patron
358
+ Then deberia encontrar el contenedor de tabla de usos (o estado vacio)
359
+ And deberia encontrar filas de uso (si el patron tiene usos)
360
+ And deberia encontrar links de ver en filas de uso (si el patron tiene usos)
361
+ ```
362
+
363
+ ### Expected Results
364
+ | Test ID | Selector Path | Status |
365
+ |---------|---------------|--------|
366
+ | SEL_PAT_008_01 | patterns.patternSelectors.usageTable.container/empty | Implemented |
367
+ | SEL_PAT_008_02 | [data-cy^="pattern-usage-row-"] | **Skipped** |
368
+ | SEL_PAT_008_03 | [data-cy^="pattern-usage-view-"] | **Skipped** |
369
+
370
+ ### Notes
371
+ - Tests SEL_PAT_008_02 and SEL_PAT_008_03 are skipped because they require the pattern to have actual usages.
372
+
373
+ ---
374
+
375
+ ## Related Components
376
+
377
+ | Component | File | Key Selectors |
378
+ |-----------|------|---------------|
379
+ | PatternsListPage | `packages/core/src/app/[locale]/(auth)/dashboard/patterns/page.tsx` | page, title, addBtn, table |
380
+ | PatternEditor | `packages/core/src/components/page-builder/PageBuilder.tsx` | header.*, blockPicker.* |
381
+ | PatternUsagesPage | `packages/core/src/app/[locale]/(auth)/dashboard/patterns/[id]/usages/page.tsx` | usageReport.*, usageStats.* |
382
+
383
+ ## Related POMs
384
+
385
+ | POM | File | Usage |
386
+ |-----|------|-------|
387
+ | PatternsPOM | `themes/default/tests/cypress/src/entities/PatternsPOM.ts` | List operations, entity selectors |
388
+ | PageBuilderPOM | `themes/default/tests/cypress/src/features/PageBuilderPOM.ts` | Editor selectors |
@@ -36,7 +36,7 @@ import { PatternsPOM } from '../../../src/entities/PatternsPOM'
36
36
  import { cySelector } from '../../../src/selectors'
37
37
  import { loginAsDefaultDeveloper } from '../../../src/session-helpers'
38
38
 
39
- describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns'] }, () => {
39
+ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns', '@feat-patterns'] }, () => {
40
40
  const patterns = PatternsPOM.create()
41
41
 
42
42
  // ============================================
@@ -49,23 +49,23 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
49
49
  patterns.waitForList()
50
50
  })
51
51
 
52
- it('should find page container', () => {
52
+ it('SEL_PAT_001_01: should find page container', { tags: '@SEL_PAT_001_01' }, () => {
53
53
  cy.get(patterns.selectors.page).should('exist')
54
54
  })
55
55
 
56
- it('should find page title', () => {
56
+ it('SEL_PAT_001_02: should find page title', { tags: '@SEL_PAT_001_02' }, () => {
57
57
  cy.get(patterns.selectors.title).should('exist')
58
58
  })
59
59
 
60
- it('should find add button', () => {
61
- cy.get(patterns.selectors.addBtn).should('exist')
60
+ it('SEL_PAT_001_03: should find add button', { tags: '@SEL_PAT_001_03' }, () => {
61
+ cy.get(patterns.selectors.addButton).should('exist')
62
62
  })
63
63
 
64
- it('should find search container', () => {
64
+ it('SEL_PAT_001_04: should find search container', { tags: '@SEL_PAT_001_04' }, () => {
65
65
  cy.get(patterns.selectors.searchContainer).should('exist')
66
66
  })
67
67
 
68
- it('should find table container', () => {
68
+ it('SEL_PAT_001_05: should find table container', { tags: '@SEL_PAT_001_05' }, () => {
69
69
  cy.get(patterns.selectors.table).should('exist')
70
70
  })
71
71
  })
@@ -81,7 +81,7 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
81
81
  patterns.waitForList()
82
82
  })
83
83
 
84
- it('should find row menu for first pattern', () => {
84
+ it('SEL_PAT_002_01: should find row menu for first pattern', { tags: '@SEL_PAT_002_01' }, () => {
85
85
  // Get first pattern row and find its menu
86
86
  cy.get('[data-cy^="patterns-row-"]').first().then(($row) => {
87
87
  const dataCy = $row.attr('data-cy')
@@ -92,7 +92,7 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
92
92
  })
93
93
  })
94
94
 
95
- it('should find edit action in row menu', () => {
95
+ it('SEL_PAT_002_02: should find edit action in row menu', { tags: '@SEL_PAT_002_02' }, () => {
96
96
  cy.get('[data-cy^="patterns-row-"]').first().then(($row) => {
97
97
  const dataCy = $row.attr('data-cy')
98
98
  const patternId = dataCy?.replace('patterns-row-', '')
@@ -103,7 +103,7 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
103
103
  })
104
104
  })
105
105
 
106
- it('should find delete action in row menu', () => {
106
+ it('SEL_PAT_002_03: should find delete action in row menu', { tags: '@SEL_PAT_002_03' }, () => {
107
107
  cy.get('[data-cy^="patterns-row-"]').first().then(($row) => {
108
108
  const dataCy = $row.attr('data-cy')
109
109
  const patternId = dataCy?.replace('patterns-row-', '')
@@ -114,7 +114,7 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
114
114
  })
115
115
  })
116
116
 
117
- it('should find usages quick action in row menu', () => {
117
+ it('SEL_PAT_002_04: should find usages quick action in row menu', { tags: '@SEL_PAT_002_04' }, () => {
118
118
  cy.get('[data-cy^="patterns-row-"]').first().then(($row) => {
119
119
  const dataCy = $row.attr('data-cy')
120
120
  const patternId = dataCy?.replace('patterns-row-', '')
@@ -139,24 +139,24 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
139
139
  cy.get(cySelector('blockEditor.header.container'), { timeout: 15000 }).should('be.visible')
140
140
  })
141
141
 
142
- it('should find header container', () => {
142
+ it('SEL_PAT_003_01: should find header container', { tags: '@SEL_PAT_003_01' }, () => {
143
143
  cy.get(cySelector('blockEditor.header.container')).should('exist')
144
144
  })
145
145
 
146
- it('should find title input', () => {
146
+ it('SEL_PAT_003_02: should find title input', { tags: '@SEL_PAT_003_02' }, () => {
147
147
  cy.get(cySelector('blockEditor.header.titleInput')).should('exist')
148
148
  })
149
149
 
150
- it('should NOT have slug input (patterns-specific)', () => {
150
+ it('SEL_PAT_003_03: should NOT have slug input (patterns-specific)', { tags: '@SEL_PAT_003_03' }, () => {
151
151
  // KEY DIFFERENCE: Patterns do not have slugs
152
152
  cy.get(cySelector('blockEditor.header.slugInput')).should('not.exist')
153
153
  })
154
154
 
155
- it('should find save button', () => {
155
+ it('SEL_PAT_003_04: should find save button', { tags: '@SEL_PAT_003_04' }, () => {
156
156
  cy.get(cySelector('blockEditor.header.saveButton')).should('exist')
157
157
  })
158
158
 
159
- it('should find view mode toggle', () => {
159
+ it('SEL_PAT_003_05: should find view mode toggle', { tags: '@SEL_PAT_003_05' }, () => {
160
160
  cy.get(cySelector('blockEditor.header.viewToggle')).should('exist')
161
161
  })
162
162
  })
@@ -172,24 +172,24 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
172
172
  cy.get(cySelector('blockEditor.header.container'), { timeout: 15000 }).should('be.visible')
173
173
  })
174
174
 
175
- it('should find block picker container', () => {
175
+ it('SEL_PAT_004_01: should find block picker container', { tags: '@SEL_PAT_004_01' }, () => {
176
176
  cy.get(cySelector('blockEditor.blockPicker.container')).should('exist')
177
177
  })
178
178
 
179
- it('should find blocks tab', () => {
179
+ it('SEL_PAT_004_02: should find blocks tab', { tags: '@SEL_PAT_004_02' }, () => {
180
180
  cy.get(cySelector('blockEditor.blockPicker.tabBlocks')).should('exist')
181
181
  })
182
182
 
183
- it('should NOT have patterns tab (patterns-specific)', () => {
183
+ it('SEL_PAT_004_03: should NOT have patterns tab (patterns-specific)', { tags: '@SEL_PAT_004_03' }, () => {
184
184
  // KEY DIFFERENCE: Patterns cannot contain other patterns (prevent recursion)
185
185
  cy.get(cySelector('blockEditor.blockPicker.tabPatterns')).should('not.exist')
186
186
  })
187
187
 
188
- it('should find config tab', () => {
188
+ it('SEL_PAT_004_04: should find config tab', { tags: '@SEL_PAT_004_04' }, () => {
189
189
  cy.get(cySelector('blockEditor.blockPicker.tabConfig')).should('exist')
190
190
  })
191
191
 
192
- it('should find search input', () => {
192
+ it('SEL_PAT_004_05: should find search input', { tags: '@SEL_PAT_004_05' }, () => {
193
193
  cy.get(cySelector('blockEditor.blockPicker.searchInput')).should('exist')
194
194
  })
195
195
  })
@@ -205,7 +205,7 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
205
205
  patterns.waitForList()
206
206
  })
207
207
 
208
- it('should navigate to pattern usages and find report container', () => {
208
+ it('SEL_PAT_005_01: should navigate to pattern usages and find report container', { tags: '@SEL_PAT_005_01' }, () => {
209
209
  // Click usages action on first pattern
210
210
  cy.get('[data-cy^="patterns-row-"]').first().then(($row) => {
211
211
  const dataCy = $row.attr('data-cy')
@@ -219,7 +219,7 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
219
219
  })
220
220
  })
221
221
 
222
- it('should find back button on usages page', () => {
222
+ it('SEL_PAT_005_02: should find back button on usages page', { tags: '@SEL_PAT_005_02' }, () => {
223
223
  cy.get('[data-cy^="patterns-row-"]').first().then(($row) => {
224
224
  const dataCy = $row.attr('data-cy')
225
225
  const patternId = dataCy?.replace('patterns-row-', '')
@@ -233,7 +233,7 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
233
233
  })
234
234
  })
235
235
 
236
- it('should find page title on usages page', () => {
236
+ it('SEL_PAT_005_03: should find page title on usages page', { tags: '@SEL_PAT_005_03' }, () => {
237
237
  cy.get('[data-cy^="patterns-row-"]').first().then(($row) => {
238
238
  const dataCy = $row.attr('data-cy')
239
239
  const patternId = dataCy?.replace('patterns-row-', '')
@@ -246,7 +246,7 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
246
246
  })
247
247
  })
248
248
 
249
- it('should find edit button on usages page', () => {
249
+ it('SEL_PAT_005_04: should find edit button on usages page', { tags: '@SEL_PAT_005_04' }, () => {
250
250
  cy.get('[data-cy^="patterns-row-"]').first().then(($row) => {
251
251
  const dataCy = $row.attr('data-cy')
252
252
  const patternId = dataCy?.replace('patterns-row-', '')
@@ -280,15 +280,15 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
280
280
  })
281
281
  })
282
282
 
283
- it('should find stats container', () => {
283
+ it('SEL_PAT_006_01: should find stats container', { tags: '@SEL_PAT_006_01' }, () => {
284
284
  cy.get(patterns.patternSelectors.usageStats.container).should('exist')
285
285
  })
286
286
 
287
- it('should find total usage card', () => {
287
+ it('SEL_PAT_006_02: should find total usage card', { tags: '@SEL_PAT_006_02' }, () => {
288
288
  cy.get(patterns.patternSelectors.usageStats.total).should('exist')
289
289
  })
290
290
 
291
- it('should find usage by type cards (if usages exist)', () => {
291
+ it('SEL_PAT_006_03: should find usage by type cards (if usages exist)', { tags: '@SEL_PAT_006_03' }, () => {
292
292
  // This might not exist if pattern has no usages, so check for either stats or loading
293
293
  cy.get('body').then(($body) => {
294
294
  if ($body.find(patterns.patternSelectors.usageStats.byType('pages')).length > 0) {
@@ -323,27 +323,27 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
323
323
  })
324
324
  })
325
325
 
326
- it('should find report container', () => {
326
+ it('SEL_PAT_007_01: should find report container', { tags: '@SEL_PAT_007_01' }, () => {
327
327
  cy.get(patterns.patternSelectors.usageReport.container).should('exist')
328
328
  })
329
329
 
330
- it('should find filter select', () => {
330
+ it('SEL_PAT_007_02: should find filter select', { tags: '@SEL_PAT_007_02' }, () => {
331
331
  cy.get(patterns.patternSelectors.usageReport.filterSelect).should('exist')
332
332
  })
333
333
 
334
- it('should find pagination container', () => {
334
+ it('SEL_PAT_007_03: should find pagination container', { tags: '@SEL_PAT_007_03' }, () => {
335
335
  cy.get(patterns.patternSelectors.usageReport.pagination).should('exist')
336
336
  })
337
337
 
338
- it('should find prev page button', () => {
338
+ it('SEL_PAT_007_04: should find prev page button', { tags: '@SEL_PAT_007_04' }, () => {
339
339
  cy.get(patterns.patternSelectors.usageReport.prevPage).should('exist')
340
340
  })
341
341
 
342
- it('should find next page button', () => {
342
+ it('SEL_PAT_007_05: should find next page button', { tags: '@SEL_PAT_007_05' }, () => {
343
343
  cy.get(patterns.patternSelectors.usageReport.nextPage).should('exist')
344
344
  })
345
345
 
346
- it('should find results info', () => {
346
+ it('SEL_PAT_007_06: should find results info', { tags: '@SEL_PAT_007_06' }, () => {
347
347
  cy.get(patterns.patternSelectors.usageReport.resultsInfo).should('exist')
348
348
  })
349
349
  })
@@ -368,7 +368,7 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
368
368
  })
369
369
  })
370
370
 
371
- it('should find usage table container (or empty state)', () => {
371
+ it('SEL_PAT_008_01: should find usage table container (or empty state)', { tags: '@SEL_PAT_008_01' }, () => {
372
372
  cy.get('body').then(($body) => {
373
373
  // Either the table exists or the empty state
374
374
  if ($body.find(patterns.patternSelectors.usageTable.container).length > 0) {
@@ -379,12 +379,12 @@ describe('Patterns Selectors Validation', { tags: ['@ui-selectors', '@patterns']
379
379
  })
380
380
  })
381
381
 
382
- it.skip('should find usage row (requires pattern with usages)', () => {
382
+ it.skip('SEL_PAT_008_02: should find usage row (requires pattern with usages)', { tags: '@SEL_PAT_008_02' }, () => {
383
383
  // This test requires the pattern to have actual usages
384
384
  cy.get('[data-cy^="pattern-usage-row-"]').first().should('exist')
385
385
  })
386
386
 
387
- it.skip('should find view link in usage row (requires pattern with usages)', () => {
387
+ it.skip('SEL_PAT_008_03: should find view link in usage row (requires pattern with usages)', { tags: '@SEL_PAT_008_03' }, () => {
388
388
  // This test requires the pattern to have actual usages
389
389
  cy.get('[data-cy^="pattern-usage-view-"]').first().should('exist')
390
390
  })
@@ -66,6 +66,11 @@ export class DashboardPOM extends BasePOM {
66
66
  topnavUserLoading: cySelector('dashboard.topnav.userLoading'),
67
67
  topnavSignin: cySelector('dashboard.topnav.signin'),
68
68
  topnavSignup: cySelector('dashboard.topnav.signup'),
69
+ // Topnav settings menu
70
+ topnavSettingsMenuTrigger: cySelector('dashboard.topnav.settingsMenu.trigger'),
71
+ topnavSettingsMenuContent: cySelector('dashboard.topnav.settingsMenu.content'),
72
+ topnavSettingsMenuItem: (index: number) => cySelector('dashboard.topnav.settingsMenu.item', { index }),
73
+ topnavSettingsMenuLink: (index: number) => cySelector('dashboard.topnav.settingsMenu.link', { index }),
69
74
  // Topnav mobile menu
70
75
  topnavMobileMenuToggle: cySelector('dashboard.topnav.mobileMenu.toggle'),
71
76
  topnavMobileMenuContainer: cySelector('dashboard.topnav.mobileMenu.container'),