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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/package.json +1 -1
  2. package/tests/cypress/e2e/_devtools/access.bdd.md +262 -0
  3. package/tests/cypress/e2e/_devtools/access.cy.ts +171 -0
  4. package/tests/cypress/e2e/_devtools/navigation.bdd.md +261 -0
  5. package/tests/cypress/e2e/_devtools/navigation.cy.ts +157 -0
  6. package/tests/cypress/e2e/_devtools/pages.bdd.md +303 -0
  7. package/tests/cypress/e2e/_devtools/pages.cy.ts +184 -0
  8. package/tests/cypress/e2e/_docs/README.md +215 -0
  9. package/tests/cypress/e2e/_docs/tutorials/sector7-superadmin-teams.narration.json +155 -0
  10. package/tests/cypress/e2e/_docs/tutorials/sector7-superadmin.cy.ts +390 -0
  11. package/tests/cypress/e2e/_docs/tutorials/teams-system.doc.cy.ts +349 -0
  12. package/tests/cypress/e2e/_docs/tutorials/teams-system.narration.json +165 -0
  13. package/tests/cypress/e2e/_selectors/auth.cy.ts +306 -0
  14. package/tests/cypress/e2e/_selectors/billing.cy.ts +89 -0
  15. package/tests/cypress/e2e/_selectors/dashboard-mobile.cy.ts +113 -0
  16. package/tests/cypress/e2e/_selectors/dashboard-navigation.cy.ts +89 -0
  17. package/tests/cypress/e2e/_selectors/dashboard-sidebar.cy.ts +60 -0
  18. package/tests/cypress/e2e/_selectors/dashboard-topnav.cy.ts +146 -0
  19. package/tests/cypress/e2e/_selectors/devtools.cy.ts +210 -0
  20. package/tests/cypress/e2e/_selectors/global-search.cy.ts +88 -0
  21. package/tests/cypress/e2e/_selectors/pages-editor.cy.ts +179 -0
  22. package/tests/cypress/e2e/_selectors/posts-editor.cy.ts +282 -0
  23. package/tests/cypress/e2e/_selectors/public.cy.ts +112 -0
  24. package/tests/cypress/e2e/_selectors/settings-api-keys.cy.ts +228 -0
  25. package/tests/cypress/e2e/_selectors/settings-billing.cy.ts +105 -0
  26. package/tests/cypress/e2e/_selectors/settings-layout.cy.ts +119 -0
  27. package/tests/cypress/e2e/_selectors/settings-password.cy.ts +71 -0
  28. package/tests/cypress/e2e/_selectors/settings-profile.cy.ts +82 -0
  29. package/tests/cypress/e2e/_selectors/settings-teams.cy.ts +68 -0
  30. package/tests/cypress/e2e/_selectors/superadmin.cy.ts +185 -0
  31. package/tests/cypress/e2e/_selectors/tasks.cy.ts +242 -0
  32. package/tests/cypress/e2e/_selectors/taxonomies.cy.ts +126 -0
  33. package/tests/cypress/e2e/_selectors/teams.cy.ts +142 -0
  34. package/tests/cypress/e2e/_superadmin/all-teams.bdd.md +261 -0
  35. package/tests/cypress/e2e/_superadmin/all-teams.cy.ts +177 -0
  36. package/tests/cypress/e2e/_superadmin/all-users.bdd.md +406 -0
  37. package/tests/cypress/e2e/_superadmin/all-users.cy.ts +294 -0
  38. package/tests/cypress/e2e/_superadmin/dashboard.bdd.md +235 -0
  39. package/tests/cypress/e2e/_superadmin/dashboard.cy.ts +149 -0
  40. package/tests/cypress/e2e/_superadmin/subscriptions-overview.bdd.md +290 -0
  41. package/tests/cypress/e2e/_superadmin/subscriptions-overview.cy.ts +194 -0
  42. package/tests/cypress/e2e/ai/ai-usage.cy.ts +209 -0
  43. package/tests/cypress/e2e/ai/chat-api.cy.ts +107 -0
  44. package/tests/cypress/e2e/ai/guardrails.cy.ts +332 -0
  45. package/tests/cypress/e2e/api/billing/BillingAPIController.js +319 -0
  46. package/tests/cypress/e2e/api/billing/check-action.cy.ts +326 -0
  47. package/tests/cypress/e2e/api/billing/checkout.cy.ts +358 -0
  48. package/tests/cypress/e2e/api/billing/lifecycle.cy.ts +423 -0
  49. package/tests/cypress/e2e/api/billing/plans/README.md +345 -0
  50. package/tests/cypress/e2e/api/billing/plans/business.cy.ts +412 -0
  51. package/tests/cypress/e2e/api/billing/plans/downgrade.cy.ts +510 -0
  52. package/tests/cypress/e2e/api/billing/plans/fixtures/billing-plans.json +163 -0
  53. package/tests/cypress/e2e/api/billing/plans/free.cy.ts +500 -0
  54. package/tests/cypress/e2e/api/billing/plans/pro.cy.ts +497 -0
  55. package/tests/cypress/e2e/api/billing/plans/starter.cy.ts +342 -0
  56. package/tests/cypress/e2e/api/billing/portal.cy.ts +313 -0
  57. package/tests/cypress/e2e/api/devtools/registries.bdd.md +300 -0
  58. package/tests/cypress/e2e/api/devtools/registries.cy.ts +368 -0
  59. package/tests/cypress/e2e/api/entities/blocks-scope.cy.ts +396 -0
  60. package/tests/cypress/e2e/api/entities/customers-crud.cy.ts +648 -0
  61. package/tests/cypress/e2e/api/entities/customers-metas.cy.ts +839 -0
  62. package/tests/cypress/e2e/api/entities/pages-crud.cy.ts +425 -0
  63. package/tests/cypress/e2e/api/entities/pages-status.cy.ts +335 -0
  64. package/tests/cypress/e2e/api/entities/post-categories-crud.cy.ts +610 -0
  65. package/tests/cypress/e2e/api/entities/posts-crud.cy.ts +709 -0
  66. package/tests/cypress/e2e/api/entities/posts-status.cy.ts +396 -0
  67. package/tests/cypress/e2e/api/entities/tasks-crud.cy.ts +602 -0
  68. package/tests/cypress/e2e/api/entities/tasks-metas.cy.ts +878 -0
  69. package/tests/cypress/e2e/api/entities/users-crud.cy.ts +469 -0
  70. package/tests/cypress/e2e/api/entities/users-metas.cy.ts +913 -0
  71. package/tests/cypress/e2e/api/entities/users-security.cy.ts +375 -0
  72. package/tests/cypress/e2e/api/scheduled-actions/cron-endpoint.bdd.md +375 -0
  73. package/tests/cypress/e2e/api/scheduled-actions/cron-endpoint.cy.ts +346 -0
  74. package/tests/cypress/e2e/api/scheduled-actions/devtools-endpoint.bdd.md +451 -0
  75. package/tests/cypress/e2e/api/scheduled-actions/devtools-endpoint.cy.ts +447 -0
  76. package/tests/cypress/e2e/api/scheduled-actions/scheduling.bdd.md +649 -0
  77. package/tests/cypress/e2e/api/scheduled-actions/scheduling.cy.ts +333 -0
  78. package/tests/cypress/e2e/api/settings/api-keys.crud.cy.ts +923 -0
  79. package/tests/cypress/e2e/uat/auth/app-roles/developer-login.bdd.md +231 -0
  80. package/tests/cypress/e2e/uat/auth/app-roles/developer-login.cy.ts +144 -0
  81. package/tests/cypress/e2e/uat/auth/app-roles/superadmin-login.bdd.md +118 -0
  82. package/tests/cypress/e2e/uat/auth/app-roles/superadmin-login.cy.ts +84 -0
  83. package/tests/cypress/e2e/uat/auth/custom-roles/editor-login.bdd.md +288 -0
  84. package/tests/cypress/e2e/uat/auth/custom-roles/editor-login.cy.ts +188 -0
  85. package/tests/cypress/e2e/uat/auth/login-logout.bdd.md +160 -0
  86. package/tests/cypress/e2e/uat/auth/login-logout.cy.ts +116 -0
  87. package/tests/cypress/e2e/uat/auth/password-reset.bdd.md +289 -0
  88. package/tests/cypress/e2e/uat/auth/password-reset.cy.ts +200 -0
  89. package/tests/cypress/e2e/uat/auth/team-roles/admin-login.bdd.md +225 -0
  90. package/tests/cypress/e2e/uat/auth/team-roles/admin-login.cy.ts +148 -0
  91. package/tests/cypress/e2e/uat/auth/team-roles/member-login.bdd.md +251 -0
  92. package/tests/cypress/e2e/uat/auth/team-roles/member-login.cy.ts +163 -0
  93. package/tests/cypress/e2e/uat/auth/team-roles/owner-login.bdd.md +231 -0
  94. package/tests/cypress/e2e/uat/auth/team-roles/owner-login.cy.ts +141 -0
  95. package/tests/cypress/e2e/uat/billing/extended.bdd.md +273 -0
  96. package/tests/cypress/e2e/uat/billing/extended.cy.ts +209 -0
  97. package/tests/cypress/e2e/uat/billing/feature-gates.bdd.md +407 -0
  98. package/tests/cypress/e2e/uat/billing/feature-gates.cy.ts +307 -0
  99. package/tests/cypress/e2e/uat/billing/page.bdd.md +329 -0
  100. package/tests/cypress/e2e/uat/billing/page.cy.ts +250 -0
  101. package/tests/cypress/e2e/uat/billing/status.bdd.md +190 -0
  102. package/tests/cypress/e2e/uat/billing/status.cy.ts +145 -0
  103. package/tests/cypress/e2e/uat/billing/team-switch.bdd.md +156 -0
  104. package/tests/cypress/e2e/uat/billing/team-switch.cy.ts +122 -0
  105. package/tests/cypress/e2e/uat/billing/usage.bdd.md +218 -0
  106. package/tests/cypress/e2e/uat/billing/usage.cy.ts +176 -0
  107. package/tests/cypress/e2e/uat/blocks/hero.bdd.md +124 -0
  108. package/tests/cypress/e2e/uat/blocks/hero.cy.ts +56 -0
  109. package/tests/cypress/e2e/uat/devtools/api-tester.cy.ts +390 -0
  110. package/tests/cypress/e2e/uat/entities/customers/member.bdd.md +275 -0
  111. package/tests/cypress/e2e/uat/entities/customers/member.cy.ts +122 -0
  112. package/tests/cypress/e2e/uat/entities/customers/owner.bdd.md +243 -0
  113. package/tests/cypress/e2e/uat/entities/customers/owner.cy.ts +165 -0
  114. package/tests/cypress/e2e/uat/entities/pages/block-crud.bdd.md +476 -0
  115. package/tests/cypress/e2e/uat/entities/pages/block-crud.cy.ts +486 -0
  116. package/tests/cypress/e2e/uat/entities/pages/block-editor.bdd.md +460 -0
  117. package/tests/cypress/e2e/uat/entities/pages/block-editor.cy.ts +301 -0
  118. package/tests/cypress/e2e/uat/entities/pages/list.bdd.md +432 -0
  119. package/tests/cypress/e2e/uat/entities/pages/list.cy.ts +273 -0
  120. package/tests/cypress/e2e/uat/entities/pages/public-rendering.bdd.md +696 -0
  121. package/tests/cypress/e2e/uat/entities/pages/public-rendering.cy.ts +340 -0
  122. package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.bdd.md +161 -0
  123. package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.cy.ts +104 -0
  124. package/tests/cypress/e2e/uat/entities/posts/categories.bdd.md +375 -0
  125. package/tests/cypress/e2e/uat/entities/posts/categories.cy.ts +241 -0
  126. package/tests/cypress/e2e/uat/entities/posts/editor.bdd.md +429 -0
  127. package/tests/cypress/e2e/uat/entities/posts/editor.cy.ts +257 -0
  128. package/tests/cypress/e2e/uat/entities/posts/list.bdd.md +340 -0
  129. package/tests/cypress/e2e/uat/entities/posts/list.cy.ts +177 -0
  130. package/tests/cypress/e2e/uat/entities/posts/public.bdd.md +614 -0
  131. package/tests/cypress/e2e/uat/entities/posts/public.cy.ts +249 -0
  132. package/tests/cypress/e2e/uat/entities/tasks/member.bdd.md +222 -0
  133. package/tests/cypress/e2e/uat/entities/tasks/member.cy.ts +165 -0
  134. package/tests/cypress/e2e/uat/entities/tasks/owner.bdd.md +419 -0
  135. package/tests/cypress/e2e/uat/entities/tasks/owner.cy.ts +191 -0
  136. package/tests/cypress/e2e/uat/roles/editor-role.bdd.md +552 -0
  137. package/tests/cypress/e2e/uat/roles/editor-role.cy.ts +210 -0
  138. package/tests/cypress/e2e/uat/roles/member-restrictions.bdd.md +450 -0
  139. package/tests/cypress/e2e/uat/roles/member-restrictions.cy.ts +189 -0
  140. package/tests/cypress/e2e/uat/roles/owner-full-crud.bdd.md +530 -0
  141. package/tests/cypress/e2e/uat/roles/owner-full-crud.cy.ts +247 -0
  142. package/tests/cypress/e2e/uat/scheduled-actions/devtools-ui.bdd.md +736 -0
  143. package/tests/cypress/e2e/uat/scheduled-actions/devtools-ui.cy.ts +740 -0
  144. package/tests/cypress/e2e/uat/teams/roles-matrix.bdd.md +553 -0
  145. package/tests/cypress/e2e/uat/teams/roles-matrix.cy.ts +185 -0
  146. package/tests/cypress/e2e/uat/teams/switcher.bdd.md +1151 -0
  147. package/tests/cypress/e2e/uat/teams/switcher.cy.ts +497 -0
  148. package/tests/cypress/e2e/uat/teams/team-switcher.md +198 -0
  149. package/tests/cypress/fixtures/blocks.json +218 -0
  150. package/tests/cypress/fixtures/entities.json +78 -0
  151. package/tests/cypress/fixtures/page-builder.json +21 -0
  152. package/tests/cypress/src/components/CategoriesPOM.ts +382 -0
  153. package/tests/cypress/src/components/CustomersPOM.ts +439 -0
  154. package/tests/cypress/src/components/DevKeyringPOM.ts +160 -0
  155. package/tests/cypress/src/components/EntityForm.ts +375 -0
  156. package/tests/cypress/src/components/EntityList.ts +389 -0
  157. package/tests/cypress/src/components/PageBuilderPOM.ts +710 -0
  158. package/tests/cypress/src/components/PostEditorPOM.ts +370 -0
  159. package/tests/cypress/src/components/PostsListPOM.ts +223 -0
  160. package/tests/cypress/src/components/PublicPagePOM.ts +447 -0
  161. package/tests/cypress/src/components/PublicPostPOM.ts +146 -0
  162. package/tests/cypress/src/components/TasksPOM.ts +272 -0
  163. package/tests/cypress/src/components/TeamSwitcherPOM.ts +450 -0
  164. package/tests/cypress/src/components/index.ts +21 -0
  165. package/tests/cypress/src/controllers/ApiKeysAPIController.js +178 -0
  166. package/tests/cypress/src/controllers/BaseAPIController.js +317 -0
  167. package/tests/cypress/src/controllers/CustomerAPIController.js +251 -0
  168. package/tests/cypress/src/controllers/PagesAPIController.js +226 -0
  169. package/tests/cypress/src/controllers/PostsAPIController.js +250 -0
  170. package/tests/cypress/src/controllers/TaskAPIController.js +240 -0
  171. package/tests/cypress/src/controllers/UsersAPIController.js +242 -0
  172. package/tests/cypress/src/controllers/index.js +25 -0
  173. package/tests/cypress/src/core/AuthPOM.ts +450 -0
  174. package/tests/cypress/src/core/BasePOM.ts +86 -0
  175. package/tests/cypress/src/core/BlockEditorBasePOM.ts +576 -0
  176. package/tests/cypress/src/core/DashboardEntityPOM.ts +692 -0
  177. package/tests/cypress/src/core/index.ts +14 -0
  178. package/tests/cypress/src/entities/CustomersPOM.ts +172 -0
  179. package/tests/cypress/src/entities/PagesPOM.ts +137 -0
  180. package/tests/cypress/src/entities/PostsPOM.ts +137 -0
  181. package/tests/cypress/src/entities/TasksPOM.ts +176 -0
  182. package/tests/cypress/src/entities/index.ts +14 -0
  183. package/tests/cypress/src/features/BillingPOM.ts +385 -0
  184. package/tests/cypress/src/features/DashboardPOM.ts +245 -0
  185. package/tests/cypress/src/features/DevtoolsPOM.ts +739 -0
  186. package/tests/cypress/src/features/PageBuilderPOM.ts +263 -0
  187. package/tests/cypress/src/features/PostEditorPOM.ts +313 -0
  188. package/tests/cypress/src/features/ScheduledActionsPOM.ts +463 -0
  189. package/tests/cypress/src/features/SettingsPOM.ts +362 -0
  190. package/tests/cypress/src/features/SuperadminPOM.ts +331 -0
  191. package/tests/cypress/src/features/SuperadminTeamRolesPOM.ts +285 -0
  192. package/tests/cypress/src/features/index.ts +28 -0
  193. package/tests/cypress/src/helpers/ApiInterceptor.ts +177 -0
  194. package/tests/cypress/src/index.ts +101 -0
  195. package/tests/cypress/src/pages/dashboard/Dashboard.js +677 -0
  196. package/tests/cypress/src/pages/dashboard/DashboardPage.js +43 -0
  197. package/tests/cypress/src/pages/dashboard/DashboardStats.js +546 -0
  198. package/tests/cypress/src/pages/dashboard/index.js +6 -0
  199. package/tests/cypress/src/pages/index.js +5 -0
  200. package/tests/cypress/src/pages/public/FeaturesPage.js +28 -0
  201. package/tests/cypress/src/pages/public/LandingPage.js +69 -0
  202. package/tests/cypress/src/pages/public/PricingPage.js +33 -0
  203. package/tests/cypress/src/pages/public/index.js +6 -0
  204. package/tests/cypress/src/selectors.ts +46 -0
  205. package/tests/cypress/src/session-helpers.ts +500 -0
  206. package/tests/cypress/support/doc-commands.ts +260 -0
  207. package/tests/cypress.config.ts +150 -0
  208. package/tests/jest/components/post-header.test.tsx +377 -0
  209. package/tests/jest/config/role-config.test.ts +529 -0
  210. package/tests/jest/jest.config.ts +81 -0
  211. package/tests/jest/langchain/COVERAGE.md +372 -0
  212. package/tests/jest/langchain/guardrails.test.ts +465 -0
  213. package/tests/jest/langchain/streaming.test.ts +367 -0
  214. package/tests/jest/langchain/token-tracker.test.ts +455 -0
  215. package/tests/jest/langchain/tracer-callbacks.test.ts +881 -0
  216. package/tests/jest/langchain/tracer.test.ts +823 -0
  217. package/tests/jest/user-roles/role-helpers.test.ts +432 -0
  218. package/tests/jest/validation/categories.test.ts +429 -0
  219. package/tests/jest/validation/posts.test.ts +546 -0
  220. package/tests/tsconfig.json +15 -0
