@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,41 @@
1
+ /**
2
+ * DashboardEntityPOM - Theme-specific base class for entity Page Object Models
3
+ *
4
+ * Extends DashboardEntityPOMCore from @nextsparkjs/testing and implements
5
+ * the abstract cySelector method with theme-specific selectors.
6
+ *
7
+ * Adds theme-specific functionality:
8
+ * - Entity config validation from fixtures
9
+ * - Convenience aliases (goToList, goToCreate, etc.)
10
+ * - Additional assertions
11
+ *
12
+ * @example
13
+ * class TasksPOM extends DashboardEntityPOM {
14
+ * constructor() {
15
+ * super('tasks')
16
+ * }
17
+ *
18
+ * fillTaskForm(data: TaskFormData) {
19
+ * // Entity-specific form handling
20
+ * }
21
+ * }
22
+ */
23
+
24
+ import { DashboardEntityPOMCore, type EntityConfig } from '@nextsparkjs/testing/pom'
25
+ import { type Replacements } from '@nextsparkjs/core/selectors'
26
+ import { cySelector } from '../selectors'
27
+
28
+ export abstract class DashboardEntityPOM extends DashboardEntityPOMCore {
29
+ /**
30
+ * Implement abstract method from BasePOMCore
31
+ * Uses theme-specific selectors (THEME_SELECTORS)
32
+ */
33
+ protected cySelector(path: string, replacements?: Replacements): string {
34
+ return cySelector(path, replacements)
35
+ }
36
+ }
37
+
38
+ export default DashboardEntityPOM
39
+
40
+ // Re-export EntityConfig for convenience
41
+ export type { EntityConfig }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Core POM exports
3
+ *
4
+ * Base classes for building Page Object Models:
5
+ * - BasePOM: Utility methods for all POMs
6
+ * - DashboardEntityPOM: Base for entity CRUD POMs
7
+ * - BlockEditorBasePOM: Base for page/post builder POMs
8
+ * - AuthPOM: Authentication pages POM
9
+ */
10
+
11
+ export { BasePOM } from './BasePOM'
12
+ export { DashboardEntityPOM, type EntityConfig } from './DashboardEntityPOM'
13
+ export { BlockEditorBasePOM } from './BlockEditorBasePOM'
14
+ export { AuthPOM, type SignupData } from './AuthPOM'
@@ -0,0 +1,172 @@
1
+ /**
2
+ * CustomersPOM - Page Object Model for Customers entity
3
+ *
4
+ * Extends DashboardEntityPOM with customer-specific form handling and workflows.
5
+ *
6
+ * @example
7
+ * // Instance usage with chaining
8
+ * CustomersPOM.create()
9
+ * .visitList()
10
+ * .waitForList()
11
+ * .clickAdd()
12
+ * .fillCustomerForm({ name: 'Acme Inc', account: 'ACC001', office: 'HQ' })
13
+ * .submitForm()
14
+ *
15
+ * // API-aware workflow
16
+ * const customers = new CustomersPOM()
17
+ * customers.createCustomerWithApiWait({
18
+ * name: 'Acme Inc',
19
+ * account: 'ACC001',
20
+ * office: 'Main Office'
21
+ * })
22
+ */
23
+
24
+ import { DashboardEntityPOM } from '../core/DashboardEntityPOM'
25
+ import entitiesConfig from '../../fixtures/entities.json'
26
+
27
+ export interface CustomerFormData {
28
+ name: string
29
+ account: string
30
+ office: string
31
+ phone?: string
32
+ salesRep?: string
33
+ visitDays?: string[]
34
+ contactDays?: string[]
35
+ }
36
+
37
+ export class CustomersPOM extends DashboardEntityPOM {
38
+ constructor() {
39
+ super(entitiesConfig.entities.customers.slug)
40
+ }
41
+
42
+ // ============================================
43
+ // FACTORY METHOD
44
+ // ============================================
45
+
46
+ static create(): CustomersPOM {
47
+ return new CustomersPOM()
48
+ }
49
+
50
+ // ============================================
51
+ // ENTITY-SPECIFIC FORM METHODS
52
+ // ============================================
53
+
54
+ /**
55
+ * Fill customer form with provided data
56
+ * Only fills fields that are provided in the data object
57
+ */
58
+ fillCustomerForm(data: CustomerFormData) {
59
+ if (data.name) {
60
+ this.fillTextField('name', data.name)
61
+ }
62
+ if (data.account) {
63
+ this.fillTextField('account', data.account)
64
+ }
65
+ if (data.office) {
66
+ this.fillTextField('office', data.office)
67
+ }
68
+ if (data.phone) {
69
+ this.fillTextField('phone', data.phone)
70
+ }
71
+ if (data.salesRep) {
72
+ this.fillTextField('salesRep', data.salesRep)
73
+ }
74
+ return this
75
+ }
76
+
77
+ // ============================================
78
+ // WORKFLOW METHODS
79
+ // ============================================
80
+
81
+ /**
82
+ * Complete create flow without API waits
83
+ */
84
+ createCustomer(data: CustomerFormData) {
85
+ this.visitCreate()
86
+ this.waitForForm()
87
+ this.fillCustomerForm(data)
88
+ this.submitForm()
89
+ return this
90
+ }
91
+
92
+ /**
93
+ * Create customer with API intercepts and waits
94
+ * Deterministic: waits for actual API responses
95
+ */
96
+ createCustomerWithApiWait(data: CustomerFormData) {
97
+ this.setupApiIntercepts()
98
+ this.clickAdd()
99
+ this.waitForForm()
100
+ this.fillCustomerForm(data)
101
+ this.submitForm()
102
+ this.api.waitForCreate()
103
+ return this
104
+ }
105
+
106
+ /**
107
+ * Create customer from list page and wait for refresh
108
+ */
109
+ createCustomerFromListWithApiWait(data: CustomerFormData) {
110
+ this.setupApiIntercepts()
111
+ this.clickAdd()
112
+ this.waitForForm()
113
+ this.fillCustomerForm(data)
114
+ this.submitForm()
115
+ this.api.waitForCreateAndRefresh()
116
+ return this
117
+ }
118
+
119
+ /**
120
+ * Update customer with API waits
121
+ */
122
+ updateCustomerWithApiWait(data: Partial<CustomerFormData>) {
123
+ this.fillCustomerForm(data as CustomerFormData)
124
+ this.submitForm()
125
+ this.api.waitForUpdate()
126
+ return this
127
+ }
128
+
129
+ /**
130
+ * Delete customer with API waits
131
+ * Flow: Navigate to detail -> Delete -> Confirm
132
+ */
133
+ deleteCustomerWithApiWait(id: string) {
134
+ this.visitDetailWithApiWait(id)
135
+ this.clickDelete()
136
+ this.confirmDelete()
137
+ this.api.waitForDelete()
138
+ return this
139
+ }
140
+
141
+ /**
142
+ * Delete customer by finding it in the list by name
143
+ */
144
+ deleteCustomerByNameWithApiWait(name: string) {
145
+ this.clickRowByText(name)
146
+ this.waitForDetail()
147
+ this.clickDelete()
148
+ this.confirmDelete()
149
+ this.api.waitForDelete()
150
+ return this
151
+ }
152
+
153
+ // ============================================
154
+ // ENTITY-SPECIFIC ASSERTIONS
155
+ // ============================================
156
+
157
+ /**
158
+ * Assert customer appears in list
159
+ */
160
+ assertCustomerInList(name: string) {
161
+ return this.assertInList(name)
162
+ }
163
+
164
+ /**
165
+ * Assert customer does not appear in list
166
+ */
167
+ assertCustomerNotInList(name: string) {
168
+ return this.assertNotInList(name)
169
+ }
170
+ }
171
+
172
+ export default CustomersPOM
@@ -0,0 +1,137 @@
1
+ /**
2
+ * PagesPOM - Page Object Model for Pages entity (List operations)
3
+ *
4
+ * Extends DashboardEntityPOM for list page operations.
5
+ * For editing pages with the block editor, use PageBuilderPOM from features/.
6
+ *
7
+ * @example
8
+ * // List operations
9
+ * PagesPOM.create()
10
+ * .visitList()
11
+ * .waitForList()
12
+ * .search('About Us')
13
+ * .selectFilter('status', 'published')
14
+ *
15
+ * // For editing pages, use PageBuilderPOM
16
+ * import { PageBuilderPOM } from '../features/PageBuilderPOM'
17
+ * PageBuilderPOM.create().visitEdit(pageId).setTitle('New Title').save()
18
+ */
19
+
20
+ import { DashboardEntityPOM } from '../core/DashboardEntityPOM'
21
+ import entitiesConfig from '../../fixtures/entities.json'
22
+
23
+ export interface PageListFilters {
24
+ status?: 'draft' | 'published' | 'archived'
25
+ locale?: 'en' | 'es'
26
+ }
27
+
28
+ export class PagesPOM extends DashboardEntityPOM {
29
+ constructor() {
30
+ super(entitiesConfig.entities.pages.slug)
31
+ }
32
+
33
+ // ============================================
34
+ // FACTORY METHOD
35
+ // ============================================
36
+
37
+ static create(): PagesPOM {
38
+ return new PagesPOM()
39
+ }
40
+
41
+ // ============================================
42
+ // PAGE-SPECIFIC LIST METHODS
43
+ // ============================================
44
+
45
+ /**
46
+ * Filter pages by status
47
+ */
48
+ filterByStatus(status: 'draft' | 'published' | 'archived') {
49
+ return this.selectFilter('status', status)
50
+ }
51
+
52
+ /**
53
+ * Apply multiple filters at once
54
+ */
55
+ applyFilters(filters: PageListFilters) {
56
+ if (filters.status) {
57
+ this.filterByStatus(filters.status)
58
+ }
59
+ if (filters.locale) {
60
+ this.selectFilter('locale', filters.locale)
61
+ }
62
+ return this
63
+ }
64
+
65
+ // ============================================
66
+ // WORKFLOW METHODS
67
+ // ============================================
68
+
69
+ /**
70
+ * Navigate to create page
71
+ * Note: Pages use block editor, so this redirects to the editor
72
+ */
73
+ navigateToCreate() {
74
+ this.clickAdd()
75
+ return this
76
+ }
77
+
78
+ /**
79
+ * Navigate to edit page for a page
80
+ * Note: Pages use block editor, so this redirects to the editor
81
+ */
82
+ navigateToEdit(id: string) {
83
+ this.clickRowAction('edit', id)
84
+ return this
85
+ }
86
+
87
+ /**
88
+ * Delete page from list with API waits
89
+ */
90
+ deletePageWithApiWait(id: string) {
91
+ this.visitDetailWithApiWait(id)
92
+ this.clickDelete()
93
+ this.confirmDelete()
94
+ this.api.waitForDelete()
95
+ return this
96
+ }
97
+
98
+ /**
99
+ * Delete page by finding it in the list by title
100
+ */
101
+ deletePageByTitleWithApiWait(title: string) {
102
+ this.clickRowByText(title)
103
+ this.waitForDetail()
104
+ this.clickDelete()
105
+ this.confirmDelete()
106
+ this.api.waitForDelete()
107
+ return this
108
+ }
109
+
110
+ // ============================================
111
+ // ENTITY-SPECIFIC ASSERTIONS
112
+ // ============================================
113
+
114
+ /**
115
+ * Assert page appears in list
116
+ */
117
+ assertPageInList(title: string) {
118
+ return this.assertInList(title)
119
+ }
120
+
121
+ /**
122
+ * Assert page does not appear in list
123
+ */
124
+ assertPageNotInList(title: string) {
125
+ return this.assertNotInList(title)
126
+ }
127
+
128
+ /**
129
+ * Assert page has specific status badge
130
+ */
131
+ assertPageStatus(id: string, status: string) {
132
+ cy.get(this.selectors.row(id)).should('contain.text', status)
133
+ return this
134
+ }
135
+ }
136
+
137
+ export default PagesPOM
@@ -0,0 +1,329 @@
1
+ /**
2
+ * PatternsPOM - Page Object Model for Patterns entity
3
+ *
4
+ * Extends DashboardEntityPOM for standard CRUD operations on patterns.
5
+ * Includes pattern-specific methods for:
6
+ * - Usage report interactions
7
+ * - Delete dialog with usage checking
8
+ * - Placeholder handling in block editor
9
+ *
10
+ * @example
11
+ * // List operations
12
+ * PatternsPOM.create()
13
+ * .visitList()
14
+ * .waitForList()
15
+ * .search('Hero Section')
16
+ *
17
+ * // View pattern usage
18
+ * PatternsPOM.create()
19
+ * .visitDetailWithApiWait(patternId)
20
+ * .assertUsageStatsLoaded()
21
+ *
22
+ * // Delete with usage warning (from list)
23
+ * PatternsPOM.create()
24
+ * .visitList()
25
+ * .openDeleteDialogFromList(patternId)
26
+ * .assertUsageWarningVisible()
27
+ * .confirmPatternDelete()
28
+ */
29
+
30
+ import { DashboardEntityPOM } from '../core/DashboardEntityPOM'
31
+ import { cySelector } from '../selectors'
32
+ import entitiesConfig from '../../fixtures/entities.json'
33
+
34
+ export class PatternsPOM extends DashboardEntityPOM {
35
+ constructor() {
36
+ super(entitiesConfig.entities.patterns.slug)
37
+ }
38
+
39
+ // ============================================
40
+ // FACTORY METHOD
41
+ // ============================================
42
+
43
+ static create(): PatternsPOM {
44
+ return new PatternsPOM()
45
+ }
46
+
47
+ // ============================================
48
+ // PATTERN-SPECIFIC SELECTORS
49
+ // ============================================
50
+
51
+ get patternSelectors() {
52
+ return {
53
+ // Usage Table
54
+ usageTable: {
55
+ container: cySelector('patterns.usageTable.container'),
56
+ loading: cySelector('patterns.usageTable.loading'),
57
+ empty: cySelector('patterns.usageTable.empty'),
58
+ row: (id: string) => cySelector('patterns.usageTable.row', { id }),
59
+ viewLink: (id: string) => cySelector('patterns.usageTable.viewLink', { id }),
60
+ },
61
+ // Usage Stats
62
+ usageStats: {
63
+ container: cySelector('patterns.usageStats.container'),
64
+ loading: cySelector('patterns.usageStats.loading'),
65
+ total: cySelector('patterns.usageStats.total'),
66
+ byType: (entityType: string) => cySelector('patterns.usageStats.byType', { entityType }),
67
+ },
68
+ // Usage Report
69
+ usageReport: {
70
+ container: cySelector('patterns.usageReport.container'),
71
+ error: cySelector('patterns.usageReport.error'),
72
+ filters: cySelector('patterns.usageReport.filters'),
73
+ filterSelect: cySelector('patterns.usageReport.filterSelect'),
74
+ pagination: cySelector('patterns.usageReport.pagination'),
75
+ prevPage: cySelector('patterns.usageReport.prevPage'),
76
+ nextPage: cySelector('patterns.usageReport.nextPage'),
77
+ resultsInfo: cySelector('patterns.usageReport.resultsInfo'),
78
+ },
79
+ // Delete Dialog
80
+ deleteDialog: {
81
+ trigger: cySelector('patterns.deleteDialog.trigger'),
82
+ container: cySelector('patterns.deleteDialog.container'),
83
+ loading: cySelector('patterns.deleteDialog.loading'),
84
+ error: cySelector('patterns.deleteDialog.error'),
85
+ warning: cySelector('patterns.deleteDialog.warning'),
86
+ usageList: cySelector('patterns.deleteDialog.usageList'),
87
+ noUsage: cySelector('patterns.deleteDialog.noUsage'),
88
+ cancel: cySelector('patterns.deleteDialog.cancel'),
89
+ confirm: cySelector('patterns.deleteDialog.confirm'),
90
+ },
91
+ // Deleted Pattern Placeholder
92
+ placeholder: {
93
+ container: cySelector('patterns.placeholder.container'),
94
+ removeBtn: cySelector('patterns.placeholder.removeBtn'),
95
+ },
96
+ }
97
+ }
98
+
99
+ // ============================================
100
+ // USAGE REPORT METHODS
101
+ // ============================================
102
+
103
+ /**
104
+ * Assert usage stats container is visible and loaded
105
+ */
106
+ assertUsageStatsLoaded(): this {
107
+ cy.get(this.patternSelectors.usageStats.container).should('be.visible')
108
+ cy.get(this.patternSelectors.usageStats.loading).should('not.exist')
109
+ return this
110
+ }
111
+
112
+ /**
113
+ * Assert usage table is visible and loaded
114
+ */
115
+ assertUsageTableLoaded(): this {
116
+ cy.get(this.patternSelectors.usageTable.container).should('be.visible')
117
+ cy.get(this.patternSelectors.usageTable.loading).should('not.exist')
118
+ return this
119
+ }
120
+
121
+ /**
122
+ * Assert usage report shows empty state
123
+ */
124
+ assertUsageTableEmpty(): this {
125
+ cy.get(this.patternSelectors.usageTable.empty).should('be.visible')
126
+ return this
127
+ }
128
+
129
+ /**
130
+ * Assert total usage count
131
+ */
132
+ assertTotalUsageCount(expectedCount: number): this {
133
+ cy.get(this.patternSelectors.usageStats.total)
134
+ .should('contain.text', expectedCount.toString())
135
+ return this
136
+ }
137
+
138
+ /**
139
+ * Filter usage by entity type
140
+ */
141
+ filterUsageByType(entityType: string): this {
142
+ cy.get(this.patternSelectors.usageReport.filterSelect).click()
143
+ cy.get(`[data-value="${entityType}"]`).click()
144
+ return this
145
+ }
146
+
147
+ /**
148
+ * Navigate to next page of usage results
149
+ */
150
+ goToNextUsagePage(): this {
151
+ cy.get(this.patternSelectors.usageReport.nextPage).click()
152
+ return this
153
+ }
154
+
155
+ /**
156
+ * Navigate to previous page of usage results
157
+ */
158
+ goToPrevUsagePage(): this {
159
+ cy.get(this.patternSelectors.usageReport.prevPage).click()
160
+ return this
161
+ }
162
+
163
+ /**
164
+ * Click view link for a specific usage row
165
+ */
166
+ clickUsageViewLink(usageId: string): this {
167
+ cy.get(this.patternSelectors.usageTable.viewLink(usageId)).click()
168
+ return this
169
+ }
170
+
171
+ // ============================================
172
+ // DELETE DIALOG METHODS
173
+ // ============================================
174
+
175
+ /**
176
+ * Open the delete dialog for a pattern from the list dropdown menu
177
+ * @param id - The pattern ID to delete
178
+ */
179
+ openDeleteDialogFromList(id: string): this {
180
+ // Click on the dropdown menu first
181
+ cy.get(this.selectors.rowMenu(id)).click()
182
+ // Then click the delete action
183
+ cy.get(this.selectors.rowAction('delete', id)).click()
184
+ // Wait for dialog to be visible
185
+ cy.get(this.patternSelectors.deleteDialog.container).should('be.visible')
186
+ return this
187
+ }
188
+
189
+ /**
190
+ * Open the delete dialog using the standalone trigger (if present)
191
+ * @deprecated Use openDeleteDialogFromList() for list-based deletion
192
+ */
193
+ openDeleteDialog(): this {
194
+ cy.get(this.patternSelectors.deleteDialog.trigger).click()
195
+ cy.get(this.patternSelectors.deleteDialog.container).should('be.visible')
196
+ return this
197
+ }
198
+
199
+ /**
200
+ * Wait for usage check to complete in delete dialog
201
+ */
202
+ waitForUsageCheck(): this {
203
+ cy.get(this.patternSelectors.deleteDialog.loading).should('not.exist')
204
+ return this
205
+ }
206
+
207
+ /**
208
+ * Assert the delete dialog shows usage warning
209
+ */
210
+ assertUsageWarningVisible(): this {
211
+ cy.get(this.patternSelectors.deleteDialog.warning).should('be.visible')
212
+ return this
213
+ }
214
+
215
+ /**
216
+ * Assert the delete dialog shows no usage message
217
+ */
218
+ assertNoUsageVisible(): this {
219
+ cy.get(this.patternSelectors.deleteDialog.noUsage).should('be.visible')
220
+ return this
221
+ }
222
+
223
+ /**
224
+ * Assert the delete dialog shows error
225
+ */
226
+ assertDeleteDialogError(): this {
227
+ cy.get(this.patternSelectors.deleteDialog.error).should('be.visible')
228
+ return this
229
+ }
230
+
231
+ /**
232
+ * Confirm deletion in the delete dialog
233
+ */
234
+ confirmPatternDelete(): this {
235
+ cy.get(this.patternSelectors.deleteDialog.confirm).click()
236
+ return this
237
+ }
238
+
239
+ /**
240
+ * Cancel deletion in the delete dialog
241
+ */
242
+ cancelPatternDelete(): this {
243
+ cy.get(this.patternSelectors.deleteDialog.cancel).click()
244
+ return this
245
+ }
246
+
247
+ /**
248
+ * Delete pattern from list with API wait
249
+ * Handles the full flow: open dialog from dropdown, wait for usage check, confirm
250
+ * @param id - The pattern ID to delete
251
+ */
252
+ deletePatternFromListWithApiWait(id: string): this {
253
+ this.openDeleteDialogFromList(id)
254
+ this.waitForUsageCheck()
255
+ this.api.interceptDelete()
256
+ this.confirmPatternDelete()
257
+ this.api.waitForDelete()
258
+ return this
259
+ }
260
+
261
+ /**
262
+ * Delete pattern with API wait (using standalone trigger)
263
+ * @deprecated Use deletePatternFromListWithApiWait() for list-based deletion
264
+ */
265
+ deletePatternWithApiWait(): this {
266
+ this.openDeleteDialog()
267
+ this.waitForUsageCheck()
268
+ this.api.interceptDelete()
269
+ this.confirmPatternDelete()
270
+ this.api.waitForDelete()
271
+ return this
272
+ }
273
+
274
+ // ============================================
275
+ // PLACEHOLDER METHODS (Block Editor context)
276
+ // ============================================
277
+
278
+ /**
279
+ * Assert deleted pattern placeholder is visible
280
+ */
281
+ assertPlaceholderVisible(): this {
282
+ cy.get(this.patternSelectors.placeholder.container).should('be.visible')
283
+ return this
284
+ }
285
+
286
+ /**
287
+ * Click remove button on deleted pattern placeholder
288
+ */
289
+ clickPlaceholderRemove(): this {
290
+ cy.get(this.patternSelectors.placeholder.removeBtn).click()
291
+ return this
292
+ }
293
+
294
+ // ============================================
295
+ // WORKFLOW METHODS
296
+ // ============================================
297
+
298
+ /**
299
+ * Create a new pattern (navigates to create page)
300
+ */
301
+ navigateToCreate(): this {
302
+ this.clickAdd()
303
+ return this
304
+ }
305
+
306
+ /**
307
+ * Navigate to edit a pattern
308
+ */
309
+ navigateToEdit(id: string): this {
310
+ this.clickRowAction('edit', id)
311
+ return this
312
+ }
313
+
314
+ /**
315
+ * Assert pattern appears in list
316
+ */
317
+ assertPatternInList(title: string): this {
318
+ return this.assertInList(title)
319
+ }
320
+
321
+ /**
322
+ * Assert pattern does not appear in list
323
+ */
324
+ assertPatternNotInList(title: string): this {
325
+ return this.assertNotInList(title)
326
+ }
327
+ }
328
+
329
+ export default PatternsPOM