@nextsparkjs/theme-default 0.1.0-beta.20 → 0.1.0-beta.21

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 (220) hide show
  1. package/package.json +1 -1
  2. package/tests/cypress/e2e/_devtools/access.bdd.md +262 -0
  3. package/tests/cypress/e2e/_devtools/access.cy.ts +171 -0
  4. package/tests/cypress/e2e/_devtools/navigation.bdd.md +261 -0
  5. package/tests/cypress/e2e/_devtools/navigation.cy.ts +157 -0
  6. package/tests/cypress/e2e/_devtools/pages.bdd.md +303 -0
  7. package/tests/cypress/e2e/_devtools/pages.cy.ts +184 -0
  8. package/tests/cypress/e2e/_docs/README.md +215 -0
  9. package/tests/cypress/e2e/_docs/tutorials/sector7-superadmin-teams.narration.json +155 -0
  10. package/tests/cypress/e2e/_docs/tutorials/sector7-superadmin.cy.ts +390 -0
  11. package/tests/cypress/e2e/_docs/tutorials/teams-system.doc.cy.ts +349 -0
  12. package/tests/cypress/e2e/_docs/tutorials/teams-system.narration.json +165 -0
  13. package/tests/cypress/e2e/_selectors/auth.cy.ts +306 -0
  14. package/tests/cypress/e2e/_selectors/billing.cy.ts +89 -0
  15. package/tests/cypress/e2e/_selectors/dashboard-mobile.cy.ts +113 -0
  16. package/tests/cypress/e2e/_selectors/dashboard-navigation.cy.ts +89 -0
  17. package/tests/cypress/e2e/_selectors/dashboard-sidebar.cy.ts +60 -0
  18. package/tests/cypress/e2e/_selectors/dashboard-topnav.cy.ts +146 -0
  19. package/tests/cypress/e2e/_selectors/devtools.cy.ts +210 -0
  20. package/tests/cypress/e2e/_selectors/global-search.cy.ts +88 -0
  21. package/tests/cypress/e2e/_selectors/pages-editor.cy.ts +179 -0
  22. package/tests/cypress/e2e/_selectors/posts-editor.cy.ts +282 -0
  23. package/tests/cypress/e2e/_selectors/public.cy.ts +112 -0
  24. package/tests/cypress/e2e/_selectors/settings-api-keys.cy.ts +228 -0
  25. package/tests/cypress/e2e/_selectors/settings-billing.cy.ts +105 -0
  26. package/tests/cypress/e2e/_selectors/settings-layout.cy.ts +119 -0
  27. package/tests/cypress/e2e/_selectors/settings-password.cy.ts +71 -0
  28. package/tests/cypress/e2e/_selectors/settings-profile.cy.ts +82 -0
  29. package/tests/cypress/e2e/_selectors/settings-teams.cy.ts +68 -0
  30. package/tests/cypress/e2e/_selectors/superadmin.cy.ts +185 -0
  31. package/tests/cypress/e2e/_selectors/tasks.cy.ts +242 -0
  32. package/tests/cypress/e2e/_selectors/taxonomies.cy.ts +126 -0
  33. package/tests/cypress/e2e/_selectors/teams.cy.ts +142 -0
  34. package/tests/cypress/e2e/_superadmin/all-teams.bdd.md +261 -0
  35. package/tests/cypress/e2e/_superadmin/all-teams.cy.ts +177 -0
  36. package/tests/cypress/e2e/_superadmin/all-users.bdd.md +406 -0
  37. package/tests/cypress/e2e/_superadmin/all-users.cy.ts +294 -0
  38. package/tests/cypress/e2e/_superadmin/dashboard.bdd.md +235 -0
  39. package/tests/cypress/e2e/_superadmin/dashboard.cy.ts +149 -0
  40. package/tests/cypress/e2e/_superadmin/subscriptions-overview.bdd.md +290 -0
  41. package/tests/cypress/e2e/_superadmin/subscriptions-overview.cy.ts +194 -0
  42. package/tests/cypress/e2e/ai/ai-usage.cy.ts +209 -0
  43. package/tests/cypress/e2e/ai/chat-api.cy.ts +107 -0
  44. package/tests/cypress/e2e/ai/guardrails.cy.ts +332 -0
  45. package/tests/cypress/e2e/api/billing/BillingAPIController.js +319 -0
  46. package/tests/cypress/e2e/api/billing/check-action.cy.ts +326 -0
  47. package/tests/cypress/e2e/api/billing/checkout.cy.ts +358 -0
  48. package/tests/cypress/e2e/api/billing/lifecycle.cy.ts +423 -0
  49. package/tests/cypress/e2e/api/billing/plans/README.md +345 -0
  50. package/tests/cypress/e2e/api/billing/plans/business.cy.ts +412 -0
  51. package/tests/cypress/e2e/api/billing/plans/downgrade.cy.ts +510 -0
  52. package/tests/cypress/e2e/api/billing/plans/fixtures/billing-plans.json +163 -0
  53. package/tests/cypress/e2e/api/billing/plans/free.cy.ts +500 -0
  54. package/tests/cypress/e2e/api/billing/plans/pro.cy.ts +497 -0
  55. package/tests/cypress/e2e/api/billing/plans/starter.cy.ts +342 -0
  56. package/tests/cypress/e2e/api/billing/portal.cy.ts +313 -0
  57. package/tests/cypress/e2e/api/devtools/registries.bdd.md +300 -0
  58. package/tests/cypress/e2e/api/devtools/registries.cy.ts +368 -0
  59. package/tests/cypress/e2e/api/entities/blocks-scope.cy.ts +396 -0
  60. package/tests/cypress/e2e/api/entities/customers-crud.cy.ts +648 -0
  61. package/tests/cypress/e2e/api/entities/customers-metas.cy.ts +839 -0
  62. package/tests/cypress/e2e/api/entities/pages-crud.cy.ts +425 -0
  63. package/tests/cypress/e2e/api/entities/pages-status.cy.ts +335 -0
  64. package/tests/cypress/e2e/api/entities/post-categories-crud.cy.ts +610 -0
  65. package/tests/cypress/e2e/api/entities/posts-crud.cy.ts +709 -0
  66. package/tests/cypress/e2e/api/entities/posts-status.cy.ts +396 -0
  67. package/tests/cypress/e2e/api/entities/tasks-crud.cy.ts +602 -0
  68. package/tests/cypress/e2e/api/entities/tasks-metas.cy.ts +878 -0
  69. package/tests/cypress/e2e/api/entities/users-crud.cy.ts +469 -0
  70. package/tests/cypress/e2e/api/entities/users-metas.cy.ts +913 -0
  71. package/tests/cypress/e2e/api/entities/users-security.cy.ts +375 -0
  72. package/tests/cypress/e2e/api/scheduled-actions/cron-endpoint.bdd.md +375 -0
  73. package/tests/cypress/e2e/api/scheduled-actions/cron-endpoint.cy.ts +346 -0
  74. package/tests/cypress/e2e/api/scheduled-actions/devtools-endpoint.bdd.md +451 -0
  75. package/tests/cypress/e2e/api/scheduled-actions/devtools-endpoint.cy.ts +447 -0
  76. package/tests/cypress/e2e/api/scheduled-actions/scheduling.bdd.md +649 -0
  77. package/tests/cypress/e2e/api/scheduled-actions/scheduling.cy.ts +333 -0
  78. package/tests/cypress/e2e/api/settings/api-keys.crud.cy.ts +923 -0
  79. package/tests/cypress/e2e/uat/auth/app-roles/developer-login.bdd.md +231 -0
  80. package/tests/cypress/e2e/uat/auth/app-roles/developer-login.cy.ts +144 -0
  81. package/tests/cypress/e2e/uat/auth/app-roles/superadmin-login.bdd.md +118 -0
  82. package/tests/cypress/e2e/uat/auth/app-roles/superadmin-login.cy.ts +84 -0
  83. package/tests/cypress/e2e/uat/auth/custom-roles/editor-login.bdd.md +288 -0
  84. package/tests/cypress/e2e/uat/auth/custom-roles/editor-login.cy.ts +188 -0
  85. package/tests/cypress/e2e/uat/auth/login-logout.bdd.md +160 -0
  86. package/tests/cypress/e2e/uat/auth/login-logout.cy.ts +116 -0
  87. package/tests/cypress/e2e/uat/auth/password-reset.bdd.md +289 -0
  88. package/tests/cypress/e2e/uat/auth/password-reset.cy.ts +200 -0
  89. package/tests/cypress/e2e/uat/auth/team-roles/admin-login.bdd.md +225 -0
  90. package/tests/cypress/e2e/uat/auth/team-roles/admin-login.cy.ts +148 -0
  91. package/tests/cypress/e2e/uat/auth/team-roles/member-login.bdd.md +251 -0
  92. package/tests/cypress/e2e/uat/auth/team-roles/member-login.cy.ts +163 -0
  93. package/tests/cypress/e2e/uat/auth/team-roles/owner-login.bdd.md +231 -0
  94. package/tests/cypress/e2e/uat/auth/team-roles/owner-login.cy.ts +141 -0
  95. package/tests/cypress/e2e/uat/billing/extended.bdd.md +273 -0
  96. package/tests/cypress/e2e/uat/billing/extended.cy.ts +209 -0
  97. package/tests/cypress/e2e/uat/billing/feature-gates.bdd.md +407 -0
  98. package/tests/cypress/e2e/uat/billing/feature-gates.cy.ts +307 -0
  99. package/tests/cypress/e2e/uat/billing/page.bdd.md +329 -0
  100. package/tests/cypress/e2e/uat/billing/page.cy.ts +250 -0
  101. package/tests/cypress/e2e/uat/billing/status.bdd.md +190 -0
  102. package/tests/cypress/e2e/uat/billing/status.cy.ts +145 -0
  103. package/tests/cypress/e2e/uat/billing/team-switch.bdd.md +156 -0
  104. package/tests/cypress/e2e/uat/billing/team-switch.cy.ts +122 -0
  105. package/tests/cypress/e2e/uat/billing/usage.bdd.md +218 -0
  106. package/tests/cypress/e2e/uat/billing/usage.cy.ts +176 -0
  107. package/tests/cypress/e2e/uat/blocks/hero.bdd.md +124 -0
  108. package/tests/cypress/e2e/uat/blocks/hero.cy.ts +56 -0
  109. package/tests/cypress/e2e/uat/devtools/api-tester.cy.ts +390 -0
  110. package/tests/cypress/e2e/uat/entities/customers/member.bdd.md +275 -0
  111. package/tests/cypress/e2e/uat/entities/customers/member.cy.ts +122 -0
  112. package/tests/cypress/e2e/uat/entities/customers/owner.bdd.md +243 -0
  113. package/tests/cypress/e2e/uat/entities/customers/owner.cy.ts +165 -0
  114. package/tests/cypress/e2e/uat/entities/pages/block-crud.bdd.md +476 -0
  115. package/tests/cypress/e2e/uat/entities/pages/block-crud.cy.ts +486 -0
  116. package/tests/cypress/e2e/uat/entities/pages/block-editor.bdd.md +460 -0
  117. package/tests/cypress/e2e/uat/entities/pages/block-editor.cy.ts +301 -0
  118. package/tests/cypress/e2e/uat/entities/pages/list.bdd.md +432 -0
  119. package/tests/cypress/e2e/uat/entities/pages/list.cy.ts +273 -0
  120. package/tests/cypress/e2e/uat/entities/pages/public-rendering.bdd.md +696 -0
  121. package/tests/cypress/e2e/uat/entities/pages/public-rendering.cy.ts +340 -0
  122. package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.bdd.md +161 -0
  123. package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.cy.ts +104 -0
  124. package/tests/cypress/e2e/uat/entities/posts/categories.bdd.md +375 -0
  125. package/tests/cypress/e2e/uat/entities/posts/categories.cy.ts +241 -0
  126. package/tests/cypress/e2e/uat/entities/posts/editor.bdd.md +429 -0
  127. package/tests/cypress/e2e/uat/entities/posts/editor.cy.ts +257 -0
  128. package/tests/cypress/e2e/uat/entities/posts/list.bdd.md +340 -0
  129. package/tests/cypress/e2e/uat/entities/posts/list.cy.ts +177 -0
  130. package/tests/cypress/e2e/uat/entities/posts/public.bdd.md +614 -0
  131. package/tests/cypress/e2e/uat/entities/posts/public.cy.ts +249 -0
  132. package/tests/cypress/e2e/uat/entities/tasks/member.bdd.md +222 -0
  133. package/tests/cypress/e2e/uat/entities/tasks/member.cy.ts +165 -0
  134. package/tests/cypress/e2e/uat/entities/tasks/owner.bdd.md +419 -0
  135. package/tests/cypress/e2e/uat/entities/tasks/owner.cy.ts +191 -0
  136. package/tests/cypress/e2e/uat/roles/editor-role.bdd.md +552 -0
  137. package/tests/cypress/e2e/uat/roles/editor-role.cy.ts +210 -0
  138. package/tests/cypress/e2e/uat/roles/member-restrictions.bdd.md +450 -0
  139. package/tests/cypress/e2e/uat/roles/member-restrictions.cy.ts +189 -0
  140. package/tests/cypress/e2e/uat/roles/owner-full-crud.bdd.md +530 -0
  141. package/tests/cypress/e2e/uat/roles/owner-full-crud.cy.ts +247 -0
  142. package/tests/cypress/e2e/uat/scheduled-actions/devtools-ui.bdd.md +736 -0
  143. package/tests/cypress/e2e/uat/scheduled-actions/devtools-ui.cy.ts +740 -0
  144. package/tests/cypress/e2e/uat/teams/roles-matrix.bdd.md +553 -0
  145. package/tests/cypress/e2e/uat/teams/roles-matrix.cy.ts +185 -0
  146. package/tests/cypress/e2e/uat/teams/switcher.bdd.md +1151 -0
  147. package/tests/cypress/e2e/uat/teams/switcher.cy.ts +497 -0
  148. package/tests/cypress/e2e/uat/teams/team-switcher.md +198 -0
  149. package/tests/cypress/fixtures/blocks.json +218 -0
  150. package/tests/cypress/fixtures/entities.json +78 -0
  151. package/tests/cypress/fixtures/page-builder.json +21 -0
  152. package/tests/cypress/src/components/CategoriesPOM.ts +382 -0
  153. package/tests/cypress/src/components/CustomersPOM.ts +439 -0
  154. package/tests/cypress/src/components/DevKeyringPOM.ts +160 -0
  155. package/tests/cypress/src/components/EntityForm.ts +375 -0
  156. package/tests/cypress/src/components/EntityList.ts +389 -0
  157. package/tests/cypress/src/components/PageBuilderPOM.ts +710 -0
  158. package/tests/cypress/src/components/PostEditorPOM.ts +370 -0
  159. package/tests/cypress/src/components/PostsListPOM.ts +223 -0
  160. package/tests/cypress/src/components/PublicPagePOM.ts +447 -0
  161. package/tests/cypress/src/components/PublicPostPOM.ts +146 -0
  162. package/tests/cypress/src/components/TasksPOM.ts +272 -0
  163. package/tests/cypress/src/components/TeamSwitcherPOM.ts +450 -0
  164. package/tests/cypress/src/components/index.ts +21 -0
  165. package/tests/cypress/src/controllers/ApiKeysAPIController.js +178 -0
  166. package/tests/cypress/src/controllers/BaseAPIController.js +317 -0
  167. package/tests/cypress/src/controllers/CustomerAPIController.js +251 -0
  168. package/tests/cypress/src/controllers/PagesAPIController.js +226 -0
  169. package/tests/cypress/src/controllers/PostsAPIController.js +250 -0
  170. package/tests/cypress/src/controllers/TaskAPIController.js +240 -0
  171. package/tests/cypress/src/controllers/UsersAPIController.js +242 -0
  172. package/tests/cypress/src/controllers/index.js +25 -0
  173. package/tests/cypress/src/core/AuthPOM.ts +450 -0
  174. package/tests/cypress/src/core/BasePOM.ts +86 -0
  175. package/tests/cypress/src/core/BlockEditorBasePOM.ts +576 -0
  176. package/tests/cypress/src/core/DashboardEntityPOM.ts +692 -0
  177. package/tests/cypress/src/core/index.ts +14 -0
  178. package/tests/cypress/src/entities/CustomersPOM.ts +172 -0
  179. package/tests/cypress/src/entities/PagesPOM.ts +137 -0
  180. package/tests/cypress/src/entities/PostsPOM.ts +137 -0
  181. package/tests/cypress/src/entities/TasksPOM.ts +176 -0
  182. package/tests/cypress/src/entities/index.ts +14 -0
  183. package/tests/cypress/src/features/BillingPOM.ts +385 -0
  184. package/tests/cypress/src/features/DashboardPOM.ts +245 -0
  185. package/tests/cypress/src/features/DevtoolsPOM.ts +739 -0
  186. package/tests/cypress/src/features/PageBuilderPOM.ts +263 -0
  187. package/tests/cypress/src/features/PostEditorPOM.ts +313 -0
  188. package/tests/cypress/src/features/ScheduledActionsPOM.ts +463 -0
  189. package/tests/cypress/src/features/SettingsPOM.ts +362 -0
  190. package/tests/cypress/src/features/SuperadminPOM.ts +331 -0
  191. package/tests/cypress/src/features/SuperadminTeamRolesPOM.ts +285 -0
  192. package/tests/cypress/src/features/index.ts +28 -0
  193. package/tests/cypress/src/helpers/ApiInterceptor.ts +177 -0
  194. package/tests/cypress/src/index.ts +101 -0
  195. package/tests/cypress/src/pages/dashboard/Dashboard.js +677 -0
  196. package/tests/cypress/src/pages/dashboard/DashboardPage.js +43 -0
  197. package/tests/cypress/src/pages/dashboard/DashboardStats.js +546 -0
  198. package/tests/cypress/src/pages/dashboard/index.js +6 -0
  199. package/tests/cypress/src/pages/index.js +5 -0
  200. package/tests/cypress/src/pages/public/FeaturesPage.js +28 -0
  201. package/tests/cypress/src/pages/public/LandingPage.js +69 -0
  202. package/tests/cypress/src/pages/public/PricingPage.js +33 -0
  203. package/tests/cypress/src/pages/public/index.js +6 -0
  204. package/tests/cypress/src/selectors.ts +46 -0
  205. package/tests/cypress/src/session-helpers.ts +500 -0
  206. package/tests/cypress/support/doc-commands.ts +260 -0
  207. package/tests/cypress.config.ts +150 -0
  208. package/tests/jest/components/post-header.test.tsx +377 -0
  209. package/tests/jest/config/role-config.test.ts +529 -0
  210. package/tests/jest/jest.config.ts +81 -0
  211. package/tests/jest/langchain/COVERAGE.md +372 -0
  212. package/tests/jest/langchain/guardrails.test.ts +465 -0
  213. package/tests/jest/langchain/streaming.test.ts +367 -0
  214. package/tests/jest/langchain/token-tracker.test.ts +455 -0
  215. package/tests/jest/langchain/tracer-callbacks.test.ts +881 -0
  216. package/tests/jest/langchain/tracer.test.ts +823 -0
  217. package/tests/jest/user-roles/role-helpers.test.ts +432 -0
  218. package/tests/jest/validation/categories.test.ts +429 -0
  219. package/tests/jest/validation/posts.test.ts +546 -0
  220. package/tests/tsconfig.json +15 -0