@@ -0,0 +1,249 @@
1
+ /// <reference types="cypress" />
2
+
3
+ /**
4
+ * Public Post Display - UAT Tests
5
+ *
6
+ * Tests for public post rendering at /blog/[slug].
7
+ * Validates post display, blocks rendering, categories, and SEO.
8
+ *
9
+ * Tags: @uat, @feat-posts, @public, @regression
10
+ */
11
+
12
+ import * as allure from 'allure-cypress'
13
+ import { PublicPostPOM } from '../../../../src'
14
+
15
+ describe('Public Post Display - UAT', {
16
+ tags: ['@uat', '@feat-posts', '@public', '@regression']
17
+ }, () => {
18
+ beforeEach(() => {
19
+ allure.epic('Posts System')
20
+ allure.feature('Public Post Display')
21
+ })
22
+
23
+ // ============================================================
24
+ // Post Rendering Tests
25
+ // ============================================================
26
+ describe('Post Rendering', () => {
27
+ it('POST-PUB-001: Should render a published post', { tags: '@smoke' }, () => {
28
+ allure.story('Post Rendering')
29
+ allure.severity('critical')
30
+
31
+ // Visit a sample post (from sample data: 'welcome-to-our-blog')
32
+ PublicPostPOM.visit('welcome-to-our-blog')
33
+ PublicPostPOM.waitForPostLoad()
34
+ PublicPostPOM.assertPostVisible()
35
+
36
+ cy.log('Published post rendered successfully')
37
+ })
38
+
39
+ it('POST-PUB-002: Should display post header', () => {
40
+ allure.story('Post Rendering')
41
+ allure.severity('normal')
42
+
43
+ PublicPostPOM.visit('welcome-to-our-blog')
44
+ PublicPostPOM.waitForPostLoad()
45
+
46
+ PublicPostPOM.assertHeaderVisible()
47
+ PublicPostPOM.assertTitle('Welcome')
48
+
49
+ cy.log('Post header displayed')
50
+ })
51
+
52
+ it('POST-PUB-003: Should display post excerpt', () => {
53
+ allure.story('Post Rendering')
54
+ allure.severity('normal')
55
+
56
+ PublicPostPOM.visit('welcome-to-our-blog')
57
+ PublicPostPOM.waitForPostLoad()
58
+
59
+ // Check that excerpt is visible
60
+ cy.get(PublicPostPOM.postSelectors.excerpt).should('be.visible')
61
+
62
+ cy.log('Post excerpt displayed')
63
+ })
64
+ })
65
+
66
+ // ============================================================
67
+ // Block Rendering Tests
68
+ // ============================================================
69
+ describe('Block Rendering', () => {
70
+ it('POST-PUB-004: Should render post blocks', () => {
71
+ allure.story('Block Rendering')
72
+ allure.severity('normal')
73
+
74
+ PublicPostPOM.visit('welcome-to-our-blog')
75
+ PublicPostPOM.waitForPostLoad()
76
+
77
+ // Sample posts have hero blocks - check that blocks are rendered
78
+ cy.get(PublicPostPOM.postSelectors.content).within(() => {
79
+ // Look for block content (hero block typically has heading and text)
80
+ cy.get('h1, h2, h3').should('exist')
81
+ })
82
+
83
+ cy.log('Post blocks rendered')
84
+ })
85
+
86
+ it('POST-PUB-005: Should render hero block correctly', () => {
87
+ allure.story('Block Rendering')
88
+ allure.severity('normal')
89
+
90
+ PublicPostPOM.visit('welcome-to-our-blog')
91
+ PublicPostPOM.waitForPostLoad()
92
+
93
+ // Hero block should render with its content
94
+ cy.get(PublicPostPOM.postSelectors.content).within(() => {
95
+ // Hero typically has heading, description, and CTA
96
+ cy.contains('Welcome', { matchCase: false }).should('exist')
97
+ })
98
+
99
+ cy.log('Hero block rendered correctly')
100
+ })
101
+ })
102
+
103
+ // ============================================================
104
+ // Category Display Tests
105
+ // ============================================================
106
+ describe('Category Display', () => {
107
+ it('POST-PUB-006: Should display category badges', () => {
108
+ allure.story('Categories')
109
+ allure.severity('normal')
110
+
111
+ PublicPostPOM.visit('welcome-to-our-blog')
112
+ PublicPostPOM.waitForPostLoad()
113
+
114
+ // Sample post has "News" category
115
+ PublicPostPOM.assertCategoryVisible('News')
116
+
117
+ cy.log('Category badges displayed')
118
+ })
119
+
120
+ it('POST-PUB-007: Should display category badges with colors', () => {
121
+ allure.story('Categories')
122
+ allure.severity('minor')
123
+
124
+ PublicPostPOM.visit('welcome-to-our-blog')
125
+ PublicPostPOM.waitForPostLoad()
126
+
127
+ // Check that categories have color styling
128
+ cy.get(PublicPostPOM.postSelectors.categoriesDisplay).within(() => {
129
+ cy.get('[style*="background"], [style*="color"]').should('exist')
130
+ })
131
+
132
+ cy.log('Category badges with colors displayed')
133
+ })
134
+ })
135
+
136
+ // ============================================================
137
+ // SEO Tests
138
+ // ============================================================
139
+ describe('SEO Meta Tags', () => {
140
+ // SEO meta tags implementation pending
141
+ it.skip('POST-PUB-008: Should have correct page title', () => {
142
+ allure.story('SEO')
143
+ allure.severity('normal')
144
+
145
+ PublicPostPOM.visit('welcome-to-our-blog')
146
+ PublicPostPOM.waitForPostLoad()
147
+
148
+ // Check that page title includes post title
149
+ PublicPostPOM.assertMetaTitle('Welcome')
150
+
151
+ cy.log('SEO title correct')
152
+ })
153
+
154
+ // SEO meta tags implementation pending
155
+ it.skip('POST-PUB-009: Should have meta description', () => {
156
+ allure.story('SEO')
157
+ allure.severity('normal')
158
+
159
+ PublicPostPOM.visit('welcome-to-our-blog')
160
+ PublicPostPOM.waitForPostLoad()
161
+
162
+ // Check for meta description
163
+ cy.get('head meta[name="description"]').should('exist')
164
+
165
+ cy.log('Meta description exists')
166
+ })
167
+
168
+ // SEO meta tags implementation pending
169
+ it.skip('POST-PUB-010: Should have OG tags for social sharing', () => {
170
+ allure.story('SEO')
171
+ allure.severity('normal')
172
+
173
+ PublicPostPOM.visit('welcome-to-our-blog')
174
+ PublicPostPOM.waitForPostLoad()
175
+
176
+ // Check for Open Graph tags
177
+ cy.get('head meta[property^="og:"]').should('have.length.at.least', 1)
178
+
179
+ cy.log('OG tags present')
180
+ })
181
+ })
182
+
183
+ // ============================================================
184
+ // Unpublished Post Tests
185
+ // ============================================================
186
+ describe('Unpublished Posts', () => {
187
+ it('POST-PUB-011: Should not display unpublished posts', () => {
188
+ allure.story('Access Control')
189
+ allure.severity('critical')
190
+
191
+ // Sample data has 'typescript-best-practices' as draft
192
+ PublicPostPOM.visit('typescript-best-practices', { failOnStatusCode: false })
193
+
194
+ // Wait for page to render then check for 404 content
195
+ cy.get('body', { timeout: 10000 }).should('be.visible').then(($body) => {
196
+ // Either URL changed to 404 or page shows error/not found content
197
+ const bodyText = $body.text().toLowerCase()
198
+ const hasNotFound = bodyText.includes('404') || bodyText.includes('not found') || bodyText.includes('page not found')
199
+ expect(hasNotFound).to.be.true
200
+ })
201
+
202
+ cy.log('Unpublished post not accessible')
203
+ })
204
+ })
205
+
206
+ // ============================================================
207
+ // 404 Tests
208
+ // ============================================================
209
+ describe('404 Not Found', () => {
210
+ it('POST-PUB-012: Should show 404 for non-existent post', () => {
211
+ allure.story('Error Handling')
212
+ allure.severity('normal')
213
+
214
+ PublicPostPOM.visit('non-existent-post-slug-12345', { failOnStatusCode: false })
215
+
216
+ // Wait for page to render then check for 404 content
217
+ cy.get('body', { timeout: 10000 }).should('be.visible').then(($body) => {
218
+ const bodyText = $body.text().toLowerCase()
219
+ const hasNotFound = bodyText.includes('404') || bodyText.includes('not found') || bodyText.includes('page not found')
220
+ expect(hasNotFound).to.be.true
221
+ })
222
+
223
+ cy.log('404 shown for non-existent post')
224
+ })
225
+ })
226
+
227
+ // ============================================================
228
+ // Featured Image Tests
229
+ // ============================================================
230
+ describe('Featured Image', () => {
231
+ it('POST-PUB-013: Should display featured image when present', () => {
232
+ allure.story('Media')
233
+ allure.severity('minor')
234
+
235
+ PublicPostPOM.visit('welcome-to-our-blog')
236
+ PublicPostPOM.waitForPostLoad()
237
+
238
+ // Check if featured image is present (may or may not be in sample data)
239
+ cy.get(PublicPostPOM.postSelectors.header).then(($header) => {
240
+ if ($header.find(PublicPostPOM.postSelectors.featuredImage).length > 0) {
241
+ PublicPostPOM.assertFeaturedImageVisible()
242
+ cy.log('Featured image displayed')
243
+ } else {
244
+ cy.log('No featured image in this post (optional field)')
245
+ }
246
+ })
247
+ })
248
+ })
249
+ })
@@ -0,0 +1,222 @@
1
+ ---
2
+ feature: Tasks Management - Member Role
3
+ priority: high
4
+ tags: [tasks, member, permissions, crud-limited]
5
+ grepTags: [uat, feat-tasks, role-member, security]
6
+ coverage: 5
7
+ ---
8
+
9
+ # Tasks Management - Member Role (Limited Access - No Delete)
10
+
11
+ > Test suite for Member role task permissions. Members can create, read, and update tasks but CANNOT delete them. These tests verify proper CRUD restrictions for the Member role.
12
+
13
+ ## Background
14
+
15
+ ```gherkin:en
16
+ Given I am logged in as Member (member@nextspark.dev)
17
+ And I have navigated to the Tasks dashboard
18
+ And the tasks list has loaded successfully
19
+ ```
20
+
21
+ ```gherkin:es
22
+ Given estoy logueado como Member (member@nextspark.dev)
23
+ And he navegado al dashboard de Tareas
24
+ And la lista de tareas ha cargado exitosamente
25
+ ```
26
+
27
+ ---
28
+
29
+ ## @test MEMBER-TASK-CREATE-001: Member can create tasks
30
+
31
+ ### Metadata
32
+ - **Priority:** High
33
+ - **Type:** Regression
34
+ - **Tags:** create, form, permissions
35
+
36
+ ```gherkin:en
37
+ Scenario: Member creates a new task
38
+
39
+ Given I am logged in as a Member
40
+ And I am on the Tasks list page
41
+ When I click the "Add" button
42
+ Then the task creation form should appear
43
+
44
+ When I enter "Member's New Task" in the Title field
45
+ And I enter "Created by team member" in the Description
46
+ And I click the "Save" button
47
+ Then the form should submit successfully
48
+ And I should see the task in the list
49
+ ```
50
+
51
+ ```gherkin:es
52
+ Scenario: Member crea una nueva tarea
53
+
54
+ Given estoy logueado como Member
55
+ And estoy en la pagina de lista de Tareas
56
+ When hago clic en el boton "Agregar"
57
+ Then deberia aparecer el formulario de creacion
58
+
59
+ When ingreso "Nueva Tarea del Member" en el campo Titulo
60
+ And ingreso "Creado por miembro del equipo" en Descripcion
61
+ And hago clic en el boton "Guardar"
62
+ Then el formulario deberia enviarse exitosamente
63
+ And deberia ver la tarea en la lista
64
+ ```
65
+
66
+ ### Expected Results
67
+ - Add button is visible and clickable for Members
68
+ - Task creation form opens correctly
69
+ - Form submission creates new task
70
+ - New task appears in the list
71
+
72
+ ---
73
+
74
+ ## @test MEMBER-TASK-READ-001: Member can view all tasks
75
+
76
+ ### Metadata
77
+ - **Priority:** High
78
+ - **Type:** Smoke
79
+ - **Tags:** read, list, permissions
80
+ - **Grep:** `@smoke`
81
+
82
+ ```gherkin:en
83
+ Scenario: Member can see the tasks table
84
+
85
+ Given I am logged in as a Member
86
+ When I navigate to the Tasks dashboard
87
+ Then I should see the tasks table
88
+ And I should see all team tasks (not just my own)
89
+ ```
90
+
91
+ ```gherkin:es
92
+ Scenario: Member puede ver la tabla de tareas
93
+
94
+ Given estoy logueado como Member
95
+ When navego al dashboard de Tareas
96
+ Then deberia ver la tabla de tareas
97
+ And deberia ver todas las tareas del equipo (no solo las mias)
98
+ ```
99
+
100
+ ### Expected Results
101
+ - Tasks dashboard is accessible
102
+ - Tasks table displays correctly
103
+ - All team tasks are visible (not just own tasks)
104
+ - Read access is granted to all tasks
105
+
106
+ ---
107
+
108
+ ## @test MEMBER-TASK-READ-002: Member can view task details
109
+
110
+ ### Metadata
111
+ - **Priority:** High
112
+ - **Type:** Regression
113
+ - **Tags:** read, details, navigation
114
+
115
+ ```gherkin:en
116
+ Scenario: Member can access task detail page
117
+
118
+ Given I am logged in as a Member
119
+ And I have created a task called "Member Test Task"
120
+ When I click on that task in the list
121
+ Then I should be navigated to the task detail page
122
+ And I should see the task title "Member Test Task"
123
+ And I should see the task description
124
+ ```
125
+
126
+ ```gherkin:es
127
+ Scenario: Member puede acceder a pagina de detalle
128
+
129
+ Given estoy logueado como Member
130
+ And he creado una tarea llamada "Tarea de Prueba Member"
131
+ When hago clic en esa tarea en la lista
132
+ Then deberia ser navegado a la pagina de detalle
133
+ And deberia ver el titulo "Tarea de Prueba Member"
134
+ And deberia ver la descripcion de la tarea
135
+ ```
136
+
137
+ ### Expected Results
138
+ - Task rows are clickable
139
+ - Detail page navigation works
140
+ - Task title displays correctly
141
+ - Task description is visible
142
+
143
+ ---
144
+
145
+ ## @test MEMBER-TASK-UPDATE-001: Member can edit tasks
146
+
147
+ ### Metadata
148
+ - **Priority:** High
149
+ - **Type:** Regression
150
+ - **Tags:** update, edit, form
151
+
152
+ ```gherkin:en
153
+ Scenario: Member can modify task information
154
+
155
+ Given I am logged in as a Member
156
+ And I have created a task called "Original Title"
157
+ When I click the "Edit" button on that task
158
+ Then the edit form should appear
159
+
160
+ When I change the Title to "Original Title - Updated"
161
+ And I click the "Save" button
162
+ Then the changes should be saved
163
+ And I should see "Original Title - Updated" in the list
164
+ ```
165
+
166
+ ```gherkin:es
167
+ Scenario: Member puede modificar informacion de tarea
168
+
169
+ Given estoy logueado como Member
170
+ And he creado una tarea llamada "Titulo Original"
171
+ When hago clic en el boton "Editar" de esa tarea
172
+ Then deberia aparecer el formulario de edicion
173
+
174
+ When cambio el Titulo a "Titulo Original - Actualizado"
175
+ And hago clic en el boton "Guardar"
176
+ Then los cambios deberian guardarse
177
+ And deberia ver "Titulo Original - Actualizado" en la lista
178
+ ```
179
+
180
+ ### Expected Results
181
+ - Edit button is visible for Members
182
+ - Edit form opens with pre-filled data
183
+ - Changes can be saved successfully
184
+ - Updated data reflects in the list
185
+
186
+ ---
187
+
188
+ ## @test MEMBER-TASK-DELETE-001: Delete button is hidden
189
+
190
+ ### Metadata
191
+ - **Priority:** Critical
192
+ - **Type:** Smoke
193
+ - **Tags:** delete, security, hidden-button
194
+ - **Grep:** `@critical` `@security`
195
+
196
+ ```gherkin:en
197
+ Scenario: Delete functionality is hidden from Member role
198
+
199
+ Given I am logged in as a Member
200
+ And there is at least one task in the list
201
+ When I click on a task to view its details
202
+ Then I should see the task information
203
+ But I should NOT see a "Delete" button
204
+ And there should be no way for me to delete the task
205
+ ```
206
+
207
+ ```gherkin:es
208
+ Scenario: Funcionalidad de eliminar oculta para rol Member
209
+
210
+ Given estoy logueado como Member
211
+ And existe al menos una tarea en la lista
212
+ When hago clic en una tarea para ver sus detalles
213
+ Then deberia ver la informacion de la tarea
214
+ But NO deberia ver un boton "Eliminar"
215
+ And no deberia haber forma de eliminar la tarea
216
+ ```
217
+
218
+ ### Expected Results
219
+ - Task information is visible
220
+ - Delete button is completely hidden (not just disabled)
221
+ - Delete button does not exist in DOM
222
+ - Security: No way to delete tasks as Member role
@@ -0,0 +1,165 @@
1
+ /// <reference types="cypress" />
2
+
3
+ import * as allure from 'allure-cypress'
4
+
5
+ import { TasksPOM } from '../../../../src/entities/TasksPOM'
6
+ import { loginAsDefaultMember } from '../../../../src/session-helpers'
7
+
8
+ describe('Tasks CRUD - Member Role (Create, Read, Update - No Delete)', {
9
+ tags: ['@uat', '@feat-tasks', '@crud', '@role-member', '@regression']
10
+ }, () => {
11
+ const tasks = TasksPOM.create()
12
+ let createdTaskTitles: string[] = []
13
+
14
+ beforeEach(() => {
15
+ allure.epic('UAT')
16
+ allure.feature('Tasks')
17
+ allure.story('Member Permissions')
18
+ tasks.setupApiIntercepts()
19
+ loginAsDefaultMember()
20
+ tasks.visitList()
21
+ tasks.api.waitForList()
22
+ tasks.waitForList()
23
+ })
24
+
25
+ describe('CREATE - Member can create tasks', () => {
26
+ it('MEMBER_TASK_CREATE_001: should create task successfully', () => {
27
+ const taskTitle = `Member Task ${Date.now()}`
28
+ const taskDescription = 'Task created by Member for testing'
29
+
30
+ // Click create button
31
+ tasks.clickAdd()
32
+
33
+ // Wait for form
34
+ tasks.waitForForm()
35
+
36
+ // Fill form
37
+ tasks.fillTextField('title', taskTitle)
38
+ tasks.fillTextarea('description', taskDescription)
39
+ tasks.submitForm()
40
+
41
+ // Wait for API response
42
+ tasks.api.waitForCreate()
43
+
44
+ // Validate task appears in list
45
+ cy.url().should('include', `/dashboard/${tasks.entitySlug}`)
46
+ tasks.assertTaskInList(taskTitle)
47
+ createdTaskTitles.push(taskTitle)
48
+
49
+ cy.log('✅ Member created task successfully')
50
+ })
51
+ })
52
+
53
+ describe('READ - Member can read tasks', () => {
54
+ it('MEMBER_TASK_READ_001: should view all tasks', () => {
55
+ // Validate list is loaded
56
+ tasks.assertTableVisible()
57
+
58
+ cy.log('✅ Member can view task list')
59
+ })
60
+
61
+ it('MEMBER_TASK_READ_002: should view task details', () => {
62
+ // Create a task first
63
+ const taskTitle = `Member Read Test ${Date.now()}`
64
+
65
+ tasks.clickAdd()
66
+ tasks.waitForForm()
67
+ tasks.fillTextField('title', taskTitle)
68
+ tasks.fillTextarea('description', 'Test description')
69
+ tasks.submitForm()
70
+ tasks.api.waitForCreate()
71
+ createdTaskTitles.push(taskTitle)
72
+
73
+ // Navigate back to list
74
+ tasks.visitList()
75
+ tasks.waitForList()
76
+
77
+ // Click on task to view details (rows use onClick, not <a> tag)
78
+ tasks.clickRowByText(taskTitle)
79
+
80
+ // Should show task details
81
+ cy.url().should('match', new RegExp(`/dashboard/${tasks.entitySlug}/[a-z0-9-]+`))
82
+ cy.contains(taskTitle).should('be.visible')
83
+
84
+ cy.log('✅ Member can view task details')
85
+ })
86
+ })
87
+
88
+ describe('UPDATE - Member can update tasks', () => {
89
+ it('MEMBER_TASK_UPDATE_001: should edit task title', () => {
90
+ const originalTitle = `Member Edit Test ${Date.now()}`
91
+ const updatedTitle = `${originalTitle} - Updated`
92
+
93
+ // Create task
94
+ tasks.clickAdd()
95
+ tasks.waitForForm()
96
+ tasks.fillTextField('title', originalTitle)
97
+ tasks.fillTextarea('description', 'Edit test')
98
+ tasks.submitForm()
99
+ tasks.api.waitForCreate()
100
+ createdTaskTitles.push(originalTitle)
101
+ createdTaskTitles.push(updatedTitle)
102
+
103
+ // Navigate back to list
104
+ tasks.visitList()
105
+ tasks.waitForList()
106
+
107
+ // Wait for task to appear
108
+ tasks.assertTaskInList(originalTitle)
109
+
110
+ // Look for edit button and click it
111
+ cy.get('body').then($body => {
112
+ // Use POM selector for edit actions (dynamic slug)
113
+ if ($body.find(tasks.selectors.rowActionEditGeneric).length > 0) {
114
+ cy.get(tasks.selectors.rowActionEditGeneric).first().click()
115
+
116
+ // Wait for form
117
+ tasks.waitForForm()
118
+
119
+ // Update title
120
+ tasks.fillTextField('title', updatedTitle)
121
+ tasks.submitForm()
122
+ tasks.api.waitForUpdate()
123
+
124
+ // Validate updated task appears
125
+ cy.url().should('include', `/dashboard/${tasks.entitySlug}`)
126
+ tasks.assertTaskInList(updatedTitle)
127
+
128
+ cy.log('✅ Member edited task successfully')
129
+ } else {
130
+ cy.log('⚠️ No edit button found')
131
+ }
132
+ })
133
+ })
134
+ })
135
+
136
+ describe('DELETE - Member CANNOT delete tasks (no permission)', () => {
137
+ it('MEMBER_TASK_DELETE_001: delete button should be hidden', () => {
138
+ // Check if there are tasks
139
+ cy.get('body').then($body => {
140
+ if ($body.find(tasks.selectors.rowGeneric).length > 0) {
141
+ // Click first task to view details (rows use onClick, not <a> tag)
142
+ cy.get(tasks.selectors.rowGeneric).first().click()
143
+
144
+ // Wait for detail page
145
+ tasks.waitForDetail()
146
+
147
+ // Delete button should NOT exist for Member role
148
+ // EntityDetailHeader uses tasks-delete-btn selector
149
+ cy.get(tasks.selectors.deleteButton).should('not.exist')
150
+
151
+ cy.log('✅ Delete button correctly hidden for Member')
152
+ } else {
153
+ cy.log('⚠️ No tasks available to check delete permission')
154
+ }
155
+ })
156
+ })
157
+ })
158
+
159
+ after(() => {
160
+ // Cleanup: Note created tasks
161
+ if (createdTaskTitles.length > 0) {
162
+ cy.log(`🧹 Cleaning up ${createdTaskTitles.length} test tasks...`)
163
+ }
164
+ })
165
+ })