@nextsparkjs/theme-default 0.1.0-beta.44 → 0.1.0-beta.45
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/components/ai-chat/ChatPanel.tsx +7 -7
- package/components/ai-chat/Message.tsx +2 -2
- package/components/ai-chat/MessageInput.tsx +3 -3
- package/components/ai-chat/MessageList.tsx +3 -3
- package/components/ai-chat/TypingIndicator.tsx +2 -2
- package/entities/customers/api/docs.md +107 -0
- package/entities/customers/api/presets.ts +80 -0
- package/entities/pages/api/docs.md +114 -0
- package/entities/pages/api/presets.ts +72 -0
- package/entities/posts/api/docs.md +120 -0
- package/entities/posts/api/presets.ts +74 -0
- package/entities/tasks/api/docs.md +126 -0
- package/entities/tasks/api/presets.ts +84 -0
- package/lib/selectors.ts +2 -2
- package/messages/de/admin.json +45 -0
- package/messages/en/admin.json +45 -0
- package/messages/es/admin.json +45 -0
- package/messages/fr/admin.json +45 -0
- package/messages/it/admin.json +45 -0
- package/messages/pt/admin.json +45 -0
- package/package.json +3 -3
- package/styles/globals.css +24 -0
- package/tests/cypress/e2e/_utils/selectors/block-editor.bdd.md +491 -0
- package/tests/cypress/e2e/_utils/selectors/block-editor.cy.ts +475 -0
- package/tests/cypress/e2e/_utils/selectors/dashboard-container.cy.ts +52 -0
- package/tests/cypress/e2e/_utils/selectors/dashboard-mobile.cy.ts +14 -14
- package/tests/cypress/e2e/_utils/selectors/dashboard-navigation.cy.ts +3 -3
- package/tests/cypress/e2e/_utils/selectors/dashboard-sidebar.bdd.md +38 -73
- package/tests/cypress/e2e/_utils/selectors/dashboard-sidebar.cy.ts +21 -42
- package/tests/cypress/e2e/_utils/selectors/dashboard-topnav.bdd.md +117 -38
- package/tests/cypress/e2e/_utils/selectors/dashboard-topnav.cy.ts +35 -12
- package/tests/cypress/e2e/_utils/selectors/settings-layout.bdd.md +50 -59
- package/tests/cypress/e2e/_utils/selectors/settings-layout.cy.ts +15 -23
- package/tests/cypress/e2e/_utils/selectors/tasks.bdd.md +395 -155
- package/tests/cypress/e2e/_utils/selectors/tasks.cy.ts +795 -174
- package/tests/cypress/e2e/api/_core/teams/teams-security.cy.ts +415 -0
- package/tests/cypress/e2e/uat/_core/teams/inline-edit.cy.ts +278 -0
- package/tests/cypress/src/core/BlockEditorBasePOM.ts +269 -99
- package/tests/cypress/src/core/DashboardEntityPOM.ts +1 -1
- package/tests/cypress/src/features/DashboardPOM.ts +49 -28
- package/tests/cypress/src/features/PageBuilderPOM.ts +20 -0
- package/tests/cypress/src/features/SettingsPOM.ts +511 -166
- package/tests/cypress/src/features/SuperadminPOM.ts +679 -159
- package/tests/cypress/src/features/index.ts +10 -10
- package/tests/cypress/e2e/_utils/selectors/pages-editor.bdd.md +0 -207
- package/tests/cypress/e2e/_utils/selectors/pages-editor.cy.ts +0 -211
- package/tests/cypress/e2e/_utils/selectors/posts-editor.bdd.md +0 -184
- package/tests/cypress/e2e/_utils/selectors/posts-editor.cy.ts +0 -350
|
@@ -56,102 +56,199 @@ export abstract class BlockEditorBasePOM extends BasePOM {
|
|
|
56
56
|
|
|
57
57
|
get editorSelectors() {
|
|
58
58
|
return {
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
59
|
+
// =========================================================================
|
|
60
|
+
// HEADER - Top bar with title, slug, toggles, and actions
|
|
61
|
+
// =========================================================================
|
|
62
|
+
container: cySelector('blockEditor.header.container'),
|
|
63
|
+
backButton: cySelector('blockEditor.header.backButton'),
|
|
64
|
+
titleInput: cySelector('blockEditor.header.titleInput'),
|
|
65
|
+
slugInput: cySelector('blockEditor.header.slugInput'),
|
|
66
|
+
externalLink: cySelector('blockEditor.header.externalLink'),
|
|
67
|
+
viewModeToggle: cySelector('blockEditor.header.viewToggle'),
|
|
68
|
+
viewEditor: cySelector('blockEditor.header.viewEditor'),
|
|
69
|
+
viewPreview: cySelector('blockEditor.header.viewPreview'),
|
|
70
|
+
saveButton: cySelector('blockEditor.header.saveButton'),
|
|
71
|
+
publishButton: cySelector('blockEditor.header.publishButton'),
|
|
72
|
+
settingsButton: cySelector('blockEditor.header.settingsButton'),
|
|
73
|
+
// Status selector (in header)
|
|
74
|
+
statusSelector: cySelector('blockEditor.header.statusSelector'),
|
|
75
|
+
statusOption: (value: string) =>
|
|
76
|
+
cySelector('blockEditor.header.statusOption', { value }),
|
|
77
|
+
statusDot: cySelector('blockEditor.header.statusDot'),
|
|
78
|
+
statusLabel: cySelector('blockEditor.header.statusLabel'),
|
|
79
|
+
// Locale selector (in header)
|
|
80
|
+
localeSelector: cySelector('blockEditor.header.localeSelector'),
|
|
81
|
+
localeOption: (locale: string) =>
|
|
82
|
+
cySelector('blockEditor.header.localeOption', { locale }),
|
|
83
|
+
|
|
84
|
+
// =========================================================================
|
|
85
|
+
// BLOCK PICKER - Left column "Bloques" tab
|
|
86
|
+
// =========================================================================
|
|
69
87
|
blockPicker: cySelector('blockEditor.blockPicker.container'),
|
|
88
|
+
// Tabs
|
|
89
|
+
tabBlocks: cySelector('blockEditor.blockPicker.tabBlocks'),
|
|
90
|
+
tabConfig: cySelector('blockEditor.blockPicker.tabConfig'),
|
|
91
|
+
tabIndicator: cySelector('blockEditor.blockPicker.tabIndicator'),
|
|
92
|
+
// Search
|
|
93
|
+
searchWrapper: cySelector('blockEditor.blockPicker.searchWrapper'),
|
|
94
|
+
searchIcon: cySelector('blockEditor.blockPicker.searchIcon'),
|
|
70
95
|
blockSearch: cySelector('blockEditor.blockPicker.searchInput'),
|
|
71
|
-
|
|
96
|
+
blockSearchClear: cySelector('blockEditor.blockPicker.searchClear'),
|
|
97
|
+
// Categories
|
|
98
|
+
categoryChips: cySelector('blockEditor.blockPicker.categoryChips'),
|
|
72
99
|
category: (category: string) =>
|
|
73
|
-
cySelector('blockEditor.blockPicker.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
//
|
|
100
|
+
cySelector('blockEditor.blockPicker.categoryChip', { category }),
|
|
101
|
+
// Block cards
|
|
102
|
+
blockItem: (slug: string) => cySelector('blockEditor.blockPicker.blockCard', { slug }),
|
|
103
|
+
blockIcon: (slug: string) => cySelector('blockEditor.blockPicker.blockIcon', { slug }),
|
|
104
|
+
blockName: (slug: string) => cySelector('blockEditor.blockPicker.blockName', { slug }),
|
|
105
|
+
addBlock: (slug: string) => cySelector('blockEditor.blockPicker.addButton', { slug }),
|
|
106
|
+
blockPickerEmpty: cySelector('blockEditor.blockPicker.empty'),
|
|
107
|
+
|
|
108
|
+
// =========================================================================
|
|
109
|
+
// ENTITY FIELDS PANEL - Left column "Configuración" tab
|
|
110
|
+
// =========================================================================
|
|
111
|
+
entityFieldsPanel: cySelector('blockEditor.entityFieldsPanel.container'),
|
|
112
|
+
entityField: (name: string) =>
|
|
113
|
+
cySelector('blockEditor.entityFieldsPanel.field', { name }),
|
|
114
|
+
entityCategoryList: cySelector('blockEditor.entityFieldsPanel.categoryList'),
|
|
115
|
+
entityCategory: (slug: string) =>
|
|
116
|
+
cySelector('blockEditor.entityFieldsPanel.categoryItem', { slug }),
|
|
117
|
+
entityCategoryCheckbox: (slug: string) =>
|
|
118
|
+
cySelector('blockEditor.entityFieldsPanel.categoryCheckbox', { slug }),
|
|
119
|
+
|
|
120
|
+
// =========================================================================
|
|
121
|
+
// LAYOUT CANVAS - Center column - Layout mode (draggable cards)
|
|
122
|
+
// =========================================================================
|
|
123
|
+
layoutCanvas: cySelector('blockEditor.layoutCanvas.container'),
|
|
124
|
+
layoutCanvasEmpty: cySelector('blockEditor.layoutCanvas.empty'),
|
|
125
|
+
layoutDropZone: cySelector('blockEditor.layoutCanvas.dropZone'),
|
|
126
|
+
// Sortable block cards
|
|
127
|
+
sortableBlock: (id: string) =>
|
|
128
|
+
cySelector('blockEditor.layoutCanvas.sortableBlock.container', { id }),
|
|
129
|
+
sortableBlockCard: (id: string) =>
|
|
130
|
+
cySelector('blockEditor.layoutCanvas.sortableBlock.card', { id }),
|
|
131
|
+
dragHandle: (id: string) =>
|
|
132
|
+
cySelector('blockEditor.layoutCanvas.sortableBlock.dragHandle', { id }),
|
|
133
|
+
sortableBlockName: (id: string) =>
|
|
134
|
+
cySelector('blockEditor.layoutCanvas.sortableBlock.name', { id }),
|
|
135
|
+
duplicateBlock: (id: string) =>
|
|
136
|
+
cySelector('blockEditor.layoutCanvas.sortableBlock.duplicateBtn', { id }),
|
|
137
|
+
removeBlock: (id: string) =>
|
|
138
|
+
cySelector('blockEditor.layoutCanvas.sortableBlock.removeBtn', { id }),
|
|
139
|
+
blockError: (id: string) =>
|
|
140
|
+
cySelector('blockEditor.layoutCanvas.sortableBlock.error', { id }),
|
|
141
|
+
// Generic selector for counting all sortable blocks
|
|
142
|
+
sortableBlockGeneric: '[data-cy^="sortable-block-"]',
|
|
143
|
+
|
|
144
|
+
// =========================================================================
|
|
145
|
+
// PREVIEW CANVAS - Center column - Preview mode (real blocks)
|
|
146
|
+
// =========================================================================
|
|
82
147
|
previewCanvas: cySelector('blockEditor.previewCanvas.container'),
|
|
148
|
+
previewWrapper: cySelector('blockEditor.previewCanvas.wrapper'),
|
|
83
149
|
previewCanvasEmpty: cySelector('blockEditor.previewCanvas.empty'),
|
|
84
150
|
previewBlock: (id: string) => cySelector('blockEditor.previewCanvas.block', { id }),
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
151
|
+
previewBlockWrapper: (id: string) =>
|
|
152
|
+
cySelector('blockEditor.previewCanvas.blockWrapper', { id }),
|
|
153
|
+
previewBlockSelected: (id: string) =>
|
|
154
|
+
cySelector('blockEditor.previewCanvas.blockSelected', { id }),
|
|
155
|
+
// Generic selector for counting all preview blocks
|
|
156
|
+
previewBlockGeneric: '[data-cy^="preview-block-"]',
|
|
157
|
+
// Move buttons (legacy selectors for backward compatibility)
|
|
158
|
+
moveUpBtn: (id: string) => `[data-cy="preview-block-${id}-move-up"]`,
|
|
159
|
+
moveDownBtn: (id: string) => `[data-cy="preview-block-${id}-move-down"]`,
|
|
160
|
+
// Floating toolbar
|
|
161
|
+
floatingToolbar: (id: string) =>
|
|
162
|
+
cySelector('blockEditor.previewCanvas.floatingToolbar.container', { id }),
|
|
163
|
+
floatingToolbarDrag: (id: string) =>
|
|
164
|
+
cySelector('blockEditor.previewCanvas.floatingToolbar.dragHandle', { id }),
|
|
165
|
+
floatingToolbarName: (id: string) =>
|
|
166
|
+
cySelector('blockEditor.previewCanvas.floatingToolbar.blockName', { id }),
|
|
167
|
+
floatingToolbarDuplicate: (id: string) =>
|
|
168
|
+
cySelector('blockEditor.previewCanvas.floatingToolbar.duplicateBtn', { id }),
|
|
169
|
+
floatingToolbarDelete: (id: string) =>
|
|
170
|
+
cySelector('blockEditor.previewCanvas.floatingToolbar.deleteBtn', { id }),
|
|
171
|
+
|
|
172
|
+
// =========================================================================
|
|
173
|
+
// ENTITY META PANEL - SEO and custom fields
|
|
174
|
+
// =========================================================================
|
|
175
|
+
entityMetaPanel: cySelector('blockEditor.entityMetaPanel.container'),
|
|
176
|
+
// SEO section
|
|
177
|
+
seoTrigger: cySelector('blockEditor.entityMetaPanel.seoSection.trigger'),
|
|
178
|
+
seoContent: cySelector('blockEditor.entityMetaPanel.seoSection.content'),
|
|
179
|
+
metaTitle: cySelector('blockEditor.entityMetaPanel.seoSection.metaTitle'),
|
|
180
|
+
metaDescription: cySelector('blockEditor.entityMetaPanel.seoSection.metaDescription'),
|
|
181
|
+
metaKeywords: cySelector('blockEditor.entityMetaPanel.seoSection.metaKeywords'),
|
|
182
|
+
ogImage: cySelector('blockEditor.entityMetaPanel.seoSection.ogImage'),
|
|
183
|
+
// Custom fields section
|
|
184
|
+
customFieldsTrigger: cySelector('blockEditor.entityMetaPanel.customFields.trigger'),
|
|
185
|
+
customFieldsContent: cySelector('blockEditor.entityMetaPanel.customFields.content'),
|
|
113
186
|
customFieldKey: (index: number) =>
|
|
114
|
-
cySelector('blockEditor.
|
|
187
|
+
cySelector('blockEditor.entityMetaPanel.customFields.fieldKey', { index }),
|
|
115
188
|
customFieldValue: (index: number) =>
|
|
116
|
-
cySelector('blockEditor.
|
|
189
|
+
cySelector('blockEditor.entityMetaPanel.customFields.fieldValue', { index }),
|
|
117
190
|
customFieldRemove: (index: number) =>
|
|
118
|
-
cySelector('blockEditor.
|
|
119
|
-
addCustomField: cySelector('blockEditor.
|
|
120
|
-
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
191
|
+
cySelector('blockEditor.entityMetaPanel.customFields.fieldRemove', { index }),
|
|
192
|
+
addCustomField: cySelector('blockEditor.entityMetaPanel.customFields.addButton'),
|
|
193
|
+
|
|
194
|
+
// =========================================================================
|
|
195
|
+
// BLOCK PROPERTIES PANEL - Right column
|
|
196
|
+
// =========================================================================
|
|
197
|
+
blockPropertiesPanel: cySelector('blockEditor.blockPropertiesPanel.container'),
|
|
198
|
+
blockPropertiesHeader: cySelector('blockEditor.blockPropertiesPanel.header'),
|
|
199
|
+
blockPropertiesClose: cySelector('blockEditor.blockPropertiesPanel.closeBtn'),
|
|
200
|
+
blockPropertiesIcon: cySelector('blockEditor.blockPropertiesPanel.blockIcon'),
|
|
201
|
+
blockPropertiesName: cySelector('blockEditor.blockPropertiesPanel.blockName'),
|
|
202
|
+
blockPropertiesTabs: cySelector('blockEditor.blockPropertiesPanel.tabs'),
|
|
203
|
+
tabContent: cySelector('blockEditor.blockPropertiesPanel.tabContent'),
|
|
204
|
+
tabDesign: cySelector('blockEditor.blockPropertiesPanel.tabDesign'),
|
|
205
|
+
tabAdvanced: cySelector('blockEditor.blockPropertiesPanel.tabAdvanced'),
|
|
206
|
+
blockPropertiesEmpty: cySelector('blockEditor.blockPropertiesPanel.empty'),
|
|
207
|
+
blockPropertiesError: cySelector('blockEditor.blockPropertiesPanel.error'),
|
|
208
|
+
// Dynamic form
|
|
209
|
+
dynamicForm: cySelector('blockEditor.blockPropertiesPanel.form.container'),
|
|
128
210
|
dynamicField: (name: string) =>
|
|
129
|
-
cySelector('blockEditor.
|
|
211
|
+
cySelector('blockEditor.blockPropertiesPanel.form.field', { name }),
|
|
212
|
+
/** @deprecated Use dynamicField instead */
|
|
213
|
+
fieldInput: (name: string) =>
|
|
214
|
+
cySelector('blockEditor.blockPropertiesPanel.form.field', { name }),
|
|
130
215
|
fieldGroup: (id: string) =>
|
|
131
|
-
cySelector('blockEditor.
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
// Array Field
|
|
216
|
+
cySelector('blockEditor.blockPropertiesPanel.form.fieldGroup', { id }),
|
|
217
|
+
// Reset props button (legacy selector)
|
|
218
|
+
resetPropsBtn: '[data-cy="reset-block-props"]',
|
|
219
|
+
// Array field
|
|
136
220
|
arrayFieldContainer: (name: string) =>
|
|
137
|
-
cySelector('blockEditor.arrayField.container', { name }),
|
|
138
|
-
arrayFieldItem: (name: string, index: number
|
|
139
|
-
cySelector('blockEditor.arrayField.item', { name, index
|
|
221
|
+
cySelector('blockEditor.blockPropertiesPanel.form.arrayField.container', { name }),
|
|
222
|
+
arrayFieldItem: (name: string, index: number) =>
|
|
223
|
+
cySelector('blockEditor.blockPropertiesPanel.form.arrayField.item', { name, index }),
|
|
224
|
+
arrayFieldItemField: (name: string, index: number, field: string) =>
|
|
225
|
+
cySelector('blockEditor.blockPropertiesPanel.form.arrayField.itemField', { name, index, field }),
|
|
140
226
|
arrayFieldMoveUp: (name: string, index: number) =>
|
|
141
|
-
cySelector('blockEditor.arrayField.
|
|
227
|
+
cySelector('blockEditor.blockPropertiesPanel.form.arrayField.itemMoveUp', { name, index }),
|
|
142
228
|
arrayFieldMoveDown: (name: string, index: number) =>
|
|
143
|
-
cySelector('blockEditor.arrayField.
|
|
229
|
+
cySelector('blockEditor.blockPropertiesPanel.form.arrayField.itemMoveDown', { name, index }),
|
|
144
230
|
arrayFieldRemove: (name: string, index: number) =>
|
|
145
|
-
cySelector('blockEditor.arrayField.
|
|
231
|
+
cySelector('blockEditor.blockPropertiesPanel.form.arrayField.itemRemove', { name, index }),
|
|
146
232
|
arrayFieldAdd: (name: string) =>
|
|
147
|
-
cySelector('blockEditor.arrayField.
|
|
148
|
-
|
|
149
|
-
//
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
233
|
+
cySelector('blockEditor.blockPropertiesPanel.form.arrayField.addButton', { name }),
|
|
234
|
+
|
|
235
|
+
// =========================================================================
|
|
236
|
+
// LEGACY ALIASES (for backward compatibility - will be removed)
|
|
237
|
+
// =========================================================================
|
|
238
|
+
/** @deprecated Use layoutCanvas instead */
|
|
239
|
+
blockCanvas: cySelector('blockEditor.layoutCanvas.container'),
|
|
240
|
+
/** @deprecated Use layoutCanvasEmpty instead */
|
|
241
|
+
blockCanvasEmpty: cySelector('blockEditor.layoutCanvas.empty'),
|
|
242
|
+
/** @deprecated Use blockPropertiesPanel instead */
|
|
243
|
+
settingsPanel: cySelector('blockEditor.blockPropertiesPanel.container'),
|
|
244
|
+
/** @deprecated Use blockPropertiesEmpty instead */
|
|
245
|
+
settingsPanelEmpty: cySelector('blockEditor.blockPropertiesPanel.empty'),
|
|
246
|
+
/** @deprecated Use blockPropertiesError instead */
|
|
247
|
+
settingsPanelError: cySelector('blockEditor.blockPropertiesPanel.error'),
|
|
248
|
+
/** @deprecated Use entityMetaPanel instead */
|
|
249
|
+
pageSettings: cySelector('blockEditor.entityMetaPanel.container'),
|
|
250
|
+
/** @deprecated Use entityFieldsPanel instead */
|
|
251
|
+
entityFieldsSidebar: cySelector('blockEditor.entityFieldsPanel.container'),
|
|
155
252
|
}
|
|
156
253
|
}
|
|
157
254
|
|
|
@@ -183,6 +280,13 @@ export abstract class BlockEditorBasePOM extends BasePOM {
|
|
|
183
280
|
return this
|
|
184
281
|
}
|
|
185
282
|
|
|
283
|
+
/**
|
|
284
|
+
* Alias for waitForEditor (legacy compatibility)
|
|
285
|
+
*/
|
|
286
|
+
waitForEditorLoad() {
|
|
287
|
+
return this.waitForEditor()
|
|
288
|
+
}
|
|
289
|
+
|
|
186
290
|
waitForSave() {
|
|
187
291
|
this.api.waitForUpdate()
|
|
188
292
|
return this
|
|
@@ -236,18 +340,51 @@ export abstract class BlockEditorBasePOM extends BasePOM {
|
|
|
236
340
|
}
|
|
237
341
|
|
|
238
342
|
/**
|
|
239
|
-
* Toggle
|
|
343
|
+
* Toggle view mode (edit/preview)
|
|
240
344
|
*/
|
|
241
|
-
|
|
242
|
-
cy.get(this.editorSelectors.
|
|
345
|
+
toggleViewMode() {
|
|
346
|
+
cy.get(this.editorSelectors.viewModeToggle).click()
|
|
243
347
|
return this
|
|
244
348
|
}
|
|
245
349
|
|
|
246
350
|
/**
|
|
247
|
-
*
|
|
351
|
+
* Switch to Layout/Editor mode
|
|
248
352
|
*/
|
|
249
|
-
|
|
250
|
-
cy.get(this.editorSelectors.
|
|
353
|
+
switchToLayoutMode() {
|
|
354
|
+
cy.get(this.editorSelectors.viewEditor).click()
|
|
355
|
+
// Wait for layout canvas OR empty state to render (depends on whether blocks exist)
|
|
356
|
+
cy.get('body').then(($body) => {
|
|
357
|
+
// Either the canvas with blocks or the empty state should exist
|
|
358
|
+
if ($body.find(this.editorSelectors.layoutCanvas).length > 0) {
|
|
359
|
+
cy.get(this.editorSelectors.layoutCanvas, { timeout: 5000 }).should('exist')
|
|
360
|
+
} else {
|
|
361
|
+
cy.get(this.editorSelectors.layoutCanvasEmpty, { timeout: 5000 }).should('exist')
|
|
362
|
+
}
|
|
363
|
+
})
|
|
364
|
+
return this
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Switch to Preview mode
|
|
369
|
+
*/
|
|
370
|
+
switchToPreviewMode() {
|
|
371
|
+
cy.get(this.editorSelectors.viewPreview).click()
|
|
372
|
+
return this
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Select Blocks tab in left sidebar
|
|
377
|
+
*/
|
|
378
|
+
selectBlocksTab() {
|
|
379
|
+
cy.get(this.editorSelectors.tabBlocks).click()
|
|
380
|
+
return this
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Select Config/Fields tab in left sidebar
|
|
385
|
+
*/
|
|
386
|
+
selectConfigTab() {
|
|
387
|
+
cy.get(this.editorSelectors.tabConfig).click()
|
|
251
388
|
return this
|
|
252
389
|
}
|
|
253
390
|
|
|
@@ -283,7 +420,7 @@ export abstract class BlockEditorBasePOM extends BasePOM {
|
|
|
283
420
|
* Select "All" category
|
|
284
421
|
*/
|
|
285
422
|
selectAllCategories() {
|
|
286
|
-
cy.get(this.editorSelectors.
|
|
423
|
+
cy.get(this.editorSelectors.category('all')).click()
|
|
287
424
|
return this
|
|
288
425
|
}
|
|
289
426
|
|
|
@@ -335,7 +472,7 @@ export abstract class BlockEditorBasePOM extends BasePOM {
|
|
|
335
472
|
* Move block up in preview
|
|
336
473
|
*/
|
|
337
474
|
moveBlockUp(blockId: string) {
|
|
338
|
-
cy.get(this.editorSelectors.
|
|
475
|
+
cy.get(this.editorSelectors.moveUpBtn(blockId)).click()
|
|
339
476
|
return this
|
|
340
477
|
}
|
|
341
478
|
|
|
@@ -343,7 +480,7 @@ export abstract class BlockEditorBasePOM extends BasePOM {
|
|
|
343
480
|
* Move block down in preview
|
|
344
481
|
*/
|
|
345
482
|
moveBlockDown(blockId: string) {
|
|
346
|
-
cy.get(this.editorSelectors.
|
|
483
|
+
cy.get(this.editorSelectors.moveDownBtn(blockId)).click()
|
|
347
484
|
return this
|
|
348
485
|
}
|
|
349
486
|
|
|
@@ -379,24 +516,23 @@ export abstract class BlockEditorBasePOM extends BasePOM {
|
|
|
379
516
|
* Reset block props to defaults
|
|
380
517
|
*/
|
|
381
518
|
resetBlockProps() {
|
|
382
|
-
cy.get(this.editorSelectors.
|
|
519
|
+
cy.get(this.editorSelectors.resetPropsBtn).click()
|
|
383
520
|
return this
|
|
384
521
|
}
|
|
385
522
|
|
|
386
523
|
/**
|
|
387
|
-
*
|
|
524
|
+
* Fill a dynamic form field
|
|
388
525
|
*/
|
|
389
|
-
|
|
390
|
-
cy.get(this.editorSelectors.
|
|
526
|
+
fillDynamicField(name: string, value: string) {
|
|
527
|
+
cy.get(this.editorSelectors.dynamicField(name)).find('input, textarea').clear().type(value)
|
|
391
528
|
return this
|
|
392
529
|
}
|
|
393
530
|
|
|
394
531
|
/**
|
|
395
|
-
*
|
|
532
|
+
* Alias for fillDynamicField (legacy compatibility)
|
|
396
533
|
*/
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
return this
|
|
534
|
+
fillField(name: string, value: string) {
|
|
535
|
+
return this.fillDynamicField(name, value)
|
|
400
536
|
}
|
|
401
537
|
|
|
402
538
|
// ============================================
|
|
@@ -549,10 +685,10 @@ export abstract class BlockEditorBasePOM extends BasePOM {
|
|
|
549
685
|
}
|
|
550
686
|
|
|
551
687
|
/**
|
|
552
|
-
* Assert status
|
|
688
|
+
* Assert status label shows specific status
|
|
553
689
|
*/
|
|
554
690
|
assertStatus(status: string) {
|
|
555
|
-
cy.get(this.editorSelectors.
|
|
691
|
+
cy.get(this.editorSelectors.statusLabel).should('contain.text', status)
|
|
556
692
|
return this
|
|
557
693
|
}
|
|
558
694
|
|
|
@@ -571,6 +707,40 @@ export abstract class BlockEditorBasePOM extends BasePOM {
|
|
|
571
707
|
cy.get(this.editorSelectors.settingsPanelEmpty).should('be.visible')
|
|
572
708
|
return this
|
|
573
709
|
}
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* Assert block count in canvas
|
|
713
|
+
*/
|
|
714
|
+
assertBlockCount(count: number) {
|
|
715
|
+
cy.get('[data-cy^="sortable-block-"]').should('have.length', count)
|
|
716
|
+
return this
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* Assert preview block count
|
|
721
|
+
*/
|
|
722
|
+
assertPreviewBlockCount(count: number) {
|
|
723
|
+
cy.get('[data-cy^="preview-block-"]').should('have.length', count)
|
|
724
|
+
return this
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Assert block is visible in picker
|
|
729
|
+
*/
|
|
730
|
+
assertBlockInPicker(blockSlug: string) {
|
|
731
|
+
cy.get(this.editorSelectors.blockItem(blockSlug))
|
|
732
|
+
.scrollIntoView()
|
|
733
|
+
.should('be.visible')
|
|
734
|
+
return this
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
/**
|
|
738
|
+
* Assert block picker is visible
|
|
739
|
+
*/
|
|
740
|
+
assertBlockPickerVisible() {
|
|
741
|
+
cy.get(this.editorSelectors.blockPicker).should('be.visible')
|
|
742
|
+
return this
|
|
743
|
+
}
|
|
574
744
|
}
|
|
575
745
|
|
|
576
746
|
export default BlockEditorBasePOM
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import { DashboardEntityPOMCore, type EntityConfig } from '@nextsparkjs/testing/pom'
|
|
25
|
-
import { type Replacements } from '@nextsparkjs/
|
|
25
|
+
import { type Replacements } from '@nextsparkjs/core/selectors'
|
|
26
26
|
import { cySelector } from '../selectors'
|
|
27
27
|
|
|
28
28
|
export abstract class DashboardEntityPOM extends DashboardEntityPOMCore {
|
|
@@ -34,71 +34,92 @@ export class DashboardPOM extends BasePOM {
|
|
|
34
34
|
|
|
35
35
|
get selectors() {
|
|
36
36
|
return {
|
|
37
|
+
// Main container
|
|
38
|
+
container: cySelector('dashboard.container'),
|
|
39
|
+
|
|
37
40
|
// Navigation
|
|
38
|
-
|
|
41
|
+
navContainer: cySelector('dashboard.navigation.container'),
|
|
39
42
|
navDashboard: cySelector('dashboard.navigation.dashboardLink'),
|
|
40
43
|
navEntity: (slug: string) => cySelector('dashboard.navigation.entityLink', { slug }),
|
|
41
44
|
navSection: (id: string) => cySelector('dashboard.navigation.section', { id }),
|
|
42
45
|
navSectionLabel: (id: string) => cySelector('dashboard.navigation.sectionLabel', { id }),
|
|
43
46
|
navSectionItem: (sectionId: string, itemId: string) => cySelector('dashboard.navigation.sectionItem', { sectionId, itemId }),
|
|
44
47
|
|
|
45
|
-
// Shell
|
|
46
|
-
shellContainer: cySelector('dashboard.shell.container'),
|
|
47
|
-
sidebarToggle: cySelector('dashboard.shell.sidebarToggle'),
|
|
48
|
-
quickCreateButton: cySelector('dashboard.shell.quickCreateButton'),
|
|
49
|
-
quickCreateDropdown: cySelector('dashboard.shell.quickCreateDropdown'),
|
|
50
|
-
quickCreateLink: (slug: string) => cySelector('dashboard.shell.quickCreateLink', { slug }),
|
|
51
|
-
|
|
52
48
|
// Topnav
|
|
49
|
+
topnavContainer: cySelector('dashboard.topnav.container'),
|
|
53
50
|
topnavSidebarToggle: cySelector('dashboard.topnav.sidebarToggle'),
|
|
54
|
-
topnavHeader: cySelector('dashboard.topnav.header'),
|
|
55
51
|
topnavLogo: cySelector('dashboard.topnav.logo'),
|
|
56
|
-
|
|
52
|
+
topnavSearchContainer: cySelector('dashboard.topnav.search.container'),
|
|
57
53
|
topnavActions: cySelector('dashboard.topnav.actions'),
|
|
58
|
-
|
|
54
|
+
topnavNotificationsTrigger: cySelector('dashboard.topnav.notifications.trigger'),
|
|
55
|
+
topnavQuickCreateTrigger: cySelector('dashboard.topnav.quickCreate.trigger'),
|
|
56
|
+
topnavQuickCreateContent: cySelector('dashboard.topnav.quickCreate.content'),
|
|
57
|
+
topnavQuickCreateLink: (slug: string) => cySelector('dashboard.topnav.quickCreate.link', { slug }),
|
|
58
|
+
topnavUserMenuTrigger: cySelector('dashboard.topnav.userMenu.trigger'),
|
|
59
|
+
topnavUserMenuContent: cySelector('dashboard.topnav.userMenu.content'),
|
|
60
|
+
topnavUserMenuItem: (icon: string) => cySelector('dashboard.topnav.userMenu.item', { icon }),
|
|
61
|
+
topnavUserMenuAction: (action: string) => cySelector('dashboard.topnav.userMenu.action', { action }),
|
|
59
62
|
topnavHelp: cySelector('dashboard.topnav.help'),
|
|
60
63
|
topnavThemeToggle: cySelector('dashboard.topnav.themeToggle'),
|
|
61
64
|
topnavSuperadmin: cySelector('dashboard.topnav.superadmin'),
|
|
62
65
|
topnavDevtools: cySelector('dashboard.topnav.devtools'),
|
|
63
|
-
topnavUserMenuTrigger: cySelector('dashboard.topnav.userMenuTrigger'),
|
|
64
|
-
topnavUserMenu: cySelector('dashboard.topnav.userMenu'),
|
|
65
|
-
topnavMenuItem: (icon: string) => cySelector('dashboard.topnav.menuItem', { icon }),
|
|
66
|
-
topnavMenuAction: (action: string) => cySelector('dashboard.topnav.menuAction', { action }),
|
|
67
66
|
topnavUserLoading: cySelector('dashboard.topnav.userLoading'),
|
|
68
67
|
topnavSignin: cySelector('dashboard.topnav.signin'),
|
|
69
68
|
topnavSignup: cySelector('dashboard.topnav.signup'),
|
|
69
|
+
// Topnav mobile menu
|
|
70
|
+
topnavMobileMenuToggle: cySelector('dashboard.topnav.mobileMenu.toggle'),
|
|
71
|
+
topnavMobileMenuContainer: cySelector('dashboard.topnav.mobileMenu.container'),
|
|
72
|
+
topnavMobileMenuActions: cySelector('dashboard.topnav.mobileMenu.actions'),
|
|
73
|
+
topnavMobileMenuUserInfo: cySelector('dashboard.topnav.mobileMenu.userInfo'),
|
|
74
|
+
topnavMobileMenuLinkProfile: cySelector('dashboard.topnav.mobileMenu.linkProfile'),
|
|
75
|
+
topnavMobileMenuLinkSettings: cySelector('dashboard.topnav.mobileMenu.linkSettings'),
|
|
76
|
+
topnavMobileMenuLinkBilling: cySelector('dashboard.topnav.mobileMenu.linkBilling'),
|
|
77
|
+
topnavMobileMenuSignout: cySelector('dashboard.topnav.mobileMenu.signout'),
|
|
78
|
+
topnavMobileMenuSuperadmin: cySelector('dashboard.topnav.mobileMenu.superadmin'),
|
|
79
|
+
topnavMobileMenuDevtools: cySelector('dashboard.topnav.mobileMenu.devtools'),
|
|
70
80
|
|
|
71
81
|
// Sidebar
|
|
72
|
-
|
|
82
|
+
sidebarContainer: cySelector('dashboard.sidebar.container'),
|
|
73
83
|
sidebarHeader: cySelector('dashboard.sidebar.header'),
|
|
84
|
+
sidebarLogo: cySelector('dashboard.sidebar.logo'),
|
|
74
85
|
sidebarContent: cySelector('dashboard.sidebar.content'),
|
|
75
86
|
sidebarFooter: cySelector('dashboard.sidebar.footer'),
|
|
76
87
|
|
|
77
88
|
// Mobile Topbar
|
|
78
|
-
|
|
89
|
+
mobileTopbarContainer: cySelector('dashboard.mobile.topbar.container'),
|
|
79
90
|
mobileTopbarUserProfile: cySelector('dashboard.mobile.topbar.userProfile'),
|
|
80
91
|
mobileTopbarNotifications: cySelector('dashboard.mobile.topbar.notifications'),
|
|
81
92
|
mobileTopbarThemeToggle: cySelector('dashboard.mobile.topbar.themeToggle'),
|
|
82
93
|
|
|
83
94
|
// Mobile Bottom Nav
|
|
84
|
-
|
|
95
|
+
mobileBottomNavContainer: cySelector('dashboard.mobile.bottomNav.container'),
|
|
85
96
|
mobileBottomNavItem: (id: string) => cySelector('dashboard.mobile.bottomNav.item', { id }),
|
|
86
97
|
|
|
87
98
|
// Mobile More Sheet
|
|
88
|
-
|
|
99
|
+
mobileMoreSheetContainer: cySelector('dashboard.mobile.moreSheet.container'),
|
|
89
100
|
mobileMoreSheetItem: (id: string) => cySelector('dashboard.mobile.moreSheet.item', { id }),
|
|
90
|
-
|
|
101
|
+
mobileMoreSheetSuperadminLink: cySelector('dashboard.mobile.moreSheet.superadminLink'),
|
|
91
102
|
mobileMoreSheetTeamSwitcher: cySelector('dashboard.mobile.moreSheet.teamSwitcher'),
|
|
92
|
-
|
|
103
|
+
mobileMoreSheetSignoutButton: cySelector('dashboard.mobile.moreSheet.signoutButton'),
|
|
93
104
|
|
|
94
|
-
// Mobile Quick Create
|
|
95
|
-
|
|
96
|
-
|
|
105
|
+
// Mobile Quick Create Sheet
|
|
106
|
+
mobileQuickCreateSheetContainer: cySelector('dashboard.mobile.quickCreateSheet.container'),
|
|
107
|
+
mobileQuickCreateSheetItem: (slug: string) => cySelector('dashboard.mobile.quickCreateSheet.item', { slug }),
|
|
97
108
|
|
|
98
109
|
// Entity table (for verifying entity pages)
|
|
99
110
|
entityPage: (slug: string) => cySelector('entities.page.container', { slug }),
|
|
100
111
|
entityTable: (slug: string) => cySelector('entities.table.container', { slug }),
|
|
101
112
|
entityAddButton: (slug: string) => cySelector('entities.table.addButton', { slug }),
|
|
113
|
+
|
|
114
|
+
// Legacy aliases (for backward compatibility during transition)
|
|
115
|
+
/** @deprecated Use navContainer instead */
|
|
116
|
+
navMain: cySelector('dashboard.navigation.container'),
|
|
117
|
+
/** @deprecated Use topnavQuickCreateTrigger instead */
|
|
118
|
+
quickCreateButton: cySelector('dashboard.topnav.quickCreate.trigger'),
|
|
119
|
+
/** @deprecated Use topnavQuickCreateContent instead */
|
|
120
|
+
quickCreateDropdown: cySelector('dashboard.topnav.quickCreate.content'),
|
|
121
|
+
/** @deprecated Use topnavQuickCreateLink instead */
|
|
122
|
+
quickCreateLink: (slug: string) => cySelector('dashboard.topnav.quickCreate.link', { slug }),
|
|
102
123
|
}
|
|
103
124
|
}
|
|
104
125
|
|
|
@@ -146,7 +167,7 @@ export class DashboardPOM extends BasePOM {
|
|
|
146
167
|
* Open quick create dropdown
|
|
147
168
|
*/
|
|
148
169
|
openQuickCreate() {
|
|
149
|
-
cy.get(this.selectors.
|
|
170
|
+
cy.get(this.selectors.topnavQuickCreateTrigger).click()
|
|
150
171
|
return this
|
|
151
172
|
}
|
|
152
173
|
|
|
@@ -155,7 +176,7 @@ export class DashboardPOM extends BasePOM {
|
|
|
155
176
|
*/
|
|
156
177
|
quickCreate(slug: string) {
|
|
157
178
|
this.openQuickCreate()
|
|
158
|
-
cy.get(this.selectors.
|
|
179
|
+
cy.get(this.selectors.topnavQuickCreateLink(slug)).click()
|
|
159
180
|
return this
|
|
160
181
|
}
|
|
161
182
|
|
|
@@ -215,7 +236,7 @@ export class DashboardPOM extends BasePOM {
|
|
|
215
236
|
* Assert quick create button is visible
|
|
216
237
|
*/
|
|
217
238
|
assertQuickCreateVisible() {
|
|
218
|
-
cy.get(this.selectors.
|
|
239
|
+
cy.get(this.selectors.topnavQuickCreateTrigger).should('be.visible')
|
|
219
240
|
return this
|
|
220
241
|
}
|
|
221
242
|
|
|
@@ -228,7 +249,7 @@ export class DashboardPOM extends BasePOM {
|
|
|
228
249
|
*/
|
|
229
250
|
waitForDashboard() {
|
|
230
251
|
cy.url().should('include', '/dashboard')
|
|
231
|
-
cy.get(this.selectors.
|
|
252
|
+
cy.get(this.selectors.navContainer, { timeout: 15000 }).should('be.visible')
|
|
232
253
|
return this
|
|
233
254
|
}
|
|
234
255
|
|