@nextsparkjs/theme-default 0.1.0-beta.17 → 0.1.0-beta.170

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 (332) hide show
  1. package/api/ai/chat/stream/route.ts +4 -1
  2. package/api/ai/orchestrator/route.ts +10 -3
  3. package/api/ai/single-agent/route.ts +10 -3
  4. package/api/ai/usage/route.ts +4 -1
  5. package/blocks/benefits/component.tsx +4 -4
  6. package/blocks/cta-section/component.tsx +4 -4
  7. package/blocks/faq-accordion/component.tsx +2 -2
  8. package/blocks/features-grid/component.tsx +5 -5
  9. package/blocks/hero/component.tsx +2 -2
  10. package/blocks/hero/fields.ts +1 -1
  11. package/blocks/hero-with-form/component.tsx +7 -7
  12. package/blocks/hero-with-form/fields.ts +1 -1
  13. package/blocks/jumbotron/component.tsx +7 -7
  14. package/blocks/jumbotron/fields.ts +1 -1
  15. package/blocks/logo-cloud/component.tsx +6 -6
  16. package/blocks/logo-cloud/fields.ts +1 -1
  17. package/blocks/post-content/component.tsx +2 -2
  18. package/blocks/pricing-table/component.tsx +5 -5
  19. package/blocks/split-content/component.tsx +5 -5
  20. package/blocks/split-content/fields.ts +1 -1
  21. package/blocks/stats-counter/component.tsx +9 -9
  22. package/blocks/testimonials/component.tsx +4 -4
  23. package/blocks/testimonials/fields.ts +1 -1
  24. package/blocks/text-content/component.tsx +12 -10
  25. package/blocks/timeline/component.tsx +12 -12
  26. package/blocks/video-hero/component.tsx +7 -7
  27. package/blocks/video-hero/fields.ts +1 -1
  28. package/components/ai-chat/ChatPanel.tsx +7 -7
  29. package/components/ai-chat/Message.tsx +2 -2
  30. package/components/ai-chat/MessageInput.tsx +3 -3
  31. package/components/ai-chat/MessageList.tsx +3 -3
  32. package/components/ai-chat/TypingIndicator.tsx +2 -2
  33. package/config/app.config.ts +90 -62
  34. package/config/billing.config.ts +5 -10
  35. package/config/dashboard.config.ts +14 -0
  36. package/config/features.config.ts +10 -0
  37. package/config/permissions.config.ts +22 -23
  38. package/docs/{01-overview → public/01-overview}/01-introduction.md +5 -0
  39. package/docs/{01-overview → public/01-overview}/02-customization.md +5 -0
  40. package/docs/{02-features → public/02-features}/03-tasks-entity.md +5 -0
  41. package/docs/{03-ai → public/03-ai}/01-overview.md +5 -0
  42. package/docs/{03-ai → public/03-ai}/02-customization.md +5 -0
  43. package/docs/superadmin/01-setup/01-configuration.md +79 -0
  44. package/docs/superadmin/01-setup/02-deployment.md +82 -0
  45. package/docs/superadmin/02-management/01-users.md +83 -0
  46. package/docs/superadmin/03-integrations/01-langchain.md +139 -0
  47. package/emails/verify-email.ts +33 -0
  48. package/entities/customers/api/docs.md +107 -0
  49. package/entities/customers/api/presets.ts +80 -0
  50. package/entities/pages/api/docs.md +114 -0
  51. package/entities/pages/api/presets.ts +72 -0
  52. package/entities/posts/api/docs.md +120 -0
  53. package/entities/posts/api/presets.ts +74 -0
  54. package/entities/tasks/api/docs.md +126 -0
  55. package/entities/tasks/api/presets.ts +84 -0
  56. package/lib/selectors.ts +7 -4
  57. package/messages/de/admin.json +45 -0
  58. package/messages/en/admin.json +56 -0
  59. package/messages/en/navigation.json +2 -1
  60. package/messages/es/admin.json +56 -0
  61. package/messages/es/navigation.json +2 -1
  62. package/messages/fr/admin.json +45 -0
  63. package/messages/it/admin.json +45 -0
  64. package/messages/pt/admin.json +45 -0
  65. package/migrations/089_add_editor_team_role.sql +15 -23
  66. package/migrations/090_demo_users_teams.sql +11 -11
  67. package/migrations/091_greek_teams_billing.sql +15 -15
  68. package/migrations/093_pages_sample_data.sql +7 -7
  69. package/migrations/098_patterns_sample_data.sql +234 -0
  70. package/nextsparkjs-theme-default-0.1.0-beta.137.tgz +0 -0
  71. package/package.json +4 -3
  72. package/styles/globals.css +42 -0
  73. package/templates/(public)/page.tsx +1 -1
  74. package/tests/cypress/e2e/_utils/devtools/access.bdd.md +262 -0
  75. package/tests/cypress/e2e/_utils/devtools/access.cy.ts +171 -0
  76. package/tests/cypress/e2e/_utils/devtools/navigation.bdd.md +261 -0
  77. package/tests/cypress/e2e/_utils/devtools/navigation.cy.ts +157 -0
  78. package/tests/cypress/e2e/_utils/devtools/pages.bdd.md +303 -0
  79. package/tests/cypress/e2e/_utils/devtools/pages.cy.ts +184 -0
  80. package/tests/cypress/e2e/_utils/docs/README.md +215 -0
  81. package/tests/cypress/e2e/_utils/selectors/auth.bdd.md +354 -0
  82. package/tests/cypress/e2e/_utils/selectors/auth.cy.ts +310 -0
  83. package/tests/cypress/e2e/_utils/selectors/billing.bdd.md +276 -0
  84. package/tests/cypress/e2e/_utils/selectors/billing.cy.ts +182 -0
  85. package/tests/cypress/e2e/_utils/selectors/block-editor.bdd.md +615 -0
  86. package/tests/cypress/e2e/_utils/selectors/block-editor.cy.ts +783 -0
  87. package/tests/cypress/e2e/_utils/selectors/dashboard-container.cy.ts +52 -0
  88. package/tests/cypress/e2e/_utils/selectors/dashboard-mobile.bdd.md +205 -0
  89. package/tests/cypress/e2e/_utils/selectors/dashboard-mobile.cy.ts +137 -0
  90. package/tests/cypress/e2e/_utils/selectors/dashboard-navigation.bdd.md +147 -0
  91. package/tests/cypress/e2e/_utils/selectors/dashboard-navigation.cy.ts +114 -0
  92. package/tests/cypress/e2e/_utils/selectors/dashboard-sidebar.bdd.md +76 -0
  93. package/tests/cypress/e2e/_utils/selectors/dashboard-sidebar.cy.ts +68 -0
  94. package/tests/cypress/e2e/_utils/selectors/dashboard-topnav.bdd.md +326 -0
  95. package/tests/cypress/e2e/_utils/selectors/dashboard-topnav.cy.ts +177 -0
  96. package/tests/cypress/e2e/_utils/selectors/devtools.bdd.md +306 -0
  97. package/tests/cypress/e2e/_utils/selectors/devtools.cy.ts +273 -0
  98. package/tests/cypress/e2e/_utils/selectors/global-search.bdd.md +115 -0
  99. package/tests/cypress/e2e/_utils/selectors/global-search.cy.ts +93 -0
  100. package/tests/cypress/e2e/_utils/selectors/patterns.bdd.md +388 -0
  101. package/tests/cypress/e2e/_utils/selectors/patterns.cy.ts +559 -0
  102. package/tests/cypress/e2e/_utils/selectors/public.cy.ts +112 -0
  103. package/tests/cypress/e2e/_utils/selectors/settings-api-keys.bdd.md +266 -0
  104. package/tests/cypress/e2e/_utils/selectors/settings-api-keys.cy.ts +233 -0
  105. package/tests/cypress/e2e/_utils/selectors/settings-billing.bdd.md +78 -0
  106. package/tests/cypress/e2e/_utils/selectors/settings-billing.cy.ts +108 -0
  107. package/tests/cypress/e2e/_utils/selectors/settings-layout.bdd.md +129 -0
  108. package/tests/cypress/e2e/_utils/selectors/settings-layout.cy.ts +115 -0
  109. package/tests/cypress/e2e/_utils/selectors/settings-password.bdd.md +82 -0
  110. package/tests/cypress/e2e/_utils/selectors/settings-password.cy.ts +74 -0
  111. package/tests/cypress/e2e/_utils/selectors/settings-profile.bdd.md +77 -0
  112. package/tests/cypress/e2e/_utils/selectors/settings-profile.cy.ts +79 -0
  113. package/tests/cypress/e2e/_utils/selectors/settings-teams.bdd.md +130 -0
  114. package/tests/cypress/e2e/_utils/selectors/settings-teams.cy.ts +86 -0
  115. package/tests/cypress/e2e/_utils/selectors/superadmin.bdd.md +261 -0
  116. package/tests/cypress/e2e/_utils/selectors/superadmin.cy.ts +193 -0
  117. package/tests/cypress/e2e/_utils/selectors/tasks.bdd.md +593 -0
  118. package/tests/cypress/e2e/_utils/selectors/tasks.cy.ts +864 -0
  119. package/tests/cypress/e2e/_utils/selectors/taxonomies.cy.ts +126 -0
  120. package/tests/cypress/e2e/_utils/selectors/teams.bdd.md +278 -0
  121. package/tests/cypress/e2e/_utils/selectors/teams.cy.ts +195 -0
  122. package/tests/cypress/e2e/_utils/superadmin/all-teams.bdd.md +261 -0
  123. package/tests/cypress/e2e/_utils/superadmin/all-teams.cy.ts +177 -0
  124. package/tests/cypress/e2e/_utils/superadmin/all-users.bdd.md +406 -0
  125. package/tests/cypress/e2e/_utils/superadmin/all-users.cy.ts +294 -0
  126. package/tests/cypress/e2e/_utils/superadmin/dashboard.bdd.md +235 -0
  127. package/tests/cypress/e2e/_utils/superadmin/dashboard.cy.ts +149 -0
  128. package/tests/cypress/e2e/_utils/superadmin/subscriptions-overview.bdd.md +290 -0
  129. package/tests/cypress/e2e/_utils/superadmin/subscriptions-overview.cy.ts +194 -0
  130. package/tests/cypress/e2e/ai/ai-usage.cy.ts +209 -0
  131. package/tests/cypress/e2e/ai/chat-api.cy.ts +119 -0
  132. package/tests/cypress/e2e/ai/guardrails.cy.ts +332 -0
  133. package/tests/cypress/e2e/api/_core/billing/BillingAPIController.js +319 -0
  134. package/tests/cypress/e2e/api/_core/billing/check-action.cy.ts +326 -0
  135. package/tests/cypress/e2e/api/_core/billing/checkout.cy.ts +358 -0
  136. package/tests/cypress/e2e/api/_core/billing/lifecycle.cy.ts +423 -0
  137. package/tests/cypress/e2e/api/_core/billing/plans/README.md +345 -0
  138. package/tests/cypress/e2e/api/_core/billing/plans/business.cy.ts +412 -0
  139. package/tests/cypress/e2e/api/_core/billing/plans/downgrade.cy.ts +510 -0
  140. package/tests/cypress/e2e/api/_core/billing/plans/fixtures/billing-plans.json +163 -0
  141. package/tests/cypress/e2e/api/_core/billing/plans/free.cy.ts +500 -0
  142. package/tests/cypress/e2e/api/_core/billing/plans/pro.cy.ts +497 -0
  143. package/tests/cypress/e2e/api/_core/billing/plans/starter.cy.ts +342 -0
  144. package/tests/cypress/e2e/api/_core/billing/portal.cy.ts +313 -0
  145. package/tests/cypress/e2e/api/_core/devtools/registries.bdd.md +300 -0
  146. package/tests/cypress/e2e/api/_core/devtools/registries.cy.ts +368 -0
  147. package/tests/cypress/e2e/api/_core/scheduled-actions/cron-endpoint.bdd.md +375 -0
  148. package/tests/cypress/e2e/api/_core/scheduled-actions/cron-endpoint.cy.ts +346 -0
  149. package/tests/cypress/e2e/api/_core/scheduled-actions/devtools-endpoint.bdd.md +451 -0
  150. package/tests/cypress/e2e/api/_core/scheduled-actions/devtools-endpoint.cy.ts +447 -0
  151. package/tests/cypress/e2e/api/_core/scheduled-actions/scheduling.bdd.md +649 -0
  152. package/tests/cypress/e2e/api/_core/scheduled-actions/scheduling.cy.ts +333 -0
  153. package/tests/cypress/e2e/api/_core/security/security-headers.cy.ts +601 -0
  154. package/tests/cypress/e2e/api/_core/settings/api-keys.crud.cy.ts +923 -0
  155. package/tests/cypress/e2e/api/_core/teams/teams-security.cy.ts +415 -0
  156. package/tests/cypress/e2e/api/_core/users/users-crud.cy.ts +469 -0
  157. package/tests/cypress/e2e/api/_core/users/users-metas.cy.ts +913 -0
  158. package/tests/cypress/e2e/api/_core/users/users-security.cy.ts +375 -0
  159. package/tests/cypress/e2e/api/entities/customers/customers-crud.cy.ts +648 -0
  160. package/tests/cypress/e2e/api/entities/customers/customers-metas.cy.ts +839 -0
  161. package/tests/cypress/e2e/api/entities/media/media-crud.cy.ts +600 -0
  162. package/tests/cypress/e2e/api/entities/media/media-role-permissions.cy.ts +617 -0
  163. package/tests/cypress/e2e/api/entities/media/media-team-isolation.cy.ts +464 -0
  164. package/tests/cypress/e2e/api/entities/pages/blocks-scope.cy.ts +396 -0
  165. package/tests/cypress/e2e/api/entities/pages/pages-crud.cy.ts +425 -0
  166. package/tests/cypress/e2e/api/entities/pages/pages-status.cy.ts +335 -0
  167. package/tests/cypress/e2e/api/entities/posts/post-categories-crud.cy.ts +610 -0
  168. package/tests/cypress/e2e/api/entities/posts/posts-crud.cy.ts +709 -0
  169. package/tests/cypress/e2e/api/entities/posts/posts-status.cy.ts +396 -0
  170. package/tests/cypress/e2e/api/entities/tasks/tasks-crud.cy.ts +602 -0
  171. package/tests/cypress/e2e/api/entities/tasks/tasks-metas.cy.ts +878 -0
  172. package/tests/cypress/e2e/patterns/patterns-in-pages.cy.ts +367 -0
  173. package/tests/cypress/e2e/uat/_core/auth/app-roles/developer-login.bdd.md +231 -0
  174. package/tests/cypress/e2e/uat/_core/auth/app-roles/developer-login.cy.ts +144 -0
  175. package/tests/cypress/e2e/uat/_core/auth/app-roles/superadmin-login.bdd.md +118 -0
  176. package/tests/cypress/e2e/uat/_core/auth/app-roles/superadmin-login.cy.ts +84 -0
  177. package/tests/cypress/e2e/uat/_core/auth/custom-roles/editor-login.bdd.md +288 -0
  178. package/tests/cypress/e2e/uat/_core/auth/custom-roles/editor-login.cy.ts +188 -0
  179. package/tests/cypress/e2e/uat/_core/auth/login-logout.bdd.md +160 -0
  180. package/tests/cypress/e2e/uat/_core/auth/login-logout.cy.ts +116 -0
  181. package/tests/cypress/e2e/uat/_core/auth/password-reset.bdd.md +289 -0
  182. package/tests/cypress/e2e/uat/_core/auth/password-reset.cy.ts +200 -0
  183. package/tests/cypress/e2e/uat/_core/auth/registration-control-invitation.cy.ts +176 -0
  184. package/tests/cypress/e2e/uat/_core/auth/registration-control-open.cy.ts +131 -0
  185. package/tests/cypress/e2e/uat/_core/auth/registration-control.cy.ts +140 -0
  186. package/tests/cypress/e2e/uat/_core/auth/team-roles/admin-login.bdd.md +225 -0
  187. package/tests/cypress/e2e/uat/_core/auth/team-roles/admin-login.cy.ts +148 -0
  188. package/tests/cypress/e2e/uat/_core/auth/team-roles/member-login.bdd.md +251 -0
  189. package/tests/cypress/e2e/uat/_core/auth/team-roles/member-login.cy.ts +163 -0
  190. package/tests/cypress/e2e/uat/_core/auth/team-roles/owner-login.bdd.md +231 -0
  191. package/tests/cypress/e2e/uat/_core/auth/team-roles/owner-login.cy.ts +141 -0
  192. package/tests/cypress/e2e/uat/_core/billing/extended.bdd.md +273 -0
  193. package/tests/cypress/e2e/uat/_core/billing/extended.cy.ts +209 -0
  194. package/tests/cypress/e2e/uat/_core/billing/feature-gates.bdd.md +407 -0
  195. package/tests/cypress/e2e/uat/_core/billing/feature-gates.cy.ts +307 -0
  196. package/tests/cypress/e2e/uat/_core/billing/page.bdd.md +329 -0
  197. package/tests/cypress/e2e/uat/_core/billing/page.cy.ts +250 -0
  198. package/tests/cypress/e2e/uat/_core/billing/status.bdd.md +190 -0
  199. package/tests/cypress/e2e/uat/_core/billing/status.cy.ts +145 -0
  200. package/tests/cypress/e2e/uat/_core/billing/team-switch.bdd.md +156 -0
  201. package/tests/cypress/e2e/uat/_core/billing/team-switch.cy.ts +122 -0
  202. package/tests/cypress/e2e/uat/_core/billing/usage.bdd.md +218 -0
  203. package/tests/cypress/e2e/uat/_core/billing/usage.cy.ts +176 -0
  204. package/tests/cypress/e2e/uat/_core/blocks/hero.bdd.md +124 -0
  205. package/tests/cypress/e2e/uat/_core/blocks/hero.cy.ts +56 -0
  206. package/tests/cypress/e2e/uat/_core/devtools/api-tester.cy.ts +390 -0
  207. package/tests/cypress/e2e/uat/_core/performance/suspense-loading.cy.ts +134 -0
  208. package/tests/cypress/e2e/uat/_core/scheduled-actions/devtools-ui.bdd.md +736 -0
  209. package/tests/cypress/e2e/uat/_core/scheduled-actions/devtools-ui.cy.ts +740 -0
  210. package/tests/cypress/e2e/uat/_core/teams/inline-edit.cy.ts +278 -0
  211. package/tests/cypress/e2e/uat/_core/teams/roles-matrix.bdd.md +553 -0
  212. package/tests/cypress/e2e/uat/_core/teams/roles-matrix.cy.ts +185 -0
  213. package/tests/cypress/e2e/uat/_core/teams/switcher.bdd.md +1151 -0
  214. package/tests/cypress/e2e/uat/_core/teams/switcher.cy.ts +497 -0
  215. package/tests/cypress/e2e/uat/_core/teams/team-switcher.md +198 -0
  216. package/tests/cypress/e2e/uat/entities/customers/member.bdd.md +275 -0
  217. package/tests/cypress/e2e/uat/entities/customers/member.cy.ts +122 -0
  218. package/tests/cypress/e2e/uat/entities/customers/owner.bdd.md +243 -0
  219. package/tests/cypress/e2e/uat/entities/customers/owner.cy.ts +165 -0
  220. package/tests/cypress/e2e/uat/entities/pages/block-crud.bdd.md +476 -0
  221. package/tests/cypress/e2e/uat/entities/pages/block-crud.cy.ts +486 -0
  222. package/tests/cypress/e2e/uat/entities/pages/block-editor.bdd.md +460 -0
  223. package/tests/cypress/e2e/uat/entities/pages/block-editor.cy.ts +301 -0
  224. package/tests/cypress/e2e/uat/entities/pages/list.bdd.md +432 -0
  225. package/tests/cypress/e2e/uat/entities/pages/list.cy.ts +273 -0
  226. package/tests/cypress/e2e/uat/entities/pages/public-rendering.bdd.md +696 -0
  227. package/tests/cypress/e2e/uat/entities/pages/public-rendering.cy.ts +340 -0
  228. package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.bdd.md +161 -0
  229. package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.cy.ts +104 -0
  230. package/tests/cypress/e2e/uat/entities/posts/categories.bdd.md +375 -0
  231. package/tests/cypress/e2e/uat/entities/posts/categories.cy.ts +241 -0
  232. package/tests/cypress/e2e/uat/entities/posts/editor.bdd.md +429 -0
  233. package/tests/cypress/e2e/uat/entities/posts/editor.cy.ts +257 -0
  234. package/tests/cypress/e2e/uat/entities/posts/list.bdd.md +340 -0
  235. package/tests/cypress/e2e/uat/entities/posts/list.cy.ts +177 -0
  236. package/tests/cypress/e2e/uat/entities/posts/public.bdd.md +614 -0
  237. package/tests/cypress/e2e/uat/entities/posts/public.cy.ts +249 -0
  238. package/tests/cypress/e2e/uat/entities/tasks/member.bdd.md +222 -0
  239. package/tests/cypress/e2e/uat/entities/tasks/member.cy.ts +165 -0
  240. package/tests/cypress/e2e/uat/entities/tasks/owner.bdd.md +419 -0
  241. package/tests/cypress/e2e/uat/entities/tasks/owner.cy.ts +191 -0
  242. package/tests/cypress/e2e/uat/features/roles/editor-role.bdd.md +552 -0
  243. package/tests/cypress/e2e/uat/features/roles/editor-role.cy.ts +210 -0
  244. package/tests/cypress/e2e/uat/features/roles/member-restrictions.bdd.md +450 -0
  245. package/tests/cypress/e2e/uat/features/roles/member-restrictions.cy.ts +189 -0
  246. package/tests/cypress/e2e/uat/features/roles/owner-full-crud.bdd.md +530 -0
  247. package/tests/cypress/e2e/uat/features/roles/owner-full-crud.cy.ts +247 -0
  248. package/tests/cypress/fixtures/blocks.json +218 -0
  249. package/tests/cypress/fixtures/entities.json +87 -0
  250. package/tests/cypress/fixtures/page-builder.json +21 -0
  251. package/tests/cypress/src/components/CategoriesPOM.ts +382 -0
  252. package/tests/cypress/src/components/CustomersPOM.ts +439 -0
  253. package/tests/cypress/src/components/DevKeyringPOM.ts +160 -0
  254. package/tests/cypress/src/components/EntityForm.ts +375 -0
  255. package/tests/cypress/src/components/EntityList.ts +389 -0
  256. package/tests/cypress/src/components/PageBuilderPOM.ts +710 -0
  257. package/tests/cypress/src/components/PostEditorPOM.ts +370 -0
  258. package/tests/cypress/src/components/PostsListPOM.ts +223 -0
  259. package/tests/cypress/src/components/PublicPagePOM.ts +447 -0
  260. package/tests/cypress/src/components/PublicPostPOM.ts +146 -0
  261. package/tests/cypress/src/components/TasksPOM.ts +272 -0
  262. package/tests/cypress/src/components/TeamSwitcherPOM.ts +450 -0
  263. package/tests/cypress/src/components/index.ts +21 -0
  264. package/tests/cypress/src/controllers/ApiKeysAPIController.js +178 -0
  265. package/tests/cypress/src/controllers/BaseAPIController.js +317 -0
  266. package/tests/cypress/src/controllers/CustomerAPIController.js +251 -0
  267. package/tests/cypress/src/controllers/MediaAPIController.js +231 -0
  268. package/tests/cypress/src/controllers/PagesAPIController.js +226 -0
  269. package/tests/cypress/src/controllers/PostsAPIController.js +250 -0
  270. package/tests/cypress/src/controllers/TaskAPIController.js +240 -0
  271. package/tests/cypress/src/controllers/UsersAPIController.js +242 -0
  272. package/tests/cypress/src/controllers/index.js +25 -0
  273. package/tests/cypress/src/core/AuthPOM.ts +450 -0
  274. package/tests/cypress/src/core/BasePOM.ts +33 -0
  275. package/tests/cypress/src/core/BlockEditorBasePOM.ts +874 -0
  276. package/tests/cypress/src/core/DashboardEntityPOM.ts +41 -0
  277. package/tests/cypress/src/core/index.ts +14 -0
  278. package/tests/cypress/src/entities/CustomersPOM.ts +172 -0
  279. package/tests/cypress/src/entities/PagesPOM.ts +137 -0
  280. package/tests/cypress/src/entities/PatternsPOM.ts +329 -0
  281. package/tests/cypress/src/entities/PostsPOM.ts +137 -0
  282. package/tests/cypress/src/entities/TasksPOM.ts +246 -0
  283. package/tests/cypress/src/entities/index.ts +16 -0
  284. package/tests/cypress/src/features/BillingPOM.ts +385 -0
  285. package/tests/cypress/src/features/DashboardPOM.ts +271 -0
  286. package/tests/cypress/src/features/DevtoolsPOM.ts +750 -0
  287. package/tests/cypress/src/features/PageBuilderPOM.ts +283 -0
  288. package/tests/cypress/src/features/PostEditorPOM.ts +313 -0
  289. package/tests/cypress/src/features/ScheduledActionsPOM.ts +463 -0
  290. package/tests/cypress/src/features/SettingsPOM.ts +707 -0
  291. package/tests/cypress/src/features/SuperadminPOM.ts +851 -0
  292. package/tests/cypress/src/features/SuperadminTeamRolesPOM.ts +285 -0
  293. package/tests/cypress/src/features/index.ts +28 -0
  294. package/tests/cypress/src/helpers/ApiInterceptor.ts +20 -0
  295. package/tests/cypress/src/index.ts +101 -0
  296. package/tests/cypress/src/pages/dashboard/Dashboard.js +677 -0
  297. package/tests/cypress/src/pages/dashboard/DashboardPage.js +43 -0
  298. package/tests/cypress/src/pages/dashboard/DashboardStats.js +546 -0
  299. package/tests/cypress/src/pages/dashboard/index.js +6 -0
  300. package/tests/cypress/src/pages/index.js +5 -0
  301. package/tests/cypress/src/pages/public/FeaturesPage.js +28 -0
  302. package/tests/cypress/src/pages/public/LandingPage.js +69 -0
  303. package/tests/cypress/src/pages/public/PricingPage.js +33 -0
  304. package/tests/cypress/src/pages/public/index.js +6 -0
  305. package/tests/cypress/src/selectors.ts +46 -0
  306. package/tests/cypress/src/session-helpers.ts +518 -0
  307. package/tests/cypress/support/doc-commands.ts +260 -0
  308. package/tests/cypress/support/e2e.ts +90 -0
  309. package/tests/cypress.config.ts +178 -0
  310. package/tests/jest/__mocks__/@nextsparkjs/core/components/ui/badge.js +16 -0
  311. package/tests/jest/__mocks__/@nextsparkjs/core/lib/db.js +11 -0
  312. package/tests/jest/__mocks__/@nextsparkjs/registries/permissions-registry.ts +160 -0
  313. package/tests/jest/__mocks__/@nextsparkjs/registries/theme-registry.ts +68 -0
  314. package/tests/jest/__mocks__/jose.js +22 -0
  315. package/tests/jest/__mocks__/next/image.js +15 -0
  316. package/tests/jest/__mocks__/next-server.js +56 -0
  317. package/tests/jest/components/post-header.test.tsx +377 -0
  318. package/tests/jest/jest.config.cjs +154 -0
  319. package/tests/jest/langchain/COVERAGE.md +372 -0
  320. package/tests/jest/langchain/guardrails.test.ts +465 -0
  321. package/tests/jest/langchain/streaming.test.ts +370 -0
  322. package/tests/jest/langchain/token-tracker.test.ts +455 -0
  323. package/tests/jest/langchain/tracer-callbacks.test.ts +881 -0
  324. package/tests/jest/langchain/tracer.test.ts +823 -0
  325. package/tests/jest/services/tasks.service.test.ts +707 -0
  326. package/tests/jest/setup.ts +170 -0
  327. package/tests/jest/tsconfig.jest.json +6 -0
  328. package/tests/jest/validation/categories.test.ts +429 -0
  329. package/tests/jest/validation/posts.test.ts +546 -0
  330. package/tests/tsconfig.json +21 -0
  331. /package/docs/{02-features → public/02-features}/01-components.md +0 -0
  332. /package/docs/{02-features → public/02-features}/02-styling.md +0 -0