@@ -0,0 +1,146 @@
1
+ /**
2
+ * UI Selectors Validation: Dashboard Topnav
3
+ *
4
+ * This test validates that dashboard topnav selectors exist in the DOM.
5
+ * This is a lightweight test that ONLY checks selector presence, not functionality.
6
+ *
7
+ * Purpose:
8
+ * - Validate DashboardPOM topnav selectors work correctly
9
+ * - Ensure all dashboard.topnav.* selectors are implemented
10
+ * - Run as Phase 12 sub-gate before functional tests
11
+ *
12
+ * Scope:
13
+ * - Navigate to dashboard (requires login)
14
+ * - Assert elements exist in DOM (no form submissions)
15
+ * - Fast execution (< 30 seconds per describe block)
16
+ *
17
+ * NOTE: Some selectors require specific states (user menu open, specific roles).
18
+ * signin/signup selectors only visible when NOT logged in.
19
+ */
20
+
21
+ import { DashboardPOM } from '../../src/features/DashboardPOM'
22
+ import { loginAsDefaultOwner } from '../../src/session-helpers'
23
+
24
+ describe('Dashboard Topnav Selectors Validation', { tags: ['@ui-selectors'] }, () => {
25
+ const dashboard = DashboardPOM.create()
26
+
27
+ beforeEach(() => {
28
+ loginAsDefaultOwner()
29
+ cy.visit('/dashboard', { timeout: 60000, failOnStatusCode: false })
30
+ cy.url().should('include', '/dashboard')
31
+ })
32
+
33
+ // ============================================
34
+ // TOPNAV STRUCTURE (4 selectors)
35
+ // ============================================
36
+ describe('Topnav Structure', () => {
37
+ it('should find topnav header', () => {
38
+ cy.get(dashboard.selectors.topnavHeader).should('exist')
39
+ })
40
+
41
+ // NOTE: Logo only visible when NOT logged in
42
+ it.skip('should find topnav logo (only visible when not logged in)', () => {
43
+ cy.get(dashboard.selectors.topnavLogo).should('exist')
44
+ })
45
+
46
+ it('should find topnav actions container', () => {
47
+ cy.get(dashboard.selectors.topnavActions).should('exist')
48
+ })
49
+
50
+ it('should find topnav search section', () => {
51
+ cy.get(dashboard.selectors.topnavSearchSection).should('exist')
52
+ })
53
+ })
54
+
55
+ // ============================================
56
+ // TOPNAV ACTIONS (4 selectors)
57
+ // ============================================
58
+ describe('Topnav Actions', () => {
59
+ it('should find sidebar toggle button', () => {
60
+ cy.get(dashboard.selectors.topnavSidebarToggle).should('exist')
61
+ })
62
+
63
+ it('should find notifications button', () => {
64
+ cy.get(dashboard.selectors.topnavNotifications).should('exist')
65
+ })
66
+
67
+ it('should find help button', () => {
68
+ cy.get(dashboard.selectors.topnavHelp).should('exist')
69
+ })
70
+
71
+ it('should find theme toggle button', () => {
72
+ cy.get(dashboard.selectors.topnavThemeToggle).should('exist')
73
+ })
74
+ })
75
+
76
+ // ============================================
77
+ // TOPNAV ADMIN LINKS (2 selectors)
78
+ // NOTE: Requires superadmin (sector7) or developer role (devzone)
79
+ // Default owner does NOT have these roles
80
+ // ============================================
81
+ describe('Topnav Admin Links', () => {
82
+ it.skip('should find sector7 link (requires superadmin or developer with sector7 enabled)', () => {
83
+ // Requires: sector7Config?.enabled && (isSuperAdmin || (isDeveloper && sector7Config?.showToDevelopers))
84
+ cy.get(dashboard.selectors.topnavSuperadmin).should('exist')
85
+ })
86
+
87
+ it.skip('should find devzone link (requires developer role)', () => {
88
+ // Requires: devZoneConfig?.enabled && isDeveloper
89
+ cy.get(dashboard.selectors.topnavDevzone).should('exist')
90
+ })
91
+ })
92
+
93
+ // ============================================
94
+ // USER MENU (4+ selectors)
95
+ // ============================================
96
+ describe('User Menu', () => {
97
+ it('should find user menu trigger', () => {
98
+ cy.get(dashboard.selectors.topnavUserMenuTrigger).should('exist')
99
+ })
100
+
101
+ it('should find user menu when opened', () => {
102
+ cy.get(dashboard.selectors.topnavUserMenuTrigger).click()
103
+ cy.get(dashboard.selectors.topnavUserMenu).should('be.visible')
104
+ })
105
+
106
+ it('should find profile menu item when opened', () => {
107
+ cy.get(dashboard.selectors.topnavUserMenuTrigger).click()
108
+ cy.get(dashboard.selectors.topnavMenuItem('user')).should('exist')
109
+ })
110
+
111
+ it('should find settings menu item when opened', () => {
112
+ cy.get(dashboard.selectors.topnavUserMenuTrigger).click()
113
+ cy.get(dashboard.selectors.topnavMenuItem('settings')).should('exist')
114
+ })
115
+
116
+ it('should find signOut action when opened', () => {
117
+ cy.get(dashboard.selectors.topnavUserMenuTrigger).click()
118
+ // Action is 'signOut' per dashboard.config.ts
119
+ cy.get(dashboard.selectors.topnavMenuAction('signOut')).should('exist')
120
+ })
121
+ })
122
+
123
+ // ============================================
124
+ // PUBLIC NAVBAR SELECTORS (2 selectors)
125
+ // NOTE: Only visible when NOT logged in - skip for logged-in tests
126
+ // ============================================
127
+ describe('Public Navbar Selectors', () => {
128
+ it.skip('should find signin button (only visible when not logged in)', () => {
129
+ cy.get(dashboard.selectors.topnavSignin).should('exist')
130
+ })
131
+
132
+ it.skip('should find signup button (only visible when not logged in)', () => {
133
+ cy.get(dashboard.selectors.topnavSignup).should('exist')
134
+ })
135
+ })
136
+
137
+ // ============================================
138
+ // LOADING STATE SELECTOR (1 selector)
139
+ // NOTE: Only visible during auth loading
140
+ // ============================================
141
+ describe('Loading State Selectors', () => {
142
+ it.skip('should find user loading state (only visible during auth loading)', () => {
143
+ cy.get(dashboard.selectors.topnavUserLoading).should('exist')
144
+ })
145
+ })
146
+ })
@@ -0,0 +1,210 @@
1
+ /**
2
+ * UI Selectors Validation: DevTools (DevTools)
3
+ *
4
+ * This test validates that devtools selectors exist in the DOM.
5
+ * This is a lightweight test that ONLY checks selector presence, not functionality.
6
+ *
7
+ * Purpose:
8
+ * - Validate DevtoolsPOM selectors work correctly
9
+ * - Ensure all dev.* selectors are implemented
10
+ * - Run as Phase 12 sub-gate before functional tests
11
+ *
12
+ * Scope:
13
+ * - Navigate to /devtools pages (requires developer role)
14
+ * - Assert elements exist in DOM (no form submissions)
15
+ * - Fast execution (< 30 seconds per describe block)
16
+ *
17
+ * IMPORTANT: DevTools is only accessible to users with 'developer' app role.
18
+ */
19
+
20
+ import { DevtoolsPOM } from '../../src/features/DevtoolsPOM'
21
+ import { loginAsDefaultDeveloper } from '../../src/session-helpers'
22
+
23
+ describe('DevTools Selectors Validation', { tags: ['@ui-selectors'] }, () => {
24
+ const dev = DevtoolsPOM.create()
25
+
26
+ beforeEach(() => {
27
+ loginAsDefaultDeveloper()
28
+ })
29
+
30
+ // ============================================
31
+ // NAVIGATION STRUCTURE (8 selectors)
32
+ // ============================================
33
+ describe('Navigation Structure', () => {
34
+ beforeEach(() => {
35
+ cy.visit('/devtools', { timeout: 60000, failOnStatusCode: false })
36
+ cy.url().should('include', '/devtools')
37
+ })
38
+
39
+ it('should find sidebar container', () => {
40
+ cy.get(dev.selectors.sidebar).should('exist')
41
+ })
42
+
43
+ it('should find sidebar collapse toggle', () => {
44
+ cy.get(dev.selectors.sidebarCollapseToggle).should('exist')
45
+ })
46
+
47
+ it('should find nav home item', () => {
48
+ cy.get(dev.selectors.navHome).should('exist')
49
+ })
50
+
51
+ it('should find nav style gallery item', () => {
52
+ cy.get(dev.selectors.navStyleGallery).should('exist')
53
+ })
54
+
55
+ it('should find nav test cases item', () => {
56
+ cy.get(dev.selectors.navTestCases).should('exist')
57
+ })
58
+
59
+ it('should find nav config item', () => {
60
+ cy.get(dev.selectors.navConfig).should('exist')
61
+ })
62
+
63
+ it('should find exit to dashboard link', () => {
64
+ cy.get(dev.selectors.exitToDashboard).should('exist')
65
+ })
66
+
67
+ it('should find go to admin link', () => {
68
+ cy.get(dev.selectors.goToAdmin).should('exist')
69
+ })
70
+ })
71
+
72
+ // ============================================
73
+ // HOME PAGE (4 selectors)
74
+ // ============================================
75
+ describe('Home Page', () => {
76
+ beforeEach(() => {
77
+ cy.visit('/devtools', { timeout: 60000, failOnStatusCode: false })
78
+ cy.url().should('include', '/devtools')
79
+ })
80
+
81
+ it('should find home page container', () => {
82
+ cy.get(dev.selectors.homePage).should('exist')
83
+ })
84
+
85
+ it('should find style gallery quick link', () => {
86
+ cy.get(dev.selectors.homeStyleLink).should('exist')
87
+ })
88
+
89
+ it('should find tests quick link', () => {
90
+ cy.get(dev.selectors.homeTestsLink).should('exist')
91
+ })
92
+
93
+ it('should find config quick link', () => {
94
+ cy.get(dev.selectors.homeConfigLink).should('exist')
95
+ })
96
+ })
97
+
98
+ // ============================================
99
+ // STYLE GALLERY PAGE (8 selectors)
100
+ // ============================================
101
+ describe('Style Gallery Page', () => {
102
+ beforeEach(() => {
103
+ cy.visit('/devtools/style', { timeout: 60000, failOnStatusCode: false })
104
+ cy.url().should('include', '/devtools/style')
105
+ })
106
+
107
+ it('should find style page container', () => {
108
+ cy.get(dev.selectors.stylePage).should('exist')
109
+ })
110
+
111
+ it('should find components tab', () => {
112
+ cy.get(dev.selectors.styleTabComponents).should('exist')
113
+ })
114
+
115
+ it('should find field types tab', () => {
116
+ cy.get(dev.selectors.styleTabFieldTypes).should('exist')
117
+ })
118
+
119
+ it('should find theme tab', () => {
120
+ cy.get(dev.selectors.styleTabTheme).should('exist')
121
+ })
122
+
123
+ it('should find guidelines tab', () => {
124
+ cy.get(dev.selectors.styleTabGuidelines).should('exist')
125
+ })
126
+
127
+ it('should find component gallery (default tab content)', () => {
128
+ cy.get(dev.selectors.styleComponentGallery).should('exist')
129
+ })
130
+
131
+ it('should find field types content when tab clicked', () => {
132
+ cy.get(dev.selectors.styleTabFieldTypes).click()
133
+ cy.get(dev.selectors.styleFieldTypes).should('exist')
134
+ })
135
+
136
+ it('should find theme preview when tab clicked', () => {
137
+ cy.get(dev.selectors.styleTabTheme).click()
138
+ cy.get(dev.selectors.styleThemePreview).should('exist')
139
+ })
140
+ })
141
+
142
+ // ============================================
143
+ // CONFIG VIEWER PAGE (8 selectors)
144
+ // ============================================
145
+ describe('Config Viewer Page', () => {
146
+ beforeEach(() => {
147
+ cy.visit('/devtools/config', { timeout: 60000, failOnStatusCode: false })
148
+ cy.url().should('include', '/devtools/config')
149
+ })
150
+
151
+ it('should find config page container', () => {
152
+ cy.get(dev.selectors.configPage).should('exist')
153
+ })
154
+
155
+ it('should find config viewer container', () => {
156
+ cy.get(dev.selectors.configViewer).should('exist')
157
+ })
158
+
159
+ it('should find theme tab', () => {
160
+ cy.get(dev.selectors.configTabTheme).should('exist')
161
+ })
162
+
163
+ it('should find entities tab', () => {
164
+ cy.get(dev.selectors.configTabEntities).should('exist')
165
+ })
166
+
167
+ it('should find theme content (default tab)', () => {
168
+ cy.get(dev.selectors.configThemeContent).should('exist')
169
+ })
170
+
171
+ it('should find entities content when tab clicked', () => {
172
+ cy.get(dev.selectors.configTabEntities).click()
173
+ cy.get(dev.selectors.configEntitiesContent).should('exist')
174
+ })
175
+
176
+ it('should find copy theme button', () => {
177
+ cy.get(dev.selectors.configCopyTheme).should('exist')
178
+ })
179
+
180
+ it('should find copy entities button when on entities tab', () => {
181
+ cy.get(dev.selectors.configTabEntities).click()
182
+ // Wait for entities to load before checking button
183
+ cy.get(dev.selectors.configEntitiesContent, { timeout: 10000 }).should('exist')
184
+ cy.get(dev.selectors.configCopyEntities).should('exist')
185
+ })
186
+ })
187
+
188
+ // ============================================
189
+ // TEST CASES PAGE (3 selectors)
190
+ // NOTE: Conditional states (loading, empty, error) removed - not testable in selector validation
191
+ // ============================================
192
+ describe('Test Cases Page', () => {
193
+ beforeEach(() => {
194
+ cy.visit('/devtools/tests', { timeout: 60000, failOnStatusCode: false })
195
+ cy.url().should('include', '/devtools/tests')
196
+ })
197
+
198
+ it('should find tests page container', () => {
199
+ cy.get(dev.selectors.testsPage).should('exist')
200
+ })
201
+
202
+ it('should find tests viewer container', () => {
203
+ cy.get(dev.selectors.testsViewer).should('exist')
204
+ })
205
+
206
+ it('should find tests tree', () => {
207
+ cy.get(dev.selectors.testsTree).should('exist')
208
+ })
209
+ })
210
+ })
@@ -0,0 +1,88 @@
1
+ /**
2
+ * UI Selectors Validation: Global Search
3
+ *
4
+ * This test validates that global search selectors exist in the DOM.
5
+ * This is a lightweight test that ONLY checks selector presence, not functionality.
6
+ *
7
+ * Purpose:
8
+ * - Validate globalSearch.* selectors work correctly
9
+ * - Ensure search modal and components are implemented
10
+ * - Run as Phase 12 sub-gate before functional tests
11
+ *
12
+ * Scope:
13
+ * - Navigate to dashboard (requires login)
14
+ * - Open search modal
15
+ * - Assert elements exist in DOM (no actual search)
16
+ *
17
+ * NOTE: Search modal must be opened via keyboard shortcut or trigger button.
18
+ */
19
+
20
+ import { cySelector } from '../../src/selectors'
21
+ import { loginAsDefaultOwner } from '../../src/session-helpers'
22
+
23
+ describe('Global Search Selectors Validation', { tags: ['@ui-selectors'] }, () => {
24
+ // Define selectors locally since globalSearch might not be in selectors.ts
25
+ const selectors = {
26
+ modal: cySelector('globalSearch.modal'),
27
+ trigger: cySelector('globalSearch.trigger'),
28
+ input: cySelector('globalSearch.input'),
29
+ results: cySelector('globalSearch.results'),
30
+ result: cySelector('globalSearch.result'),
31
+ }
32
+
33
+ beforeEach(() => {
34
+ loginAsDefaultOwner()
35
+ cy.visit('/dashboard', { timeout: 60000, failOnStatusCode: false })
36
+ cy.url().should('include', '/dashboard')
37
+ })
38
+
39
+ // ============================================
40
+ // SEARCH TRIGGER (1 selector)
41
+ // ============================================
42
+ describe('Search Trigger', () => {
43
+ it.skip('should find search trigger button (selector not implemented)', () => {
44
+ cy.get(selectors.trigger).should('exist')
45
+ })
46
+ })
47
+
48
+ // ============================================
49
+ // SEARCH MODAL (4 selectors)
50
+ // These require the modal to be open
51
+ // ============================================
52
+ describe('Search Modal (when open)', () => {
53
+ beforeEach(() => {
54
+ // Try to open search modal via keyboard shortcut (Cmd+K or Ctrl+K)
55
+ cy.get('body').type('{meta}k')
56
+ // Wait a bit for modal to open
57
+ cy.wait(500)
58
+ })
59
+
60
+ it.skip('should find search modal container (selector not implemented)', () => {
61
+ cy.get(selectors.modal).should('exist')
62
+ })
63
+
64
+ it('should find search input', () => {
65
+ cy.get(selectors.input).should('exist')
66
+ })
67
+
68
+ it.skip('should find search results container (requires search query)', () => {
69
+ cy.get(selectors.results).should('exist')
70
+ })
71
+
72
+ it.skip('should find search result item (requires search query with results)', () => {
73
+ cy.get(selectors.result).should('exist')
74
+ })
75
+ })
76
+
77
+ // ============================================
78
+ // ALTERNATIVE: Open via click
79
+ // ============================================
80
+ describe('Search Modal (opened via click)', () => {
81
+ it.skip('should open search modal when clicking trigger (trigger selector not implemented)', () => {
82
+ cy.get(selectors.trigger).click()
83
+ cy.wait(500)
84
+ cy.get(selectors.modal).should('exist')
85
+ cy.get(selectors.input).should('exist')
86
+ })
87
+ })
88
+ })
@@ -0,0 +1,179 @@
1
+ /**
2
+ * POC Test: Pages Block Editor Selectors Validation
3
+ *
4
+ * This test validates selectors specific to the Page Builder that are NOT
5
+ * available in the Posts editor:
6
+ * - Page Settings panel
7
+ * - SEO settings (meta title, description, keywords)
8
+ * - Locale selector
9
+ *
10
+ * Purpose:
11
+ * - Validate selectors from BlockEditorBasePOM work correctly for pages
12
+ * - Test page-specific features (SEO, locale)
13
+ *
14
+ * Scope:
15
+ * - Only login and navigate
16
+ * - Assert elements exist in DOM (no full CRUD operations)
17
+ */
18
+
19
+ import { PageBuilderPOM } from '../../src/features/PageBuilderPOM'
20
+ import { PagesPOM } from '../../src/entities/PagesPOM'
21
+ import { loginAsDefaultOwner } from '../../src/session-helpers'
22
+
23
+ describe('Pages Block Editor Selectors Validation', { tags: ['@ui-selectors'] }, ()
24
+ => {
25
+ const pageBuilder = PageBuilderPOM.create()
26
+ const pages = PagesPOM.create()
27
+
28
+ beforeEach(() => {
29
+ loginAsDefaultOwner()
30
+ })
31
+
32
+ describe('Pages List Page Selectors (Entity POM)', () => {
33
+ beforeEach(() => {
34
+ pages.visitList()
35
+ pages.waitForList()
36
+ })
37
+
38
+ it('should find pages table container', () => {
39
+ cy.get(pages.selectors.tableContainer).should('exist')
40
+ })
41
+
42
+ it('should find pages add button', () => {
43
+ cy.get(pages.selectors.addButton).should('exist')
44
+ })
45
+
46
+ it('should find at least one page row', () => {
47
+ cy.get(pages.selectors.rowGeneric).should('have.length.at.least', 1)
48
+ })
49
+ })
50
+
51
+ describe('Block Editor Core Selectors (Pages)', () => {
52
+ beforeEach(() => {
53
+ pageBuilder.visitCreate()
54
+ pageBuilder.waitForEditor()
55
+ })
56
+
57
+ it('should find editor container', () => {
58
+ cy.get(pageBuilder.editorSelectors.container).should('exist')
59
+ })
60
+
61
+ it('should find title input', () => {
62
+ cy.get(pageBuilder.editorSelectors.titleInput).should('exist')
63
+ })
64
+
65
+ it('should find slug input', () => {
66
+ cy.get(pageBuilder.editorSelectors.slugInput).should('exist')
67
+ })
68
+
69
+ it('should find save button', () => {
70
+ cy.get(pageBuilder.editorSelectors.saveButton).should('exist')
71
+ })
72
+ })
73
+
74
+ describe('Page Settings Selectors (Pages-specific)', () => {
75
+ beforeEach(() => {
76
+ // Navigate to edit an existing page to see page settings and SEO
77
+ pages.visitList()
78
+ pages.waitForList()
79
+
80
+ cy.get(pages.selectors.rowGeneric)
81
+ .first()
82
+ .invoke('attr', 'data-cy')
83
+ .then((dataCy) => {
84
+ const id = dataCy?.replace('pages-row-', '') || ''
85
+ pageBuilder.visitEdit(id)
86
+ pageBuilder.waitForEditor()
87
+ })
88
+ })
89
+
90
+ it('should find entity fields sidebar in edit mode', () => {
91
+ // Switch to "Campos" tab to see entity fields
92
+ cy.get('[data-cy="sidebar-fields"]').click()
93
+ // Uses entity-fields-sidebar instead of page-settings-panel
94
+ cy.get(pageBuilder.editorSelectors.entityFieldsSidebar).should('exist')
95
+ })
96
+
97
+ // NOTE: SEO settings are not yet implemented in the page editor
98
+ // These tests are skipped until the SEO section is added
99
+ it.skip('should find SEO trigger in edit mode (SEO not implemented)', () => {
100
+ cy.get('[data-cy="sidebar-fields"]').click()
101
+ cy.get(pageBuilder.editorSelectors.seoTrigger).should('exist')
102
+ })
103
+
104
+ it.skip('should find SEO fields when expanded (SEO not implemented)', () => {
105
+ cy.get('[data-cy="sidebar-fields"]').click()
106
+ pageBuilder.openSeoSettings()
107
+ cy.get(pageBuilder.editorSelectors.metaTitle).should('exist')
108
+ cy.get(pageBuilder.editorSelectors.metaDescription).should('exist')
109
+ })
110
+
111
+ it('should find locale selector', () => {
112
+ cy.get('[data-cy="sidebar-fields"]').click()
113
+ // Uses field-locale pattern from entity fields
114
+ cy.get(pageBuilder.pageSelectors.localeSelect).should('exist')
115
+ })
116
+ })
117
+
118
+ describe('Block Picker Selectors (Pages)', () => {
119
+ beforeEach(() => {
120
+ pageBuilder.visitCreate()
121
+ pageBuilder.waitForEditor()
122
+ })
123
+
124
+ it('should find block picker container', () => {
125
+ cy.get(pageBuilder.editorSelectors.blockPicker).should('exist')
126
+ })
127
+
128
+ it('should find hero block (common in pages)', () => {
129
+ cy.get(pageBuilder.editorSelectors.blockItem('hero')).should('exist')
130
+ cy.get(pageBuilder.editorSelectors.addBlock('hero')).should('exist')
131
+ })
132
+ })
133
+
134
+ describe('Block Canvas and Settings (Pages)', () => {
135
+ beforeEach(() => {
136
+ pageBuilder.visitCreate()
137
+ pageBuilder.waitForEditor()
138
+ })
139
+
140
+ it('should find empty state when no blocks added', () => {
141
+ cy.get(pageBuilder.editorSelectors.blockCanvasEmpty).should('exist')
142
+ })
143
+
144
+ it('should find block canvas and settings when block is added', () => {
145
+ // Add a hero block
146
+ pageBuilder.addBlock('hero')
147
+
148
+ // Canvas and settings should appear
149
+ cy.get(pageBuilder.editorSelectors.blockCanvas).should('exist')
150
+ cy.get(pageBuilder.editorSelectors.settingsPanel).should('exist')
151
+ cy.get(pageBuilder.editorSelectors.tabContent).should('exist')
152
+ cy.get(pageBuilder.editorSelectors.tabDesign).should('exist')
153
+ })
154
+ })
155
+
156
+ describe('Edit Existing Page Selectors', () => {
157
+ it('should find editor elements when editing an existing page', () => {
158
+ // Get a page ID from the list
159
+ pages.visitList()
160
+ pages.waitForList()
161
+
162
+ cy.get(pages.selectors.rowGeneric)
163
+ .first()
164
+ .invoke('attr', 'data-cy')
165
+ .then((dataCy) => {
166
+ const id = dataCy?.replace('pages-row-', '') || ''
167
+
168
+ // Navigate to edit
169
+ pageBuilder.visitEdit(id)
170
+ pageBuilder.waitForEditor()
171
+
172
+ // Validate editor is loaded with existing content
173
+ cy.get(pageBuilder.editorSelectors.container).should('exist')
174
+ cy.get(pageBuilder.editorSelectors.titleInput).should('exist')
175
+ cy.get(pageBuilder.editorSelectors.saveButton).should('exist')
176
+ })
177
+ })
178
+ })
179
+ })