@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,390 @@
1
+ /**
2
+ * UAT Tests: DevTools API Tester
3
+ *
4
+ * This test suite validates the API Tester feature in DevTools.
5
+ * The API Tester allows developers to test API endpoints directly from the browser.
6
+ *
7
+ * Coverage:
8
+ * - Navigation to endpoint detail pages
9
+ * - HTTP method selection
10
+ * - Path parameter handling
11
+ * - Query parameter management
12
+ * - Request body (JSON payload) editing
13
+ * - Authentication modes (session/API key)
14
+ * - Request execution and cancellation
15
+ * - Response display (status, timing, body, headers)
16
+ *
17
+ * Session: 2025-12-30-devtools-api-mini-postman-v1
18
+ * Workflow Phase: 15 (qa-automation)
19
+ */
20
+
21
+ import { DevtoolsPOM } from '../../../src/features/DevtoolsPOM'
22
+ import { loginAsDefaultDeveloper } from '../../../src/session-helpers'
23
+
24
+ describe('DevTools API Tester UAT', () => {
25
+ const devtools = DevtoolsPOM.create()
26
+
27
+ beforeEach('Login as developer', () => {
28
+ // DevTools requires developer role
29
+ loginAsDefaultDeveloper()
30
+ })
31
+
32
+ // ============================================
33
+ // UAT-001: Navigation to Endpoint Detail
34
+ // ACs: AC-NAV-01, AC-NAV-02
35
+ // ============================================
36
+ describe('UAT-001: Navigate to endpoint detail from list', () => {
37
+ it('should navigate to /devtools/api', () => {
38
+ devtools.visitApiList()
39
+ cy.url().should('include', '/devtools/api')
40
+ })
41
+
42
+ it('should click on an endpoint and navigate to detail page', () => {
43
+ devtools.visitApiList()
44
+ cy.wait(1000) // Wait for endpoints to load
45
+
46
+ // Click first endpoint
47
+ devtools.clickFirstEndpoint()
48
+
49
+ // Should navigate to detail page
50
+ cy.url().should('match', /\/devtools\/api\/v1\//)
51
+ })
52
+
53
+ it('should show endpoint info and API tester on detail page', () => {
54
+ // Visit a known endpoint directly (e.g., /api/v1/profile)
55
+ devtools.visitApiEndpoint('/v1/profile')
56
+
57
+ devtools
58
+ .assertApiTesterVisible()
59
+ .assertEndpointInfoVisible()
60
+ })
61
+ })
62
+
63
+ // ============================================
64
+ // UAT-002: Method Selector Shows Available Methods
65
+ // ACs: AC-MTH-01, AC-MTH-02
66
+ // ============================================
67
+ describe('UAT-002: Method selector shows available methods', () => {
68
+ beforeEach(() => {
69
+ // Visit endpoint with multiple methods (e.g., /api/v1/profile has GET, PATCH)
70
+ devtools.visitApiEndpoint('/v1/profile')
71
+ })
72
+
73
+ it('should show only available methods for the endpoint', () => {
74
+ // Profile endpoint should have GET and PATCH
75
+ devtools
76
+ .assertMethodExists('get')
77
+ .assertMethodExists('patch')
78
+ })
79
+
80
+ it('should have GET selected by default if available', () => {
81
+ cy.get('[data-cy="api-tester-method-get"]')
82
+ .should('have.class', 'ring-2') // Selected state has ring
83
+ })
84
+ })
85
+
86
+ // ============================================
87
+ // UAT-003: Method Selection Updates UI
88
+ // ACs: AC-MTH-03, AC-MTH-04
89
+ // ============================================
90
+ describe('UAT-003: Method selection updates UI (payload editor)', () => {
91
+ beforeEach(() => {
92
+ devtools.visitApiEndpoint('/v1/profile')
93
+ })
94
+
95
+ it('should NOT show payload editor for GET method', () => {
96
+ devtools.selectMethod('get')
97
+ devtools.assertPayloadEditorNotVisible()
98
+ })
99
+
100
+ it('should show payload editor when PATCH method is selected', () => {
101
+ devtools.selectMethod('patch')
102
+ devtools.assertPayloadEditorVisible()
103
+ })
104
+ })
105
+
106
+ // ============================================
107
+ // UAT-004: Path Parameters Detection and URL Preview
108
+ // ACs: AC-PATH-01, AC-PATH-02, AC-PATH-03
109
+ // ============================================
110
+ describe('UAT-004: Path parameters detected and URL preview updates', () => {
111
+ beforeEach(() => {
112
+ // Visit endpoint with path param (e.g., /api/v1/customers/[id])
113
+ devtools.visitApiEndpoint('/v1/customers/%5Bid%5D') // URL-encoded [id]
114
+ })
115
+
116
+ it('should detect path parameters from endpoint pattern', () => {
117
+ cy.get('[data-cy="api-tester-path-params"]').should('exist')
118
+ cy.get('[data-cy="api-tester-path-param-id"]').should('exist')
119
+ })
120
+
121
+ it('should have labeled input field for path param', () => {
122
+ cy.get('[data-cy="api-tester-path-param-id-input"]').should('exist')
123
+ })
124
+
125
+ it('should update URL preview when path param value changes', () => {
126
+ // Initially URL preview should show [id] placeholder
127
+ devtools.assertUrlPreviewContains('/v1/customers/')
128
+
129
+ // Fill path param
130
+ devtools.fillPathParam('id', '12345')
131
+
132
+ // URL preview should now show the value
133
+ devtools.assertUrlPreviewContains('12345')
134
+ })
135
+ })
136
+
137
+ // ============================================
138
+ // UAT-005: Path Parameter Validation
139
+ // ACs: AC-PATH-04
140
+ // ============================================
141
+ describe('UAT-005: Path parameter validation (required params)', () => {
142
+ beforeEach(() => {
143
+ devtools.visitApiEndpoint('/v1/customers/%5Bid%5D')
144
+ })
145
+
146
+ it('should show "required" badge on required path params', () => {
147
+ cy.get('[data-cy="api-tester-path-param-id"]')
148
+ .should('contain', 'required')
149
+ })
150
+
151
+ it('should disable Send button when required path param is empty', () => {
152
+ // Path param should be empty by default
153
+ cy.get('[data-cy="api-tester-send-btn"]').should('be.disabled')
154
+ })
155
+
156
+ it('should enable Send button when required path param is filled', () => {
157
+ devtools.fillPathParam('id', '12345')
158
+ cy.get('[data-cy="api-tester-send-btn"]').should('not.be.disabled')
159
+ })
160
+ })
161
+
162
+ // ============================================
163
+ // UAT-006: Query Parameters Add/Remove/Update URL
164
+ // ACs: AC-QRY-01, AC-QRY-02, AC-QRY-03, AC-QRY-04
165
+ // ============================================
166
+ describe('UAT-006: Query params add/remove and URL updates', () => {
167
+ beforeEach(() => {
168
+ devtools.visitApiEndpoint('/v1/profile')
169
+ })
170
+
171
+ it('should have key-value inputs for query params', () => {
172
+ cy.get('[data-cy="api-tester-query-editor"]').should('exist')
173
+ cy.get('[data-cy="api-tester-query-add-btn"]').should('exist')
174
+ })
175
+
176
+ it('should add query param row when Add button clicked', () => {
177
+ cy.get('[data-cy="api-tester-query-add-btn"]').click()
178
+ cy.get('[data-cy="api-tester-query-row-0"]').should('exist')
179
+ })
180
+
181
+ it('should update URL preview when query param is added', () => {
182
+ cy.get('[data-cy="api-tester-query-add-btn"]').click()
183
+ cy.get('[data-cy="api-tester-query-row-0-key"]').type('limit')
184
+ cy.get('[data-cy="api-tester-query-row-0-value"]').type('10')
185
+
186
+ devtools.assertUrlPreviewContains('limit=10')
187
+ })
188
+
189
+ it('should URL-encode query param values', () => {
190
+ cy.get('[data-cy="api-tester-query-add-btn"]').click()
191
+ cy.get('[data-cy="api-tester-query-row-0-key"]').type('filter')
192
+ cy.get('[data-cy="api-tester-query-row-0-value"]').type('status eq active')
193
+
194
+ // URLSearchParams should encode spaces as +
195
+ devtools.assertUrlPreviewContains('filter=status')
196
+ })
197
+
198
+ it('should remove query param row when delete button clicked', () => {
199
+ cy.get('[data-cy="api-tester-query-add-btn"]').click()
200
+ cy.get('[data-cy="api-tester-query-row-0"]').should('exist')
201
+
202
+ cy.get('[data-cy="api-tester-query-row-0-delete"]').click()
203
+ cy.get('[data-cy="api-tester-query-row-0"]').should('not.exist')
204
+ })
205
+ })
206
+
207
+ // ============================================
208
+ // UAT-007: JSON Payload Editor Validation
209
+ // ACs: AC-BODY-01, AC-BODY-02, AC-BODY-03
210
+ // ============================================
211
+ describe('UAT-007: JSON payload editor validation', () => {
212
+ beforeEach(() => {
213
+ devtools.visitApiEndpoint('/v1/profile')
214
+ devtools.selectMethod('patch')
215
+ })
216
+
217
+ it('should show JSON textarea for POST/PATCH/PUT methods', () => {
218
+ devtools.assertPayloadEditorVisible()
219
+ cy.get('[data-cy="api-tester-payload-textarea"]').should('exist')
220
+ })
221
+
222
+ it('should show validation error for invalid JSON', () => {
223
+ devtools.fillPayload('{name: "test"}') // Invalid JSON (unquoted key)
224
+
225
+ devtools.assertPayloadErrorShown()
226
+ })
227
+
228
+ it('should NOT show error for valid JSON', () => {
229
+ devtools.fillPayload('{"name": "test"}')
230
+
231
+ cy.get('[data-cy="api-tester-payload-error"]').should('not.exist')
232
+ })
233
+
234
+ it('should disable Send button when JSON is invalid', () => {
235
+ devtools.fillPayload('{invalid}')
236
+
237
+ cy.get('[data-cy="api-tester-send-btn"]').should('be.disabled')
238
+ })
239
+ })
240
+
241
+ // ============================================
242
+ // UAT-008: Authentication Toggle Session/API Key
243
+ // ACs: AC-AUTH-01, AC-AUTH-04
244
+ // ============================================
245
+ describe('UAT-008: Authentication modes (session/API key)', () => {
246
+ beforeEach(() => {
247
+ devtools.visitApiEndpoint('/v1/profile')
248
+ })
249
+
250
+ it('should show authentication section', () => {
251
+ cy.get('[data-cy="api-tester-auth"]').should('exist')
252
+ cy.get('[data-cy="api-tester-auth-type"]').should('exist')
253
+ })
254
+
255
+ it('should have "Use current session" selected by default', () => {
256
+ cy.get('[data-cy="api-tester-auth-session"]')
257
+ .should('have.attr', 'data-state', 'checked')
258
+ })
259
+
260
+ it('should show API key input when "Use API key" is selected', () => {
261
+ // Initially API key input should not be visible
262
+ cy.get('[data-cy="api-tester-apikey-input"]').should('not.be.visible')
263
+
264
+ // Select API key option
265
+ devtools.selectAuthType('apiKey')
266
+
267
+ // API key input should now be visible
268
+ cy.get('[data-cy="api-tester-apikey-input"]').should('be.visible')
269
+ })
270
+
271
+ it('should hide API key input when switching back to session', () => {
272
+ devtools.selectAuthType('apiKey')
273
+ cy.get('[data-cy="api-tester-apikey-input"]').should('be.visible')
274
+
275
+ devtools.selectAuthType('session')
276
+ cy.get('[data-cy="api-tester-apikey-input"]').should('not.be.visible')
277
+ })
278
+ })
279
+
280
+ // ============================================
281
+ // UAT-009: Send Request and Display Response
282
+ // ACs: AC-EXEC-01, AC-EXEC-02, AC-RSP-01, AC-RSP-02, AC-RSP-04
283
+ // ============================================
284
+ describe('UAT-009: Send request and display response', () => {
285
+ beforeEach(() => {
286
+ devtools.visitApiEndpoint('/v1/profile')
287
+ })
288
+
289
+ it('should show idle state before sending request', () => {
290
+ cy.get('[data-cy="api-tester-response-idle"]').should('be.visible')
291
+ })
292
+
293
+ it('should execute request when Send button is clicked', () => {
294
+ devtools.clickSendRequest()
295
+
296
+ // Should show loading state
297
+ cy.get('[data-cy="api-tester-response-loading"]').should('be.visible')
298
+
299
+ // Wait for response
300
+ devtools.waitForResponse()
301
+ })
302
+
303
+ it('should display response status code with correct color', () => {
304
+ devtools.clickSendRequest()
305
+ devtools.waitForResponse()
306
+
307
+ // Status 200 should be visible
308
+ devtools.assertResponseStatus(200)
309
+
310
+ // Status badge should have green color (for 2xx)
311
+ cy.get('[data-cy="api-tester-response-status"]')
312
+ .should('have.class', 'bg-emerald-100')
313
+ })
314
+
315
+ it('should display response time in milliseconds', () => {
316
+ devtools.clickSendRequest()
317
+ devtools.waitForResponse()
318
+
319
+ devtools.assertResponseTimeVisible()
320
+ cy.get('[data-cy="api-tester-response-time"]')
321
+ .should('match', /\d+ms/)
322
+ })
323
+
324
+ it('should display formatted JSON body', () => {
325
+ devtools.clickSendRequest()
326
+ devtools.waitForResponse()
327
+
328
+ // Response body should be visible and formatted
329
+ cy.get('[data-cy="api-tester-response-body"]').should('be.visible')
330
+ cy.get('[data-cy="api-tester-response-body"]').should('contain', '{')
331
+ })
332
+ })
333
+
334
+ // ============================================
335
+ // UAT-010: Response Tabs (Body/Headers) and Status Colors
336
+ // ACs: AC-RSP-03, AC-RSP-06
337
+ // ============================================
338
+ describe('UAT-010: Response tabs and large response handling', () => {
339
+ beforeEach(() => {
340
+ devtools.visitApiEndpoint('/v1/profile')
341
+ devtools.clickSendRequest()
342
+ devtools.waitForResponse()
343
+ })
344
+
345
+ it('should have Body and Headers tabs', () => {
346
+ cy.get('[data-cy="api-tester-response-tab-body"]').should('exist')
347
+ cy.get('[data-cy="api-tester-response-tab-headers"]').should('exist')
348
+ })
349
+
350
+ it('should show body content by default', () => {
351
+ cy.get('[data-cy="api-tester-response-body"]').should('be.visible')
352
+ })
353
+
354
+ it('should switch to Headers tab when clicked', () => {
355
+ devtools.clickResponseHeadersTab()
356
+
357
+ cy.get('[data-cy="api-tester-response-headers"]').should('be.visible')
358
+ })
359
+
360
+ it('should display response headers as key-value pairs', () => {
361
+ devtools.clickResponseHeadersTab()
362
+
363
+ // Should show headers like "content-type: application/json"
364
+ cy.get('[data-cy="api-tester-response-headers"]').should('contain', ':')
365
+ })
366
+
367
+ it('should handle large responses with scrolling', () => {
368
+ // Response body should be in a ScrollArea
369
+ cy.get('[data-cy="api-tester-response-body"]')
370
+ .parent() // ScrollArea wrapper
371
+ .should('have.css', 'overflow', 'auto')
372
+ .or('have.css', 'overflow-y', 'auto')
373
+ })
374
+ })
375
+
376
+ // ============================================
377
+ // BONUS: Navigation Back to List
378
+ // AC: AC-NAV-03
379
+ // ============================================
380
+ describe('BONUS: Back navigation', () => {
381
+ it('should navigate back to list when back button is clicked', () => {
382
+ devtools.visitApiEndpoint('/v1/profile')
383
+
384
+ devtools.clickBackToList()
385
+
386
+ // Should be back at /devtools/api (no trailing path)
387
+ cy.url().should('eq', Cypress.config().baseUrl + '/devtools/api')
388
+ })
389
+ })
390
+ })
@@ -0,0 +1,275 @@
1
+ ---
2
+ feature: Customers Management - Member Role
3
+ priority: high
4
+ tags: [customers, member, permissions, read-only, security]
5
+ grepTags: [uat, feat-customers, role-member, security]
6
+ coverage: 7
7
+ ---
8
+
9
+ # Customers Management - Member Role (View Only - Restricted)
10
+
11
+ > Test suite for Member role customer permissions. Members can only READ customers - they CANNOT create, update, or delete. These tests verify proper UI 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 Customers dashboard
18
+ And the customers 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 Clientes
24
+ And la lista de clientes ha cargado exitosamente
25
+ ```
26
+
27
+ ---
28
+
29
+ ## @test CUST-MEMBER-001: View customer list
30
+
31
+ ### Metadata
32
+ - **Priority:** Critical
33
+ - **Type:** Smoke
34
+ - **Tags:** read, list, permissions
35
+ - **Grep:** `@smoke` `@critical`
36
+
37
+ ```gherkin:en
38
+ Scenario: Member can view the customers table
39
+
40
+ Given I am logged in as a Member
41
+ When I navigate to the Customers dashboard
42
+ Then the customers page should be visible
43
+ And the customers table should be displayed
44
+ ```
45
+
46
+ ```gherkin:es
47
+ Scenario: Member puede ver la tabla de clientes
48
+
49
+ Given estoy logueado como Member
50
+ When navego al dashboard de Clientes
51
+ Then la pagina de clientes deberia estar visible
52
+ And la tabla de clientes deberia mostrarse
53
+ ```
54
+
55
+ ### Expected Results
56
+ - Customers dashboard is accessible to Member role
57
+ - Customers table displays with data
58
+ - Read access is properly granted
59
+
60
+ ---
61
+
62
+ ## @test CUST-MEMBER-002: View customer details
63
+
64
+ ### Metadata
65
+ - **Priority:** High
66
+ - **Type:** Regression
67
+ - **Tags:** read, details, navigation
68
+
69
+ ```gherkin:en
70
+ Scenario: Member can view individual customer details
71
+
72
+ Given I am logged in as a Member
73
+ And there is at least one customer in the list
74
+ When I click on a customer row
75
+ Then I should be navigated to the customer detail page
76
+ And the URL should match /dashboard/customers/{id}
77
+ And the detail header should be visible
78
+ ```
79
+
80
+ ```gherkin:es
81
+ Scenario: Member puede ver detalles de un cliente
82
+
83
+ Given estoy logueado como Member
84
+ And existe al menos un cliente en la lista
85
+ When hago clic en una fila de cliente
86
+ Then deberia ser navegado a la pagina de detalle
87
+ And la URL deberia coincidir con /dashboard/customers/{id}
88
+ And el encabezado de detalle deberia estar visible
89
+ ```
90
+
91
+ ### Expected Results
92
+ - Customer rows are clickable for Members
93
+ - Detail page navigation works
94
+ - Customer information is visible
95
+ - Detail header displays correctly
96
+
97
+ ---
98
+
99
+ ## @test CUST-MEMBER-003: Edit button is hidden
100
+
101
+ ### Metadata
102
+ - **Priority:** High
103
+ - **Type:** Regression
104
+ - **Tags:** update, security, hidden-button
105
+ - **Grep:** `@security`
106
+
107
+ ```gherkin:en
108
+ Scenario: Edit button is hidden for Member role
109
+
110
+ Given I am logged in as a Member
111
+ And there is at least one customer in the list
112
+ When I click on a customer row to view details
113
+ Then I should see the customer information
114
+ But I should NOT see an "Edit" button
115
+ And the edit button should not exist in the DOM
116
+ ```
117
+
118
+ ```gherkin:es
119
+ Scenario: Boton editar oculto para rol Member
120
+
121
+ Given estoy logueado como Member
122
+ And existe al menos un cliente en la lista
123
+ When hago clic en una fila para ver detalles
124
+ Then deberia ver la informacion del cliente
125
+ But NO deberia ver un boton "Editar"
126
+ And el boton editar no deberia existir en el DOM
127
+ ```
128
+
129
+ ### Expected Results
130
+ - Customer information is visible
131
+ - Edit button is completely hidden (not just disabled)
132
+ - Edit button does not exist in DOM
133
+ - Security: No way to access edit functionality
134
+
135
+ ---
136
+
137
+ ## @test CUST-MEMBER-004: Create button is hidden
138
+
139
+ ### Metadata
140
+ - **Priority:** Critical
141
+ - **Type:** Smoke
142
+ - **Tags:** create, security, hidden-button
143
+ - **Grep:** `@smoke` `@critical` `@security`
144
+
145
+ ```gherkin:en
146
+ Scenario: Create button is hidden for Member role
147
+
148
+ Given I am logged in as a Member
149
+ When I navigate to the Customers list page
150
+ Then the customers page should be visible
151
+ But I should NOT see an "Add" button
152
+ And the create button should not exist in the DOM
153
+ ```
154
+
155
+ ```gherkin:es
156
+ Scenario: Boton crear oculto para rol Member
157
+
158
+ Given estoy logueado como Member
159
+ When navego a la pagina de lista de Clientes
160
+ Then la pagina de clientes deberia estar visible
161
+ But NO deberia ver un boton "Agregar"
162
+ And el boton crear no deberia existir en el DOM
163
+ ```
164
+
165
+ ### Expected Results
166
+ - Customers list page loads correctly
167
+ - Add/Create button is completely hidden
168
+ - Create button does not exist in DOM
169
+ - Security: No way to access create functionality
170
+
171
+ ---
172
+
173
+ ## @test CUST-MEMBER-005: No UI access to create form
174
+
175
+ ### Metadata
176
+ - **Priority:** Medium
177
+ - **Type:** Regression
178
+ - **Tags:** create, security, form-access
179
+
180
+ ```gherkin:en
181
+ Scenario: Member has no UI access to create form
182
+
183
+ Given I am logged in as a Member
184
+ When I am on the Customers list page
185
+ Then there should be no way to access the create form
186
+ And the "Add" button should not exist
187
+ ```
188
+
189
+ ```gherkin:es
190
+ Scenario: Member no tiene acceso UI al formulario de creacion
191
+
192
+ Given estoy logueado como Member
193
+ When estoy en la pagina de lista de Clientes
194
+ Then no deberia haber forma de acceder al formulario de creacion
195
+ And el boton "Agregar" no deberia existir
196
+ ```
197
+
198
+ ### Expected Results
199
+ - No UI element leads to create form
200
+ - Add button does not exist
201
+ - Create form is inaccessible through UI
202
+
203
+ ---
204
+
205
+ ## @test CUST-MEMBER-006: Delete buttons are hidden
206
+
207
+ ### Metadata
208
+ - **Priority:** Critical
209
+ - **Type:** Smoke
210
+ - **Tags:** delete, security, hidden-button
211
+ - **Grep:** `@smoke` `@critical` `@security`
212
+
213
+ ```gherkin:en
214
+ Scenario: Delete buttons are hidden in list view
215
+
216
+ Given I am logged in as a Member
217
+ When I am on the Customers list page
218
+ Then I should NOT see any delete action buttons
219
+ And no delete buttons should exist in table rows
220
+ ```
221
+
222
+ ```gherkin:es
223
+ Scenario: Botones eliminar ocultos en vista de lista
224
+
225
+ Given estoy logueado como Member
226
+ When estoy en la pagina de lista de Clientes
227
+ Then NO deberia ver ningun boton de accion eliminar
228
+ And no deberian existir botones eliminar en las filas
229
+ ```
230
+
231
+ ### Expected Results
232
+ - No delete buttons visible in list view
233
+ - Delete actions do not exist in table rows
234
+ - Security: No way to trigger delete from list
235
+
236
+ ---
237
+
238
+ ## @test CUST-MEMBER-007: No delete action in detail view
239
+
240
+ ### Metadata
241
+ - **Priority:** High
242
+ - **Type:** Regression
243
+ - **Tags:** delete, security, detail-view
244
+ - **Grep:** `@security`
245
+
246
+ ```gherkin:en
247
+ Scenario: Delete button is hidden in detail view
248
+
249
+ Given I am logged in as a Member
250
+ And there is at least one customer in the list
251
+ When I click on a customer row to view details
252
+ Then the detail page should load
253
+ And the detail header should be visible
254
+ But I should NOT see a "Delete" button
255
+ And the delete button should not exist in the DOM
256
+ ```
257
+
258
+ ```gherkin:es
259
+ Scenario: Boton eliminar oculto en vista de detalle
260
+
261
+ Given estoy logueado como Member
262
+ And existe al menos un cliente en la lista
263
+ When hago clic en una fila para ver detalles
264
+ Then la pagina de detalle deberia cargar
265
+ And el encabezado de detalle deberia estar visible
266
+ But NO deberia ver un boton "Eliminar"
267
+ And el boton eliminar no deberia existir en el DOM
268
+ ```
269
+
270
+ ### Expected Results
271
+ - Detail page loads correctly
272
+ - Detail header is visible
273
+ - Delete button is completely hidden
274
+ - Delete button does not exist in DOM
275
+ - Security: No way to trigger delete from detail view