@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,447 @@
1
+ /// <reference types="cypress" />
2
+
3
+ /**
4
+ * Scheduled Actions API - DevTools Endpoint Tests
5
+ *
6
+ * Tests for /api/v1/devtools/scheduled-actions endpoint that:
7
+ * - Validates authentication (requires superadmin/developer API key)
8
+ * - Supports status filtering (pending, running, completed, failed)
9
+ * - Supports action_type filtering
10
+ * - Returns paginated results
11
+ * - Includes registered action types in meta
12
+ *
13
+ * Session: 2025-12-30-scheduled-actions-v1
14
+ * Phase: 9 (api-tester)
15
+ *
16
+ * AC Coverage:
17
+ * - AC-27: Filter by status
18
+ * - AC-28: Filter by action_type
19
+ * - AC-29: Combined filters
20
+ * - AC-30: Invalid filter handling
21
+ * - AC-31: Pagination with filters
22
+ * - AC-32: Meta includes registeredActionTypes
23
+ */
24
+
25
+ import * as allure from 'allure-cypress'
26
+
27
+ describe('Scheduled Actions API - DevTools Endpoint', {
28
+ tags: ['@api', '@feat-scheduled-actions', '@regression']
29
+ }, () => {
30
+ const BASE_URL = Cypress.config('baseUrl') || 'http://localhost:5173'
31
+ const DEVTOOLS_ENDPOINT = `${BASE_URL}/api/v1/devtools/scheduled-actions`
32
+
33
+ // API key for superadmin/developer access
34
+ const API_KEY = Cypress.env('SUPERADMIN_API_KEY') || 'test_api_key_for_testing_purposes_only_not_a_real_secret_key_abc123'
35
+
36
+ beforeEach(() => {
37
+ allure.epic('API')
38
+ allure.feature('Scheduled Actions')
39
+ allure.story('DevTools Endpoint')
40
+ })
41
+
42
+ // ============================================================
43
+ // TEST 1: Authentication
44
+ // ============================================================
45
+ describe('Authentication', () => {
46
+ it('SA_DEVTOOLS_AUTH_001: Should return 401 without API key', () => {
47
+ allure.severity('critical')
48
+
49
+ cy.request({
50
+ method: 'GET',
51
+ url: DEVTOOLS_ENDPOINT,
52
+ failOnStatusCode: false
53
+ }).then((response) => {
54
+ expect(response.status).to.eq(401)
55
+ expect(response.body.success).to.be.false
56
+ expect(response.body.error.code).to.eq('AUTHENTICATION_REQUIRED')
57
+
58
+ cy.log('Returns 401 without API key')
59
+ })
60
+ })
61
+
62
+ it('SA_DEVTOOLS_AUTH_002: Should return 200 with valid API key', () => {
63
+ allure.severity('critical')
64
+
65
+ cy.request({
66
+ method: 'GET',
67
+ url: DEVTOOLS_ENDPOINT,
68
+ headers: {
69
+ 'x-api-key': API_KEY
70
+ },
71
+ failOnStatusCode: false
72
+ }).then((response) => {
73
+ expect(response.status).to.eq(200)
74
+ expect(response.body.success).to.be.true
75
+
76
+ cy.log('Returns 200 with valid API key')
77
+ })
78
+ })
79
+ })
80
+
81
+ // ============================================================
82
+ // TEST 2: Status Filtering (AC-27)
83
+ // ============================================================
84
+ describe('Status Filtering', () => {
85
+ it('SA_DEVTOOLS_001: Should filter by status=pending', () => {
86
+ allure.severity('critical')
87
+ allure.tag('@ac-27')
88
+
89
+ cy.request({
90
+ method: 'GET',
91
+ url: `${DEVTOOLS_ENDPOINT}?status=pending`,
92
+ headers: {
93
+ 'x-api-key': API_KEY
94
+ }
95
+ }).then((response) => {
96
+ expect(response.status).to.eq(200)
97
+ expect(response.body.success).to.be.true
98
+ expect(response.body.data).to.have.property('actions')
99
+ expect(response.body.data.actions).to.be.an('array')
100
+
101
+ // All returned actions should have status=pending
102
+ response.body.data.actions.forEach((action: { status: string }) => {
103
+ expect(action.status).to.eq('pending')
104
+ })
105
+
106
+ cy.log(`Found ${response.body.data.actions.length} pending actions`)
107
+ })
108
+ })
109
+
110
+ it('SA_DEVTOOLS_002: Should filter by status=completed', () => {
111
+ allure.severity('critical')
112
+ allure.tag('@ac-27')
113
+
114
+ cy.request({
115
+ method: 'GET',
116
+ url: `${DEVTOOLS_ENDPOINT}?status=completed`,
117
+ headers: {
118
+ 'x-api-key': API_KEY
119
+ }
120
+ }).then((response) => {
121
+ expect(response.status).to.eq(200)
122
+ expect(response.body.success).to.be.true
123
+
124
+ // All returned actions should have status=completed
125
+ response.body.data.actions.forEach((action: { status: string }) => {
126
+ expect(action.status).to.eq('completed')
127
+ })
128
+
129
+ cy.log(`Found ${response.body.data.actions.length} completed actions`)
130
+ })
131
+ })
132
+
133
+ it('SA_DEVTOOLS_002b: Should filter by status=failed', () => {
134
+ allure.severity('normal')
135
+ allure.tag('@ac-27')
136
+
137
+ cy.request({
138
+ method: 'GET',
139
+ url: `${DEVTOOLS_ENDPOINT}?status=failed`,
140
+ headers: {
141
+ 'x-api-key': API_KEY
142
+ }
143
+ }).then((response) => {
144
+ expect(response.status).to.eq(200)
145
+ expect(response.body.success).to.be.true
146
+
147
+ // All returned actions should have status=failed
148
+ response.body.data.actions.forEach((action: { status: string }) => {
149
+ expect(action.status).to.eq('failed')
150
+ })
151
+
152
+ cy.log(`Found ${response.body.data.actions.length} failed actions`)
153
+ })
154
+ })
155
+
156
+ it('SA_DEVTOOLS_002c: Should filter by status=running', () => {
157
+ allure.severity('normal')
158
+ allure.tag('@ac-27')
159
+
160
+ cy.request({
161
+ method: 'GET',
162
+ url: `${DEVTOOLS_ENDPOINT}?status=running`,
163
+ headers: {
164
+ 'x-api-key': API_KEY
165
+ }
166
+ }).then((response) => {
167
+ expect(response.status).to.eq(200)
168
+ expect(response.body.success).to.be.true
169
+
170
+ // All returned actions should have status=running
171
+ response.body.data.actions.forEach((action: { status: string }) => {
172
+ expect(action.status).to.eq('running')
173
+ })
174
+
175
+ cy.log(`Found ${response.body.data.actions.length} running actions`)
176
+ })
177
+ })
178
+ })
179
+
180
+ // ============================================================
181
+ // TEST 3: Action Type Filtering (AC-28)
182
+ // ============================================================
183
+ describe('Action Type Filtering', () => {
184
+ it('SA_DEVTOOLS_003: Should filter by action_type=webhook:send', () => {
185
+ allure.severity('critical')
186
+ allure.tag('@ac-28')
187
+
188
+ cy.request({
189
+ method: 'GET',
190
+ url: `${DEVTOOLS_ENDPOINT}?action_type=webhook:send`,
191
+ headers: {
192
+ 'x-api-key': API_KEY
193
+ }
194
+ }).then((response) => {
195
+ expect(response.status).to.eq(200)
196
+ expect(response.body.success).to.be.true
197
+
198
+ // All returned actions should have actionType=webhook:send
199
+ response.body.data.actions.forEach((action: { actionType: string }) => {
200
+ expect(action.actionType).to.eq('webhook:send')
201
+ })
202
+
203
+ cy.log(`Found ${response.body.data.actions.length} webhook:send actions`)
204
+ })
205
+ })
206
+
207
+ it('SA_DEVTOOLS_003b: Should filter by action_type=billing:check-renewals', () => {
208
+ allure.severity('normal')
209
+ allure.tag('@ac-28')
210
+
211
+ cy.request({
212
+ method: 'GET',
213
+ url: `${DEVTOOLS_ENDPOINT}?action_type=billing:check-renewals`,
214
+ headers: {
215
+ 'x-api-key': API_KEY
216
+ }
217
+ }).then((response) => {
218
+ expect(response.status).to.eq(200)
219
+ expect(response.body.success).to.be.true
220
+
221
+ // All returned actions should have actionType=billing:check-renewals
222
+ response.body.data.actions.forEach((action: { actionType: string }) => {
223
+ expect(action.actionType).to.eq('billing:check-renewals')
224
+ })
225
+
226
+ cy.log(`Found ${response.body.data.actions.length} billing:check-renewals actions`)
227
+ })
228
+ })
229
+ })
230
+
231
+ // ============================================================
232
+ // TEST 4: Combined Filters (AC-29)
233
+ // ============================================================
234
+ describe('Combined Filters', () => {
235
+ it('SA_DEVTOOLS_004: Should filter by status AND action_type together', () => {
236
+ allure.severity('critical')
237
+ allure.tag('@ac-29')
238
+
239
+ cy.request({
240
+ method: 'GET',
241
+ url: `${DEVTOOLS_ENDPOINT}?status=completed&action_type=webhook:send`,
242
+ headers: {
243
+ 'x-api-key': API_KEY
244
+ }
245
+ }).then((response) => {
246
+ expect(response.status).to.eq(200)
247
+ expect(response.body.success).to.be.true
248
+
249
+ // All returned actions should match both criteria
250
+ response.body.data.actions.forEach((action: { status: string; actionType: string }) => {
251
+ expect(action.status).to.eq('completed')
252
+ expect(action.actionType).to.eq('webhook:send')
253
+ })
254
+
255
+ cy.log(`Found ${response.body.data.actions.length} completed webhook:send actions`)
256
+ })
257
+ })
258
+ })
259
+
260
+ // ============================================================
261
+ // TEST 5: Invalid Filter Handling (AC-30)
262
+ // ============================================================
263
+ describe('Invalid Filter Handling', () => {
264
+ it('SA_DEVTOOLS_005: Should return empty array for non-existent action_type', () => {
265
+ allure.severity('normal')
266
+ allure.tag('@ac-30')
267
+
268
+ cy.request({
269
+ method: 'GET',
270
+ url: `${DEVTOOLS_ENDPOINT}?action_type=non-existent:action`,
271
+ headers: {
272
+ 'x-api-key': API_KEY
273
+ }
274
+ }).then((response) => {
275
+ expect(response.status).to.eq(200)
276
+ expect(response.body.success).to.be.true
277
+ expect(response.body.data.actions).to.be.an('array')
278
+ expect(response.body.data.actions.length).to.eq(0)
279
+ expect(response.body.data.pagination.total).to.eq(0)
280
+
281
+ cy.log('Returns empty array for non-existent action type')
282
+ })
283
+ })
284
+
285
+ it('SA_DEVTOOLS_005b: Should handle invalid status gracefully', () => {
286
+ allure.severity('normal')
287
+ allure.tag('@ac-30')
288
+
289
+ cy.request({
290
+ method: 'GET',
291
+ url: `${DEVTOOLS_ENDPOINT}?status=invalid_status`,
292
+ headers: {
293
+ 'x-api-key': API_KEY
294
+ }
295
+ }).then((response) => {
296
+ // Should either return empty or treat as no filter
297
+ expect(response.status).to.eq(200)
298
+ expect(response.body.success).to.be.true
299
+
300
+ cy.log('Handles invalid status gracefully')
301
+ })
302
+ })
303
+ })
304
+
305
+ // ============================================================
306
+ // TEST 6: Pagination with Filters (AC-31)
307
+ // ============================================================
308
+ describe('Pagination with Filters', () => {
309
+ it('SA_DEVTOOLS_006: Should paginate filtered results correctly', () => {
310
+ allure.severity('critical')
311
+ allure.tag('@ac-31')
312
+
313
+ cy.request({
314
+ method: 'GET',
315
+ url: `${DEVTOOLS_ENDPOINT}?status=completed&limit=5&page=1`,
316
+ headers: {
317
+ 'x-api-key': API_KEY
318
+ }
319
+ }).then((response) => {
320
+ expect(response.status).to.eq(200)
321
+ expect(response.body.success).to.be.true
322
+ expect(response.body.data).to.have.property('pagination')
323
+ expect(response.body.data.pagination).to.have.property('total')
324
+ expect(response.body.data.pagination).to.have.property('page')
325
+ expect(response.body.data.pagination).to.have.property('limit')
326
+ expect(response.body.data.pagination).to.have.property('totalPages')
327
+
328
+ expect(response.body.data.pagination.page).to.eq(1)
329
+ expect(response.body.data.pagination.limit).to.eq(5)
330
+ expect(response.body.data.actions.length).to.be.at.most(5)
331
+
332
+ cy.log(`Page 1: ${response.body.data.actions.length} actions`)
333
+ cy.log(`Total: ${response.body.data.pagination.total}`)
334
+ cy.log(`Total Pages: ${response.body.data.pagination.totalPages}`)
335
+ })
336
+ })
337
+
338
+ it('SA_DEVTOOLS_006b: Should navigate to page 2 with filters', () => {
339
+ allure.severity('normal')
340
+ allure.tag('@ac-31')
341
+
342
+ // First, get page 1 to see if there are enough items
343
+ cy.request({
344
+ method: 'GET',
345
+ url: `${DEVTOOLS_ENDPOINT}?limit=5&page=1`,
346
+ headers: {
347
+ 'x-api-key': API_KEY
348
+ }
349
+ }).then((response) => {
350
+ expect(response.status).to.eq(200)
351
+ const totalPages = response.body.data.pagination.totalPages
352
+
353
+ if (totalPages >= 2) {
354
+ // Request page 2
355
+ cy.request({
356
+ method: 'GET',
357
+ url: `${DEVTOOLS_ENDPOINT}?limit=5&page=2`,
358
+ headers: {
359
+ 'x-api-key': API_KEY
360
+ }
361
+ }).then((page2Response) => {
362
+ expect(page2Response.status).to.eq(200)
363
+ expect(page2Response.body.data.pagination.page).to.eq(2)
364
+
365
+ cy.log(`Page 2: ${page2Response.body.data.actions.length} actions`)
366
+ })
367
+ } else {
368
+ cy.log('Not enough data for page 2 test - only 1 page exists')
369
+ }
370
+ })
371
+ })
372
+ })
373
+
374
+ // ============================================================
375
+ // TEST 7: Response Meta (AC-32)
376
+ // ============================================================
377
+ describe('Response Meta', () => {
378
+ it('SA_DEVTOOLS_007: Should include registeredActionTypes in meta', () => {
379
+ allure.severity('critical')
380
+ allure.tag('@ac-32')
381
+
382
+ cy.request({
383
+ method: 'GET',
384
+ url: DEVTOOLS_ENDPOINT,
385
+ headers: {
386
+ 'x-api-key': API_KEY
387
+ }
388
+ }).then((response) => {
389
+ expect(response.status).to.eq(200)
390
+ expect(response.body.success).to.be.true
391
+ expect(response.body.data).to.have.property('meta')
392
+ expect(response.body.data.meta).to.have.property('registeredActionTypes')
393
+ expect(response.body.data.meta.registeredActionTypes).to.be.an('array')
394
+
395
+ // Should include known action types
396
+ const actionTypes = response.body.data.meta.registeredActionTypes
397
+ expect(actionTypes).to.include('webhook:send')
398
+ expect(actionTypes).to.include('billing:check-renewals')
399
+
400
+ cy.log(`Registered action types: ${actionTypes.join(', ')}`)
401
+ })
402
+ })
403
+ })
404
+
405
+ // ============================================================
406
+ // TEST 8: Response Structure
407
+ // ============================================================
408
+ describe('Response Structure', () => {
409
+ it('SA_DEVTOOLS_008: Should return correct action structure', () => {
410
+ allure.severity('critical')
411
+
412
+ cy.request({
413
+ method: 'GET',
414
+ url: `${DEVTOOLS_ENDPOINT}?limit=1`,
415
+ headers: {
416
+ 'x-api-key': API_KEY
417
+ }
418
+ }).then((response) => {
419
+ expect(response.status).to.eq(200)
420
+ expect(response.body.success).to.be.true
421
+
422
+ if (response.body.data.actions.length > 0) {
423
+ const action = response.body.data.actions[0]
424
+
425
+ // Validate action structure
426
+ expect(action).to.have.property('id')
427
+ expect(action).to.have.property('actionType')
428
+ expect(action).to.have.property('status')
429
+ expect(action).to.have.property('payload')
430
+ expect(action).to.have.property('teamId')
431
+ expect(action).to.have.property('scheduledAt')
432
+ expect(action).to.have.property('createdAt')
433
+ expect(action).to.have.property('updatedAt')
434
+ expect(action).to.have.property('attempts')
435
+ expect(action).to.have.property('recurringInterval')
436
+
437
+ cy.log('Action structure validated')
438
+ cy.log(`Action ID: ${action.id}`)
439
+ cy.log(`Type: ${action.actionType}`)
440
+ cy.log(`Status: ${action.status}`)
441
+ } else {
442
+ cy.log('No actions found to validate structure')
443
+ }
444
+ })
445
+ })
446
+ })
447
+ })