@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,851 @@
1
+ /**
2
+ * SuperadminPOM - Page Object Model for Superadmin Area
3
+ *
4
+ * Handles Superadmin Panel pages:
5
+ * - Dashboard with system stats (/superadmin)
6
+ * - All users management (/superadmin/users, /superadmin/users/[id])
7
+ * - All teams management (/superadmin/teams, /superadmin/teams/[id])
8
+ * - Team Roles - RBAC & Plan Features (/superadmin/team-roles)
9
+ * - Subscriptions overview (/superadmin/subscriptions)
10
+ * - Admin documentation (/superadmin/docs, /superadmin/docs/[section]/[page])
11
+ *
12
+ * Selector Structure (8 first-level keys):
13
+ * - container: Main wrapper
14
+ * - sidebar: Navigation sidebar (collapsible)
15
+ * - dashboard: Dashboard overview page
16
+ * - users: Users management (list + detail)
17
+ * - teams: Teams management (list + detail)
18
+ * - subscriptions: Subscriptions overview
19
+ * - teamRoles: RBAC Matrix and Plan Features
20
+ * - docs: Admin documentation pages
21
+ *
22
+ * Uses selectors from centralized selectors.ts
23
+ */
24
+
25
+ import { BasePOM } from '../core/BasePOM'
26
+ import { cySelector } from '../selectors'
27
+
28
+ type PaginationContext = 'users' | 'teams' | 'subscriptions'
29
+
30
+ export class SuperadminPOM extends BasePOM {
31
+ // ============================================
32
+ // FACTORY METHOD
33
+ // ============================================
34
+
35
+ static create(): SuperadminPOM {
36
+ return new SuperadminPOM()
37
+ }
38
+
39
+ // ============================================
40
+ // SELECTORS
41
+ // ============================================
42
+
43
+ get selectors() {
44
+ return {
45
+ // Main container
46
+ container: cySelector('superadmin.container'),
47
+
48
+ // ─────────────────────────────────────────
49
+ // SIDEBAR - Navigation sidebar (collapsible)
50
+ // ─────────────────────────────────────────
51
+ sidebar: {
52
+ container: cySelector('superadmin.sidebar.container'),
53
+ header: cySelector('superadmin.sidebar.header'),
54
+ collapseButton: cySelector('superadmin.sidebar.collapseButton'),
55
+ securityNotice: cySelector('superadmin.sidebar.securityNotice'),
56
+ nav: {
57
+ dashboard: cySelector('superadmin.sidebar.nav.dashboard'),
58
+ users: cySelector('superadmin.sidebar.nav.users'),
59
+ teams: cySelector('superadmin.sidebar.nav.teams'),
60
+ teamRoles: cySelector('superadmin.sidebar.nav.teamRoles'),
61
+ docs: cySelector('superadmin.sidebar.nav.docs'),
62
+ subscriptions: cySelector('superadmin.sidebar.nav.subscriptions'),
63
+ analytics: cySelector('superadmin.sidebar.nav.analytics'),
64
+ config: cySelector('superadmin.sidebar.nav.config'),
65
+ },
66
+ exitButton: cySelector('superadmin.sidebar.exitButton'),
67
+ },
68
+
69
+ // ─────────────────────────────────────────
70
+ // DASHBOARD - Overview page
71
+ // ─────────────────────────────────────────
72
+ dashboard: {
73
+ container: cySelector('superadmin.dashboard.container'),
74
+ header: {
75
+ title: cySelector('superadmin.dashboard.header.title'),
76
+ badge: cySelector('superadmin.dashboard.header.badge'),
77
+ },
78
+ quickActions: {
79
+ container: cySelector('superadmin.dashboard.quickActions.container'),
80
+ users: cySelector('superadmin.dashboard.quickActions.users'),
81
+ analytics: cySelector('superadmin.dashboard.quickActions.analytics'),
82
+ config: cySelector('superadmin.dashboard.quickActions.config'),
83
+ },
84
+ systemStatus: {
85
+ container: cySelector('superadmin.dashboard.systemStatus.container'),
86
+ online: cySelector('superadmin.dashboard.systemStatus.online'),
87
+ version: cySelector('superadmin.dashboard.systemStatus.version'),
88
+ security: cySelector('superadmin.dashboard.systemStatus.security'),
89
+ },
90
+ },
91
+
92
+ // ─────────────────────────────────────────
93
+ // USERS - User management (list + detail)
94
+ // ─────────────────────────────────────────
95
+ users: {
96
+ container: cySelector('superadmin.users.container'),
97
+ header: {
98
+ backButton: cySelector('superadmin.users.header.backButton'),
99
+ title: cySelector('superadmin.users.header.title'),
100
+ refreshButton: cySelector('superadmin.users.header.refreshButton'),
101
+ },
102
+ stats: {
103
+ totalUsers: cySelector('superadmin.users.stats.totalUsers'),
104
+ workTeams: cySelector('superadmin.users.stats.workTeams'),
105
+ superadmins: cySelector('superadmin.users.stats.superadmins'),
106
+ distribution: cySelector('superadmin.users.stats.distribution'),
107
+ },
108
+ filters: {
109
+ search: cySelector('superadmin.users.filters.search'),
110
+ roleFilter: cySelector('superadmin.users.filters.roleFilter'),
111
+ statusFilter: cySelector('superadmin.users.filters.statusFilter'),
112
+ clearButton: cySelector('superadmin.users.filters.clearButton'),
113
+ },
114
+ tabs: {
115
+ container: cySelector('superadmin.users.tabs.container'),
116
+ regularUsers: cySelector('superadmin.users.tabs.regularUsers'),
117
+ superadmins: cySelector('superadmin.users.tabs.superadmins'),
118
+ },
119
+ table: {
120
+ element: cySelector('superadmin.users.table.element'),
121
+ row: (id: string) => cySelector('superadmin.users.table.row', { id }),
122
+ viewButton: (id: string) => cySelector('superadmin.users.table.viewButton', { id }),
123
+ editButton: (id: string) => cySelector('superadmin.users.table.editButton', { id }),
124
+ banButton: (id: string) => cySelector('superadmin.users.table.banButton', { id }),
125
+ deleteButton: (id: string) => cySelector('superadmin.users.table.deleteButton', { id }),
126
+ impersonateButton: (id: string) => cySelector('superadmin.users.table.impersonateButton', { id }),
127
+ },
128
+ pagination: {
129
+ container: cySelector('superadmin.users.pagination.container'),
130
+ pageSize: cySelector('superadmin.users.pagination.pageSize'),
131
+ first: cySelector('superadmin.users.pagination.first'),
132
+ prev: cySelector('superadmin.users.pagination.prev'),
133
+ next: cySelector('superadmin.users.pagination.next'),
134
+ last: cySelector('superadmin.users.pagination.last'),
135
+ },
136
+ detail: {
137
+ container: cySelector('superadmin.users.detail.container'),
138
+ info: {
139
+ email: cySelector('superadmin.users.detail.info.email'),
140
+ role: cySelector('superadmin.users.detail.info.role'),
141
+ status: cySelector('superadmin.users.detail.info.status'),
142
+ teams: cySelector('superadmin.users.detail.info.teams'),
143
+ activity: cySelector('superadmin.users.detail.info.activity'),
144
+ },
145
+ actions: cySelector('superadmin.users.detail.actions'),
146
+ metas: {
147
+ container: cySelector('superadmin.users.detail.metas.container'),
148
+ title: cySelector('superadmin.users.detail.metas.title'),
149
+ table: cySelector('superadmin.users.detail.metas.table'),
150
+ empty: cySelector('superadmin.users.detail.metas.empty'),
151
+ row: (key: string) => cySelector('superadmin.users.detail.metas.row', { key }),
152
+ key: (key: string) => cySelector('superadmin.users.detail.metas.key', { key }),
153
+ value: (key: string) => cySelector('superadmin.users.detail.metas.value', { key }),
154
+ type: (key: string) => cySelector('superadmin.users.detail.metas.type', { key }),
155
+ public: (key: string) => cySelector('superadmin.users.detail.metas.public', { key }),
156
+ searchable: (key: string) => cySelector('superadmin.users.detail.metas.searchable', { key }),
157
+ },
158
+ },
159
+ },
160
+
161
+ // ─────────────────────────────────────────
162
+ // TEAMS - Team management (list + detail)
163
+ // ─────────────────────────────────────────
164
+ teams: {
165
+ container: cySelector('superadmin.teams.container'),
166
+ header: {
167
+ backButton: cySelector('superadmin.teams.header.backButton'),
168
+ title: cySelector('superadmin.teams.header.title'),
169
+ refreshButton: cySelector('superadmin.teams.header.refreshButton'),
170
+ },
171
+ stats: {
172
+ totalTeams: cySelector('superadmin.teams.stats.totalTeams'),
173
+ },
174
+ filters: {
175
+ search: cySelector('superadmin.teams.filters.search'),
176
+ clearButton: cySelector('superadmin.teams.filters.clearButton'),
177
+ },
178
+ tabs: {
179
+ container: cySelector('superadmin.teams.tabs.container'),
180
+ userTeams: cySelector('superadmin.teams.tabs.userTeams'),
181
+ systemAdmin: cySelector('superadmin.teams.tabs.systemAdmin'),
182
+ },
183
+ table: {
184
+ element: cySelector('superadmin.teams.table.element'),
185
+ row: (id: string) => cySelector('superadmin.teams.table.row', { id }),
186
+ menuButton: (id: string) => cySelector('superadmin.teams.table.menuButton', { id }),
187
+ menuContent: (id: string) => cySelector('superadmin.teams.table.menuContent', { id }),
188
+ viewButton: (id: string) => cySelector('superadmin.teams.table.viewButton', { id }),
189
+ editButton: (id: string) => cySelector('superadmin.teams.table.editButton', { id }),
190
+ deleteButton: (id: string) => cySelector('superadmin.teams.table.deleteButton', { id }),
191
+ },
192
+ pagination: {
193
+ container: cySelector('superadmin.teams.pagination.container'),
194
+ pageSize: cySelector('superadmin.teams.pagination.pageSize'),
195
+ first: cySelector('superadmin.teams.pagination.first'),
196
+ prev: cySelector('superadmin.teams.pagination.prev'),
197
+ next: cySelector('superadmin.teams.pagination.next'),
198
+ last: cySelector('superadmin.teams.pagination.last'),
199
+ },
200
+ detail: {
201
+ container: cySelector('superadmin.teams.detail.container'),
202
+ info: {
203
+ name: cySelector('superadmin.teams.detail.info.name'),
204
+ owner: cySelector('superadmin.teams.detail.info.owner'),
205
+ members: cySelector('superadmin.teams.detail.info.members'),
206
+ },
207
+ membersTable: {
208
+ container: cySelector('superadmin.teams.detail.membersTable.container'),
209
+ row: (id: string) => cySelector('superadmin.teams.detail.membersTable.row', { id }),
210
+ },
211
+ subscription: {
212
+ container: cySelector('superadmin.teams.detail.subscription.container'),
213
+ plan: cySelector('superadmin.teams.detail.subscription.plan'),
214
+ status: cySelector('superadmin.teams.detail.subscription.status'),
215
+ period: cySelector('superadmin.teams.detail.subscription.period'),
216
+ providerLink: cySelector('superadmin.teams.detail.subscription.providerLink'),
217
+ },
218
+ billingHistory: {
219
+ container: cySelector('superadmin.teams.detail.billingHistory.container'),
220
+ row: (id: string) => cySelector('superadmin.teams.detail.billingHistory.row', { id }),
221
+ },
222
+ usage: {
223
+ container: cySelector('superadmin.teams.detail.usage.container'),
224
+ metric: (slug: string) => cySelector('superadmin.teams.detail.usage.metric', { slug }),
225
+ },
226
+ },
227
+ },
228
+
229
+ // ─────────────────────────────────────────
230
+ // SUBSCRIPTIONS - Subscriptions overview
231
+ // ─────────────────────────────────────────
232
+ subscriptions: {
233
+ container: cySelector('superadmin.subscriptions.container'),
234
+ header: {
235
+ backButton: cySelector('superadmin.subscriptions.header.backButton'),
236
+ title: cySelector('superadmin.subscriptions.header.title'),
237
+ refreshButton: cySelector('superadmin.subscriptions.header.refreshButton'),
238
+ },
239
+ stats: {
240
+ mrr: cySelector('superadmin.subscriptions.stats.mrr'),
241
+ arr: cySelector('superadmin.subscriptions.stats.arr'),
242
+ activeCount: cySelector('superadmin.subscriptions.stats.activeCount'),
243
+ totalCount: cySelector('superadmin.subscriptions.stats.totalCount'),
244
+ needsAttention: cySelector('superadmin.subscriptions.stats.needsAttention'),
245
+ planDistribution: cySelector('superadmin.subscriptions.stats.planDistribution'),
246
+ planCount: (plan: string) => cySelector('superadmin.subscriptions.stats.planCount', { plan }),
247
+ },
248
+ filters: {
249
+ search: cySelector('superadmin.subscriptions.filters.search'),
250
+ statusFilter: cySelector('superadmin.subscriptions.filters.statusFilter'),
251
+ planFilter: cySelector('superadmin.subscriptions.filters.planFilter'),
252
+ intervalFilter: cySelector('superadmin.subscriptions.filters.intervalFilter'),
253
+ clearButton: cySelector('superadmin.subscriptions.filters.clearButton'),
254
+ },
255
+ table: {
256
+ element: cySelector('superadmin.subscriptions.table.element'),
257
+ row: (id: string) => cySelector('superadmin.subscriptions.table.row', { id }),
258
+ viewTeamButton: (id: string) => cySelector('superadmin.subscriptions.table.viewTeamButton', { id }),
259
+ providerLink: (id: string) => cySelector('superadmin.subscriptions.table.providerLink', { id }),
260
+ },
261
+ pagination: {
262
+ container: cySelector('superadmin.subscriptions.pagination.container'),
263
+ pageSize: cySelector('superadmin.subscriptions.pagination.pageSize'),
264
+ first: cySelector('superadmin.subscriptions.pagination.first'),
265
+ prev: cySelector('superadmin.subscriptions.pagination.prev'),
266
+ next: cySelector('superadmin.subscriptions.pagination.next'),
267
+ last: cySelector('superadmin.subscriptions.pagination.last'),
268
+ },
269
+ },
270
+
271
+ // ─────────────────────────────────────────
272
+ // TEAM ROLES - RBAC Matrix and Plan Features
273
+ // ─────────────────────────────────────────
274
+ teamRoles: {
275
+ container: cySelector('superadmin.teamRoles.container'),
276
+ header: {
277
+ backButton: cySelector('superadmin.teamRoles.header.backButton'),
278
+ title: cySelector('superadmin.teamRoles.header.title'),
279
+ },
280
+ tabs: {
281
+ container: cySelector('superadmin.teamRoles.tabs.container'),
282
+ rbac: cySelector('superadmin.teamRoles.tabs.rbac'),
283
+ plans: cySelector('superadmin.teamRoles.tabs.plans'),
284
+ },
285
+ rbac: {
286
+ stats: {
287
+ roles: cySelector('superadmin.teamRoles.rbac.stats.roles'),
288
+ permissions: cySelector('superadmin.teamRoles.rbac.stats.permissions'),
289
+ protectedRole: cySelector('superadmin.teamRoles.rbac.stats.protectedRole'),
290
+ defaultRole: cySelector('superadmin.teamRoles.rbac.stats.defaultRole'),
291
+ },
292
+ hierarchy: {
293
+ container: cySelector('superadmin.teamRoles.rbac.hierarchy.container'),
294
+ roleCard: (role: string) => cySelector('superadmin.teamRoles.rbac.hierarchy.roleCard', { role }),
295
+ },
296
+ matrix: {
297
+ container: cySelector('superadmin.teamRoles.rbac.matrix.container'),
298
+ permissionRow: (permission: string) => cySelector('superadmin.teamRoles.rbac.matrix.permissionRow', { permission: permission.replace(/\./g, '-') }),
299
+ },
300
+ },
301
+ plans: {
302
+ stats: {
303
+ totalPlans: cySelector('superadmin.teamRoles.plans.stats.totalPlans'),
304
+ features: cySelector('superadmin.teamRoles.plans.stats.features'),
305
+ limits: cySelector('superadmin.teamRoles.plans.stats.limits'),
306
+ activeTheme: cySelector('superadmin.teamRoles.plans.stats.activeTheme'),
307
+ },
308
+ planCard: (slug: string) => cySelector('superadmin.teamRoles.plans.planCard', { slug }),
309
+ matrix: {
310
+ container: cySelector('superadmin.teamRoles.plans.matrix.container'),
311
+ featureRow: (slug: string) => cySelector('superadmin.teamRoles.plans.matrix.featureRow', { slug }),
312
+ limitRow: (slug: string) => cySelector('superadmin.teamRoles.plans.matrix.limitRow', { slug }),
313
+ },
314
+ },
315
+ },
316
+
317
+ // ─────────────────────────────────────────
318
+ // DOCS - Admin documentation pages
319
+ // ─────────────────────────────────────────
320
+ docs: {
321
+ container: cySelector('superadmin.docs.container'),
322
+ pageDetail: cySelector('superadmin.docs.pageDetail'),
323
+ sectionCard: (slug: string) => cySelector('superadmin.docs.sectionCard', { slug }),
324
+ pageLink: (slug: string) => cySelector('superadmin.docs.pageLink', { slug }),
325
+ },
326
+ }
327
+ }
328
+
329
+ // ============================================
330
+ // LEGACY SELECTOR ALIASES (for backward compatibility)
331
+ // These map old selector names to new structure
332
+ // TODO: Remove after updating all tests
333
+ // ============================================
334
+
335
+ get legacySelectors() {
336
+ return {
337
+ // Old navigation selectors → new sidebar.nav
338
+ navContainer: this.selectors.container,
339
+ navDashboard: this.selectors.sidebar.nav.dashboard,
340
+ navUsers: this.selectors.sidebar.nav.users,
341
+ navTeams: this.selectors.sidebar.nav.teams,
342
+ navTeamRoles: this.selectors.sidebar.nav.teamRoles,
343
+ navSubscriptions: this.selectors.sidebar.nav.subscriptions,
344
+ exitToDashboard: this.selectors.sidebar.exitButton,
345
+
346
+ // Old dashboard selectors
347
+ dashboardContainer: this.selectors.dashboard.container,
348
+
349
+ // Old users selectors
350
+ usersContainer: this.selectors.users.container,
351
+ usersTable: this.selectors.users.table.element,
352
+ usersSearch: this.selectors.users.filters.search,
353
+ userRow: this.selectors.users.table.row,
354
+ userView: this.selectors.users.table.viewButton,
355
+ userEdit: this.selectors.users.table.editButton,
356
+ userBan: this.selectors.users.table.banButton,
357
+ userDelete: this.selectors.users.table.deleteButton,
358
+ userImpersonate: this.selectors.users.table.impersonateButton,
359
+
360
+ // Old teams selectors
361
+ teamsContainer: this.selectors.teams.container,
362
+ teamsTable: this.selectors.teams.table.element,
363
+ teamsSearch: this.selectors.teams.filters.search,
364
+ teamRow: this.selectors.teams.table.row,
365
+ teamActionsButton: this.selectors.teams.table.menuButton,
366
+ teamView: this.selectors.teams.table.viewButton,
367
+ teamEdit: this.selectors.teams.table.editButton,
368
+ teamDelete: this.selectors.teams.table.deleteButton,
369
+
370
+ // Old subscriptions selectors
371
+ subscriptionsContainer: this.selectors.subscriptions.container,
372
+ subscriptionsMrr: this.selectors.subscriptions.stats.mrr,
373
+ subscriptionsPlanDistribution: this.selectors.subscriptions.stats.planDistribution,
374
+ subscriptionsPlanCount: this.selectors.subscriptions.stats.planCount,
375
+ subscriptionsActiveCount: this.selectors.subscriptions.stats.activeCount,
376
+
377
+ // Old permission selectors
378
+ permissionRow: this.selectors.teamRoles.rbac.matrix.permissionRow,
379
+ }
380
+ }
381
+
382
+ // ============================================
383
+ // NAVIGATION - Visit Pages
384
+ // ============================================
385
+
386
+ /** Navigate to Superadmin dashboard */
387
+ visitDashboard() {
388
+ cy.visit('/superadmin', { timeout: 60000 })
389
+ return this
390
+ }
391
+
392
+ /** Navigate to all users page */
393
+ visitUsers() {
394
+ cy.visit('/superadmin/users', { timeout: 60000 })
395
+ return this
396
+ }
397
+
398
+ /** Navigate to user detail page */
399
+ visitUserDetail(id: string) {
400
+ cy.visit(`/superadmin/users/${id}`, { timeout: 60000 })
401
+ return this
402
+ }
403
+
404
+ /** Navigate to all teams page */
405
+ visitTeams() {
406
+ cy.visit('/superadmin/teams', { timeout: 60000 })
407
+ return this
408
+ }
409
+
410
+ /** Navigate to team detail page */
411
+ visitTeamDetail(id: string) {
412
+ cy.visit(`/superadmin/teams/${id}`, { timeout: 60000 })
413
+ return this
414
+ }
415
+
416
+ /** Navigate to subscriptions overview */
417
+ visitSubscriptions() {
418
+ cy.visit('/superadmin/subscriptions', { timeout: 60000 })
419
+ return this
420
+ }
421
+
422
+ /** Navigate to team roles (RBAC & Plans) */
423
+ visitTeamRoles() {
424
+ cy.visit('/superadmin/team-roles', { timeout: 60000 })
425
+ return this
426
+ }
427
+
428
+ /** Navigate to docs index */
429
+ visitDocs() {
430
+ cy.visit('/superadmin/docs', { timeout: 60000 })
431
+ return this
432
+ }
433
+
434
+ /** Navigate to a specific doc page */
435
+ visitDocPage(section: string, page: string) {
436
+ cy.visit(`/superadmin/docs/${section}/${page}`, { timeout: 60000 })
437
+ return this
438
+ }
439
+
440
+ // ============================================
441
+ // NAVIGATION - Sidebar Clicks
442
+ // ============================================
443
+
444
+ /** Click nav link to dashboard */
445
+ clickNavDashboard() {
446
+ cy.get(this.selectors.sidebar.nav.dashboard).click()
447
+ return this
448
+ }
449
+
450
+ /** Click nav link to users */
451
+ clickNavUsers() {
452
+ cy.get(this.selectors.sidebar.nav.users).click()
453
+ return this
454
+ }
455
+
456
+ /** Click nav link to teams */
457
+ clickNavTeams() {
458
+ cy.get(this.selectors.sidebar.nav.teams).click()
459
+ return this
460
+ }
461
+
462
+ /** Click nav link to team roles */
463
+ clickNavTeamRoles() {
464
+ cy.get(this.selectors.sidebar.nav.teamRoles).click()
465
+ return this
466
+ }
467
+
468
+ /** Click nav link to subscriptions */
469
+ clickNavSubscriptions() {
470
+ cy.get(this.selectors.sidebar.nav.subscriptions).click()
471
+ return this
472
+ }
473
+
474
+ /** Click nav link to docs */
475
+ clickNavDocs() {
476
+ cy.get(this.selectors.sidebar.nav.docs).click()
477
+ return this
478
+ }
479
+
480
+ /** Click exit button to return to main dashboard */
481
+ clickExitButton() {
482
+ cy.get(this.selectors.sidebar.exitButton).click()
483
+ return this
484
+ }
485
+
486
+ /** Toggle sidebar collapse */
487
+ toggleSidebarCollapse() {
488
+ cy.get(this.selectors.sidebar.collapseButton).click()
489
+ return this
490
+ }
491
+
492
+ // ============================================
493
+ // USERS ACTIONS
494
+ // ============================================
495
+
496
+ /** Search users */
497
+ searchUsers(query: string) {
498
+ cy.get(this.selectors.users.filters.search).clear().type(query)
499
+ return this
500
+ }
501
+
502
+ /** Clear users search */
503
+ clearUsersSearch() {
504
+ cy.get(this.selectors.users.filters.search).clear()
505
+ return this
506
+ }
507
+
508
+ /** Clear all users filters */
509
+ clearUsersFilters() {
510
+ cy.get(this.selectors.users.filters.clearButton).click()
511
+ return this
512
+ }
513
+
514
+ /** Switch to regular users tab */
515
+ switchToRegularUsersTab() {
516
+ cy.get(this.selectors.users.tabs.regularUsers).click()
517
+ return this
518
+ }
519
+
520
+ /** Switch to superadmins tab */
521
+ switchToSuperadminsTab() {
522
+ cy.get(this.selectors.users.tabs.superadmins).click()
523
+ return this
524
+ }
525
+
526
+ /** Click on a user row to view details */
527
+ clickUserRow(id: string) {
528
+ cy.get(this.selectors.users.table.row(id)).click()
529
+ return this
530
+ }
531
+
532
+ /** View user details via button */
533
+ viewUser(id: string) {
534
+ cy.get(this.selectors.users.table.viewButton(id)).click()
535
+ return this
536
+ }
537
+
538
+ /** Ban a user */
539
+ banUser(id: string) {
540
+ cy.get(this.selectors.users.table.banButton(id)).click()
541
+ return this
542
+ }
543
+
544
+ /** Impersonate a user */
545
+ impersonateUser(id: string) {
546
+ cy.get(this.selectors.users.table.impersonateButton(id)).click()
547
+ return this
548
+ }
549
+
550
+ // ============================================
551
+ // TEAMS ACTIONS
552
+ // ============================================
553
+
554
+ /** Search teams */
555
+ searchTeams(query: string) {
556
+ cy.get(this.selectors.teams.filters.search).clear().type(query)
557
+ return this
558
+ }
559
+
560
+ /** Clear teams search */
561
+ clearTeamsSearch() {
562
+ cy.get(this.selectors.teams.filters.search).clear()
563
+ return this
564
+ }
565
+
566
+ /** Clear all teams filters */
567
+ clearTeamsFilters() {
568
+ cy.get(this.selectors.teams.filters.clearButton).click()
569
+ return this
570
+ }
571
+
572
+ /** Switch to user teams tab */
573
+ switchToUserTeamsTab() {
574
+ cy.get(this.selectors.teams.tabs.userTeams).click()
575
+ return this
576
+ }
577
+
578
+ /** Switch to system admin team tab */
579
+ switchToSystemAdminTab() {
580
+ cy.get(this.selectors.teams.tabs.systemAdmin).click()
581
+ return this
582
+ }
583
+
584
+ /** Click on a team row to view details */
585
+ clickTeamRow(id: string) {
586
+ cy.get(this.selectors.teams.table.row(id)).click()
587
+ return this
588
+ }
589
+
590
+ /** Open team actions menu */
591
+ openTeamMenu(id: string) {
592
+ cy.get(this.selectors.teams.table.menuButton(id)).click()
593
+ return this
594
+ }
595
+
596
+ /** View team details via button */
597
+ viewTeam(id: string) {
598
+ cy.get(this.selectors.teams.table.viewButton(id)).click()
599
+ return this
600
+ }
601
+
602
+ // ============================================
603
+ // TEAM ROLES ACTIONS
604
+ // ============================================
605
+
606
+ /** Switch to RBAC tab */
607
+ switchToRbacTab() {
608
+ cy.get(this.selectors.teamRoles.tabs.rbac).click()
609
+ return this
610
+ }
611
+
612
+ /** Switch to Plans tab */
613
+ switchToPlansTab() {
614
+ cy.get(this.selectors.teamRoles.tabs.plans).click()
615
+ return this
616
+ }
617
+
618
+ // ============================================
619
+ // PAGINATION (Contextual)
620
+ // ============================================
621
+
622
+ /** Get pagination selectors for a specific context */
623
+ getPaginationSelectors(context: PaginationContext) {
624
+ return this.selectors[context].pagination
625
+ }
626
+
627
+ /** Go to first page */
628
+ paginateFirst(context: PaginationContext) {
629
+ cy.get(this.selectors[context].pagination.first).click()
630
+ return this
631
+ }
632
+
633
+ /** Go to previous page */
634
+ paginatePrev(context: PaginationContext) {
635
+ cy.get(this.selectors[context].pagination.prev).click()
636
+ return this
637
+ }
638
+
639
+ /** Go to next page */
640
+ paginateNext(context: PaginationContext) {
641
+ cy.get(this.selectors[context].pagination.next).click()
642
+ return this
643
+ }
644
+
645
+ /** Go to last page */
646
+ paginateLast(context: PaginationContext) {
647
+ cy.get(this.selectors[context].pagination.last).click()
648
+ return this
649
+ }
650
+
651
+ /** Change page size */
652
+ changePageSize(context: PaginationContext, size: number) {
653
+ cy.get(this.selectors[context].pagination.pageSize).click()
654
+ cy.get(`[data-value="${size}"]`).click()
655
+ return this
656
+ }
657
+
658
+ // ============================================
659
+ // ASSERTIONS
660
+ // ============================================
661
+
662
+ /** Assert on Superadmin area */
663
+ assertOnSuperadmin() {
664
+ cy.url().should('include', '/superadmin')
665
+ return this
666
+ }
667
+
668
+ /** Assert dashboard is visible */
669
+ assertDashboardVisible() {
670
+ cy.get(this.selectors.dashboard.container).should('be.visible')
671
+ return this
672
+ }
673
+
674
+ /** Assert sidebar is visible */
675
+ assertSidebarVisible() {
676
+ cy.get(this.selectors.sidebar.nav.dashboard).should('be.visible')
677
+ return this
678
+ }
679
+
680
+ /** Assert users page is visible */
681
+ assertUsersVisible() {
682
+ cy.get(this.selectors.users.container).should('be.visible')
683
+ return this
684
+ }
685
+
686
+ /** Assert users table is visible */
687
+ assertUsersTableVisible() {
688
+ cy.get(this.selectors.users.table.element).should('be.visible')
689
+ return this
690
+ }
691
+
692
+ /** Assert user detail is visible */
693
+ assertUserDetailVisible() {
694
+ cy.get(this.selectors.users.detail.container).should('be.visible')
695
+ return this
696
+ }
697
+
698
+ /** Assert user metadata section is visible */
699
+ assertUserMetasVisible() {
700
+ cy.get(this.selectors.users.detail.metas.container).should('be.visible')
701
+ return this
702
+ }
703
+
704
+ /** Assert teams page is visible */
705
+ assertTeamsVisible() {
706
+ cy.get(this.selectors.teams.container).should('be.visible')
707
+ return this
708
+ }
709
+
710
+ /** Assert teams table is visible */
711
+ assertTeamsTableVisible() {
712
+ cy.get(this.selectors.teams.table.element).should('be.visible')
713
+ return this
714
+ }
715
+
716
+ /** Assert team detail is visible */
717
+ assertTeamDetailVisible() {
718
+ cy.get(this.selectors.teams.detail.container).should('be.visible')
719
+ return this
720
+ }
721
+
722
+ /** Assert nav items are visible */
723
+ assertNavVisible() {
724
+ cy.get(this.selectors.container).should('be.visible')
725
+ return this
726
+ }
727
+
728
+ /** Assert subscriptions page is visible */
729
+ assertSubscriptionsVisible() {
730
+ cy.get(this.selectors.subscriptions.container).should('be.visible')
731
+ return this
732
+ }
733
+
734
+ /** Assert team roles page is visible */
735
+ assertTeamRolesVisible() {
736
+ cy.get(this.selectors.teamRoles.container).should('be.visible')
737
+ return this
738
+ }
739
+
740
+ /** Assert RBAC matrix is visible */
741
+ assertRbacMatrixVisible() {
742
+ cy.get(this.selectors.teamRoles.rbac.matrix.container).should('be.visible')
743
+ return this
744
+ }
745
+
746
+ /** Assert Plans matrix is visible */
747
+ assertPlansMatrixVisible() {
748
+ cy.get(this.selectors.teamRoles.plans.matrix.container).should('be.visible')
749
+ return this
750
+ }
751
+
752
+ /** Assert docs index is visible */
753
+ assertDocsVisible() {
754
+ cy.get(this.selectors.docs.container).should('be.visible')
755
+ return this
756
+ }
757
+
758
+ /** Assert docs page detail is visible */
759
+ assertDocPageVisible() {
760
+ cy.get(this.selectors.docs.pageDetail).should('be.visible')
761
+ return this
762
+ }
763
+
764
+ /** Assert access denied (redirect from superadmin) */
765
+ assertAccessDenied() {
766
+ cy.url().should('not.include', '/superadmin')
767
+ cy.url().should('satisfy', (url: string) => {
768
+ return url.includes('/dashboard') || url.includes('error=access_denied')
769
+ })
770
+ return this
771
+ }
772
+
773
+ // ============================================
774
+ // WAITS
775
+ // ============================================
776
+
777
+ /** Wait for Superadmin dashboard to load */
778
+ waitForDashboard() {
779
+ cy.url().should('include', '/superadmin')
780
+ cy.get(this.selectors.dashboard.container, { timeout: 15000 }).should('be.visible')
781
+ return this
782
+ }
783
+
784
+ /** Wait for users page to load */
785
+ waitForUsers() {
786
+ cy.url().should('include', '/superadmin/users')
787
+ cy.get(this.selectors.users.container, { timeout: 15000 }).should('be.visible')
788
+ return this
789
+ }
790
+
791
+ /** Wait for user detail to load */
792
+ waitForUserDetail() {
793
+ cy.url().should('match', /\/superadmin\/users\/[^/]+$/)
794
+ cy.get(this.selectors.users.detail.container, { timeout: 15000 }).should('be.visible')
795
+ return this
796
+ }
797
+
798
+ /** Wait for teams page to load */
799
+ waitForTeams() {
800
+ cy.url().should('include', '/superadmin/teams')
801
+ cy.get(this.selectors.teams.container, { timeout: 15000 }).should('be.visible')
802
+ return this
803
+ }
804
+
805
+ /** Wait for team detail to load */
806
+ waitForTeamDetail() {
807
+ cy.url().should('match', /\/superadmin\/teams\/[^/]+$/)
808
+ cy.get(this.selectors.teams.detail.container, { timeout: 15000 }).should('be.visible')
809
+ return this
810
+ }
811
+
812
+ /** Wait for subscriptions page to load */
813
+ waitForSubscriptions() {
814
+ cy.url().should('include', '/superadmin/subscriptions')
815
+ cy.get(this.selectors.subscriptions.container, { timeout: 15000 }).should('be.visible')
816
+ return this
817
+ }
818
+
819
+ /** Wait for team roles page to load */
820
+ waitForTeamRoles() {
821
+ cy.url().should('include', '/superadmin/team-roles')
822
+ cy.get(this.selectors.teamRoles.container, { timeout: 15000 }).should('be.visible')
823
+ return this
824
+ }
825
+
826
+ /** Wait for docs index to load */
827
+ waitForDocs() {
828
+ cy.url().should('include', '/superadmin/docs')
829
+ cy.get(this.selectors.docs.container, { timeout: 15000 }).should('be.visible')
830
+ return this
831
+ }
832
+
833
+ /** Wait for doc page detail to load */
834
+ waitForDocPage() {
835
+ cy.url().should('match', /\/superadmin\/docs\/[^/]+\/[^/]+$/)
836
+ cy.get(this.selectors.docs.pageDetail, { timeout: 15000 }).should('be.visible')
837
+ return this
838
+ }
839
+
840
+ // ============================================
841
+ // DOCS ACTIONS
842
+ // ============================================
843
+
844
+ /** Click on a doc page link */
845
+ clickDocPageLink(slug: string) {
846
+ cy.get(this.selectors.docs.pageLink(slug)).click()
847
+ return this
848
+ }
849
+ }
850
+
851
+ export default SuperadminPOM