@@ -0,0 +1,385 @@
1
+ /**
2
+ * Billing Page Object Model
3
+ *
4
+ * Encapsulates interactions with the billing settings page:
5
+ * - /dashboard/settings/billing
6
+ *
7
+ * UI Elements:
8
+ * - Current plan card with usage
9
+ * - Billing history (invoices)
10
+ * - Payment method
11
+ * - Plan features
12
+ *
13
+ * @version 3.0 - Uses centralized selectors from cySelector()
14
+ */
15
+
16
+ import { BasePOM } from '../core/BasePOM'
17
+ import { cySelector } from '../selectors'
18
+
19
+ export class BillingPOM extends BasePOM {
20
+ /**
21
+ * Selectors using centralized cySelector()
22
+ */
23
+ get selectors() {
24
+ return {
25
+ main: cySelector('settings.billing.main'),
26
+ header: cySelector('settings.billing.header'),
27
+ upgradePlan: cySelector('settings.billing.upgradePlan'),
28
+ addPayment: cySelector('settings.billing.addPayment'),
29
+ invoicesTable: cySelector('settings.billing.invoicesTableAlt'),
30
+ invoicesRow: cySelector('settings.billing.invoicesRow'),
31
+ invoicesLoadMore: cySelector('settings.billing.invoicesLoadMore'),
32
+ invoiceStatusBadge: cySelector('settings.billing.invoiceStatusBadge'),
33
+ paymentMethod: cySelector('settings.billing.paymentMethod'),
34
+ usage: cySelector('settings.billing.usage'),
35
+ usageDashboard: cySelector('settings.billing.usageDashboard'),
36
+ pricingTable: cySelector('settings.pricing.table'),
37
+ pricingSettingsTable: cySelector('settings.pricing.settingsTable'),
38
+ featurePlaceholder: (feature: string) => cySelector('settings.features.placeholder', { feature }),
39
+ featureContent: (feature: string) => cySelector('settings.features.content', { feature }),
40
+ placeholderUpgradeBtn: cySelector('settings.features.placeholderUpgradeBtn'),
41
+ }
42
+ }
43
+
44
+ // Factory method for clean instantiation
45
+ static create(): BillingPOM {
46
+ return new BillingPOM()
47
+ }
48
+
49
+ // ============================================================
50
+ // NAVIGATION
51
+ // ============================================================
52
+
53
+ /**
54
+ * Visit billing settings page
55
+ * Uses failOnStatusCode: false to handle intermittent 500 errors
56
+ */
57
+ visitBilling(): BillingPOM {
58
+ cy.visit('/dashboard/settings/billing', { timeout: 60000, failOnStatusCode: false })
59
+ cy.url().should('include', '/billing')
60
+ return this
61
+ }
62
+
63
+ /**
64
+ * Visit pricing page
65
+ */
66
+ visitPricing(): BillingPOM {
67
+ cy.visit('/pricing', { timeout: 30000 })
68
+ return this
69
+ }
70
+
71
+ // ============================================================
72
+ // SELECTORS
73
+ // ============================================================
74
+
75
+ /**
76
+ * Main billing container
77
+ */
78
+ getBillingMain(): Cypress.Chainable<JQuery<HTMLElement>> {
79
+ return cy.get(this.selectors.main)
80
+ }
81
+
82
+ /**
83
+ * Billing header
84
+ */
85
+ getBillingHeader(): Cypress.Chainable<JQuery<HTMLElement>> {
86
+ return cy.get(this.selectors.header)
87
+ }
88
+
89
+ /**
90
+ * Upgrade plan button
91
+ */
92
+ getUpgradeButton(): Cypress.Chainable<JQuery<HTMLElement>> {
93
+ return cy.get(this.selectors.upgradePlan)
94
+ }
95
+
96
+ /**
97
+ * Add payment method button
98
+ */
99
+ getAddPaymentButton(): Cypress.Chainable<JQuery<HTMLElement>> {
100
+ return cy.get(this.selectors.addPayment)
101
+ }
102
+
103
+ /**
104
+ * Load more invoices button
105
+ */
106
+ getLoadMoreInvoicesButton(): Cypress.Chainable<JQuery<HTMLElement>> {
107
+ return cy.get(this.selectors.invoicesLoadMore)
108
+ }
109
+
110
+ /**
111
+ * Invoices table
112
+ */
113
+ getInvoicesTable(): Cypress.Chainable<JQuery<HTMLElement>> {
114
+ return cy.get(this.selectors.invoicesTable)
115
+ }
116
+
117
+ /**
118
+ * Invoice rows
119
+ */
120
+ getInvoiceRows(): Cypress.Chainable<JQuery<HTMLElement>> {
121
+ return cy.get(this.selectors.invoicesRow)
122
+ }
123
+
124
+ /**
125
+ * Invoice status badges
126
+ */
127
+ getInvoiceStatusBadge(): Cypress.Chainable<JQuery<HTMLElement>> {
128
+ return cy.get(this.selectors.invoiceStatusBadge)
129
+ }
130
+
131
+ // ============================================================
132
+ // ASSERTIONS
133
+ // ============================================================
134
+
135
+ /**
136
+ * Assert billing page is visible
137
+ */
138
+ assertBillingPageVisible(): BillingPOM {
139
+ this.getBillingMain().should('be.visible')
140
+ this.getBillingHeader().should('be.visible')
141
+ return this
142
+ }
143
+
144
+ /**
145
+ * Assert current plan is displayed
146
+ * @param planName Expected plan name (e.g., "Free", "Pro")
147
+ */
148
+ assertCurrentPlan(planName: string): BillingPOM {
149
+ cy.contains(planName).should('be.visible')
150
+ return this
151
+ }
152
+
153
+ /**
154
+ * Assert upgrade button is visible
155
+ */
156
+ assertUpgradeButtonVisible(): BillingPOM {
157
+ this.getUpgradeButton().should('be.visible')
158
+ return this
159
+ }
160
+
161
+ /**
162
+ * Assert invoices are displayed
163
+ * @param count Expected number of invoices (0 for empty state)
164
+ */
165
+ assertInvoicesCount(count: number): BillingPOM {
166
+ if (count === 0) {
167
+ // Empty state
168
+ cy.contains(/no invoices|sin facturas/i).should('be.visible')
169
+ } else {
170
+ this.getInvoiceRows().should('have.length.at.least', count)
171
+ }
172
+ return this
173
+ }
174
+
175
+ /**
176
+ * Assert no payment method message
177
+ */
178
+ assertNoPaymentMethod(): BillingPOM {
179
+ // Match both English and Spanish:
180
+ // EN: "No payment method configured"
181
+ // ES: "No hay método de pago configurado"
182
+ cy.contains(/no payment method configured|no hay método de pago configurado/i).should('be.visible')
183
+ return this
184
+ }
185
+
186
+ /**
187
+ * Assert usage is displayed
188
+ */
189
+ assertUsageVisible(): BillingPOM {
190
+ // Check for usage numbers (format: X / Y)
191
+ cy.contains(/\d+\s*\/\s*\d+/).should('be.visible')
192
+ return this
193
+ }
194
+
195
+ // ============================================================
196
+ // ACTIONS
197
+ // ============================================================
198
+
199
+ /**
200
+ * Click upgrade button
201
+ */
202
+ clickUpgrade(): BillingPOM {
203
+ this.getUpgradeButton().click()
204
+ return this
205
+ }
206
+
207
+ /**
208
+ * Click add payment button
209
+ */
210
+ clickAddPayment(): BillingPOM {
211
+ this.getAddPaymentButton().click()
212
+ return this
213
+ }
214
+
215
+ /**
216
+ * Load more invoices
217
+ */
218
+ loadMoreInvoices(): BillingPOM {
219
+ this.getLoadMoreInvoicesButton().click()
220
+ return this
221
+ }
222
+
223
+ // ============================================================
224
+ // FEATURE GATE ASSERTIONS
225
+ // ============================================================
226
+
227
+ /**
228
+ * Assert feature is blocked (shows upgrade message)
229
+ * @param featureName Name of the blocked feature
230
+ */
231
+ assertFeatureBlocked(featureName: string): BillingPOM {
232
+ cy.contains(new RegExp(`(upgrade|plan required|not available)`, 'i')).should('be.visible')
233
+ return this
234
+ }
235
+
236
+ /**
237
+ * Assert feature is available
238
+ * @param featureName Name of the feature
239
+ */
240
+ assertFeatureAvailable(featureName: string): BillingPOM {
241
+ // No upgrade message for this feature
242
+ cy.contains(featureName).should('be.visible')
243
+ return this
244
+ }
245
+
246
+ // ============================================================
247
+ // PRICING PAGE METHODS
248
+ // ============================================================
249
+
250
+ /**
251
+ * Visit pricing settings page
252
+ */
253
+ visitPricingSettings(): BillingPOM {
254
+ cy.visit('/dashboard/settings/pricing', { timeout: 30000 })
255
+ return this
256
+ }
257
+
258
+ /**
259
+ * Get pricing table
260
+ */
261
+ getPricingTable(): Cypress.Chainable<JQuery<HTMLElement>> {
262
+ return cy.get(`${this.selectors.pricingTable}, ${this.selectors.pricingSettingsTable}`)
263
+ }
264
+
265
+ /**
266
+ * Assert pricing table is visible
267
+ */
268
+ assertPricingTableVisible(): BillingPOM {
269
+ this.getPricingTable().should('be.visible')
270
+ return this
271
+ }
272
+
273
+ // ============================================================
274
+ // FEATURE PAGES METHODS
275
+ // ============================================================
276
+
277
+ /**
278
+ * Visit feature analytics page
279
+ */
280
+ visitAnalyticsFeature(): BillingPOM {
281
+ cy.visit('/dashboard/features/analytics', { timeout: 30000 })
282
+ return this
283
+ }
284
+
285
+ /**
286
+ * Visit feature webhooks page
287
+ */
288
+ visitWebhooksFeature(): BillingPOM {
289
+ cy.visit('/dashboard/features/webhooks', { timeout: 30000 })
290
+ return this
291
+ }
292
+
293
+ /**
294
+ * Visit feature automation page
295
+ */
296
+ visitAutomationFeature(): BillingPOM {
297
+ cy.visit('/dashboard/features/automation', { timeout: 30000 })
298
+ return this
299
+ }
300
+
301
+ /**
302
+ * Get feature placeholder
303
+ */
304
+ getFeaturePlaceholder(feature: string): Cypress.Chainable<JQuery<HTMLElement>> {
305
+ return cy.get(this.selectors.featurePlaceholder(feature))
306
+ }
307
+
308
+ /**
309
+ * Assert feature placeholder is visible
310
+ */
311
+ assertFeaturePlaceholderVisible(feature: string): BillingPOM {
312
+ this.getFeaturePlaceholder(feature).should('be.visible')
313
+ return this
314
+ }
315
+
316
+ /**
317
+ * Assert feature content is visible (user has access)
318
+ */
319
+ assertFeatureContentVisible(feature: string): BillingPOM {
320
+ cy.get(this.selectors.featureContent(feature)).should('be.visible')
321
+ return this
322
+ }
323
+
324
+ /**
325
+ * Get placeholder upgrade button
326
+ */
327
+ getPlaceholderUpgradeButton(): Cypress.Chainable<JQuery<HTMLElement>> {
328
+ return cy.get(this.selectors.placeholderUpgradeBtn)
329
+ }
330
+
331
+ /**
332
+ * Click placeholder upgrade button
333
+ */
334
+ clickPlaceholderUpgrade(): BillingPOM {
335
+ this.getPlaceholderUpgradeButton().click()
336
+ return this
337
+ }
338
+
339
+ // ============================================================
340
+ // USAGE METHODS
341
+ // ============================================================
342
+
343
+ /**
344
+ * Get usage section
345
+ */
346
+ getUsageSection(): Cypress.Chainable<JQuery<HTMLElement>> {
347
+ return cy.get(`${this.selectors.usage}, ${this.selectors.usageDashboard}`)
348
+ }
349
+
350
+ /**
351
+ * Assert usage limit is displayed
352
+ * @param limitName Name of the limit (e.g., "tasks", "customers")
353
+ * @param current Current usage (optional, just checks format if not provided)
354
+ * @param max Maximum allowed (optional)
355
+ */
356
+ assertUsageLimit(limitName: string, current?: number, max?: number): BillingPOM {
357
+ if (current !== undefined && max !== undefined) {
358
+ cy.contains(new RegExp(`${current}\\s*/\\s*${max}`, 'i')).should('be.visible')
359
+ } else {
360
+ // Just check for X / Y format
361
+ cy.contains(/\d+\s*\/\s*\d+/).should('be.visible')
362
+ }
363
+ return this
364
+ }
365
+
366
+ // ============================================================
367
+ // PAYMENT METHODS
368
+ // ============================================================
369
+
370
+ /**
371
+ * Get payment method section
372
+ */
373
+ getPaymentMethodSection(): Cypress.Chainable<JQuery<HTMLElement>> {
374
+ const paymentMethodAlt = cySelector('settings.billing.paymentMethodAlt')
375
+ return cy.get(`${this.selectors.paymentMethod}, ${paymentMethodAlt}`)
376
+ }
377
+
378
+ /**
379
+ * Assert payment method exists
380
+ */
381
+ assertPaymentMethodExists(): BillingPOM {
382
+ this.getPaymentMethodSection().should('be.visible')
383
+ return this
384
+ }
385
+ }
@@ -0,0 +1,271 @@
1
+ /**
2
+ * DashboardPOM - Page Object Model for Dashboard Navigation
3
+ *
4
+ * Handles dashboard shell navigation and access control:
5
+ * - Sidebar navigation links (nav-link-entity-{slug})
6
+ * - Entity page access verification
7
+ * - Quick create menu
8
+ * - Dashboard page access
9
+ *
10
+ * Uses selectors from centralized selectors.ts
11
+ *
12
+ * NOTE: For CRUD operations on entities, use entity-specific POMs:
13
+ * - CustomersPOM, TasksPOM, etc. from entities/
14
+ * - These extend DashboardEntityPOM for full CRUD support
15
+ *
16
+ * NOTE: For team switching, use TeamSwitcherPOM from components/
17
+ */
18
+
19
+ import { BasePOM } from '../core/BasePOM'
20
+ import { cySelector } from '../selectors'
21
+
22
+ export class DashboardPOM extends BasePOM {
23
+ // ============================================
24
+ // FACTORY METHOD
25
+ // ============================================
26
+
27
+ static create(): DashboardPOM {
28
+ return new DashboardPOM()
29
+ }
30
+
31
+ // ============================================
32
+ // SELECTORS
33
+ // ============================================
34
+
35
+ get selectors() {
36
+ return {
37
+ // Main container
38
+ container: cySelector('dashboard.container'),
39
+
40
+ // Navigation
41
+ navContainer: cySelector('dashboard.navigation.container'),
42
+ navDashboard: cySelector('dashboard.navigation.dashboardLink'),
43
+ navEntity: (slug: string) => cySelector('dashboard.navigation.entityLink', { slug }),
44
+ navSection: (id: string) => cySelector('dashboard.navigation.section', { id }),
45
+ navSectionLabel: (id: string) => cySelector('dashboard.navigation.sectionLabel', { id }),
46
+ navSectionItem: (sectionId: string, itemId: string) => cySelector('dashboard.navigation.sectionItem', { sectionId, itemId }),
47
+
48
+ // Topnav
49
+ topnavContainer: cySelector('dashboard.topnav.container'),
50
+ topnavSidebarToggle: cySelector('dashboard.topnav.sidebarToggle'),
51
+ topnavLogo: cySelector('dashboard.topnav.logo'),
52
+ topnavSearchContainer: cySelector('dashboard.topnav.search.container'),
53
+ topnavActions: cySelector('dashboard.topnav.actions'),
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 }),
62
+ topnavHelp: cySelector('dashboard.topnav.help'),
63
+ topnavThemeToggle: cySelector('dashboard.topnav.themeToggle'),
64
+ topnavSuperadmin: cySelector('dashboard.topnav.superadmin'),
65
+ topnavDevtools: cySelector('dashboard.topnav.devtools'),
66
+ topnavUserLoading: cySelector('dashboard.topnav.userLoading'),
67
+ topnavSignin: cySelector('dashboard.topnav.signin'),
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 }),
74
+ // Topnav mobile menu
75
+ topnavMobileMenuToggle: cySelector('dashboard.topnav.mobileMenu.toggle'),
76
+ topnavMobileMenuContainer: cySelector('dashboard.topnav.mobileMenu.container'),
77
+ topnavMobileMenuActions: cySelector('dashboard.topnav.mobileMenu.actions'),
78
+ topnavMobileMenuUserInfo: cySelector('dashboard.topnav.mobileMenu.userInfo'),
79
+ topnavMobileMenuLinkProfile: cySelector('dashboard.topnav.mobileMenu.linkProfile'),
80
+ topnavMobileMenuLinkSettings: cySelector('dashboard.topnav.mobileMenu.linkSettings'),
81
+ topnavMobileMenuLinkBilling: cySelector('dashboard.topnav.mobileMenu.linkBilling'),
82
+ topnavMobileMenuSignout: cySelector('dashboard.topnav.mobileMenu.signout'),
83
+ topnavMobileMenuSuperadmin: cySelector('dashboard.topnav.mobileMenu.superadmin'),
84
+ topnavMobileMenuDevtools: cySelector('dashboard.topnav.mobileMenu.devtools'),
85
+
86
+ // Sidebar
87
+ sidebarContainer: cySelector('dashboard.sidebar.container'),
88
+ sidebarHeader: cySelector('dashboard.sidebar.header'),
89
+ sidebarLogo: cySelector('dashboard.sidebar.logo'),
90
+ sidebarContent: cySelector('dashboard.sidebar.content'),
91
+ sidebarFooter: cySelector('dashboard.sidebar.footer'),
92
+
93
+ // Mobile Topbar
94
+ mobileTopbarContainer: cySelector('dashboard.mobile.topbar.container'),
95
+ mobileTopbarUserProfile: cySelector('dashboard.mobile.topbar.userProfile'),
96
+ mobileTopbarNotifications: cySelector('dashboard.mobile.topbar.notifications'),
97
+ mobileTopbarThemeToggle: cySelector('dashboard.mobile.topbar.themeToggle'),
98
+
99
+ // Mobile Bottom Nav
100
+ mobileBottomNavContainer: cySelector('dashboard.mobile.bottomNav.container'),
101
+ mobileBottomNavItem: (id: string) => cySelector('dashboard.mobile.bottomNav.item', { id }),
102
+
103
+ // Mobile More Sheet
104
+ mobileMoreSheetContainer: cySelector('dashboard.mobile.moreSheet.container'),
105
+ mobileMoreSheetItem: (id: string) => cySelector('dashboard.mobile.moreSheet.item', { id }),
106
+ mobileMoreSheetSuperadminLink: cySelector('dashboard.mobile.moreSheet.superadminLink'),
107
+ mobileMoreSheetTeamSwitcher: cySelector('dashboard.mobile.moreSheet.teamSwitcher'),
108
+ mobileMoreSheetSignoutButton: cySelector('dashboard.mobile.moreSheet.signoutButton'),
109
+
110
+ // Mobile Quick Create Sheet
111
+ mobileQuickCreateSheetContainer: cySelector('dashboard.mobile.quickCreateSheet.container'),
112
+ mobileQuickCreateSheetItem: (slug: string) => cySelector('dashboard.mobile.quickCreateSheet.item', { slug }),
113
+
114
+ // Entity table (for verifying entity pages)
115
+ entityPage: (slug: string) => cySelector('entities.page.container', { slug }),
116
+ entityTable: (slug: string) => cySelector('entities.table.container', { slug }),
117
+ entityAddButton: (slug: string) => cySelector('entities.table.addButton', { slug }),
118
+
119
+ // Legacy aliases (for backward compatibility during transition)
120
+ /** @deprecated Use navContainer instead */
121
+ navMain: cySelector('dashboard.navigation.container'),
122
+ /** @deprecated Use topnavQuickCreateTrigger instead */
123
+ quickCreateButton: cySelector('dashboard.topnav.quickCreate.trigger'),
124
+ /** @deprecated Use topnavQuickCreateContent instead */
125
+ quickCreateDropdown: cySelector('dashboard.topnav.quickCreate.content'),
126
+ /** @deprecated Use topnavQuickCreateLink instead */
127
+ quickCreateLink: (slug: string) => cySelector('dashboard.topnav.quickCreate.link', { slug }),
128
+ }
129
+ }
130
+
131
+ // ============================================
132
+ // NAVIGATION
133
+ // ============================================
134
+
135
+ /**
136
+ * Navigate to main dashboard
137
+ */
138
+ visitDashboard() {
139
+ cy.visit('/dashboard', { timeout: 60000 })
140
+ return this
141
+ }
142
+
143
+ /**
144
+ * Navigate to an entity page
145
+ */
146
+ visitEntity(slug: string) {
147
+ cy.visit(`/dashboard/${slug}`, { timeout: 60000 })
148
+ return this
149
+ }
150
+
151
+ /**
152
+ * Navigate to entity via sidebar link
153
+ */
154
+ clickEntityNav(slug: string) {
155
+ cy.get(this.selectors.navEntity(slug)).click()
156
+ return this
157
+ }
158
+
159
+ /**
160
+ * Navigate to dashboard via sidebar link
161
+ */
162
+ clickDashboardNav() {
163
+ cy.get(this.selectors.navDashboard).click()
164
+ return this
165
+ }
166
+
167
+ // ============================================
168
+ // QUICK CREATE
169
+ // ============================================
170
+
171
+ /**
172
+ * Open quick create dropdown
173
+ */
174
+ openQuickCreate() {
175
+ cy.get(this.selectors.topnavQuickCreateTrigger).click()
176
+ return this
177
+ }
178
+
179
+ /**
180
+ * Click quick create link for an entity
181
+ */
182
+ quickCreate(slug: string) {
183
+ this.openQuickCreate()
184
+ cy.get(this.selectors.topnavQuickCreateLink(slug)).click()
185
+ return this
186
+ }
187
+
188
+ // ============================================
189
+ // ASSERTIONS
190
+ // ============================================
191
+
192
+ /**
193
+ * Assert dashboard page is visible
194
+ */
195
+ assertDashboardVisible() {
196
+ cy.url().should('include', '/dashboard')
197
+ return this
198
+ }
199
+
200
+ /**
201
+ * Assert entity nav link is visible
202
+ */
203
+ assertEntityNavVisible(slug: string) {
204
+ cy.get(this.selectors.navEntity(slug)).should('be.visible')
205
+ return this
206
+ }
207
+
208
+ /**
209
+ * Assert entity nav link is NOT visible (restricted access)
210
+ */
211
+ assertEntityNavNotVisible(slug: string) {
212
+ cy.get(this.selectors.navEntity(slug)).should('not.exist')
213
+ return this
214
+ }
215
+
216
+ /**
217
+ * Assert entity page is accessible (table container visible)
218
+ */
219
+ assertEntityPageVisible(slug: string) {
220
+ cy.get(this.selectors.entityTable(slug)).should('be.visible')
221
+ return this
222
+ }
223
+
224
+ /**
225
+ * Assert entity add button is visible (create permission)
226
+ */
227
+ assertEntityAddButtonVisible(slug: string) {
228
+ cy.get(this.selectors.entityAddButton(slug)).should('be.visible')
229
+ return this
230
+ }
231
+
232
+ /**
233
+ * Assert entity add button is NOT visible (no create permission)
234
+ */
235
+ assertEntityAddButtonNotVisible(slug: string) {
236
+ cy.get(this.selectors.entityAddButton(slug)).should('not.exist')
237
+ return this
238
+ }
239
+
240
+ /**
241
+ * Assert quick create button is visible
242
+ */
243
+ assertQuickCreateVisible() {
244
+ cy.get(this.selectors.topnavQuickCreateTrigger).should('be.visible')
245
+ return this
246
+ }
247
+
248
+ // ============================================
249
+ // WAITS
250
+ // ============================================
251
+
252
+ /**
253
+ * Wait for dashboard to be fully loaded
254
+ */
255
+ waitForDashboard() {
256
+ cy.url().should('include', '/dashboard')
257
+ cy.get(this.selectors.navContainer, { timeout: 15000 }).should('be.visible')
258
+ return this
259
+ }
260
+
261
+ /**
262
+ * Wait for entity page to be loaded
263
+ */
264
+ waitForEntityPage(slug: string) {
265
+ cy.url().should('include', `/dashboard/${slug}`)
266
+ cy.get(this.selectors.entityTable(slug), { timeout: 15000 }).should('be.visible')
267
+ return this
268
+ }
269
+ }
270
+
271
+ export default DashboardPOM