@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,116 @@
1
+ /// <reference types="cypress" />
2
+
3
+ import * as allure from 'allure-cypress'
4
+
5
+ import { DevKeyringPOM } from '../../../src/components/DevKeyringPOM'
6
+ import { DEFAULT_THEME_USERS } from '../../../src/session-helpers'
7
+
8
+ describe('Authentication - DevKeyring Flow', {
9
+ tags: ['@uat', '@feat-auth', '@smoke', '@regression']
10
+ }, () => {
11
+ const devKeyring = DevKeyringPOM.create()
12
+ const users = DEFAULT_THEME_USERS
13
+
14
+ beforeEach(() => {
15
+ allure.epic('UAT')
16
+ allure.feature('Authentication')
17
+ allure.story('DevKeyring Login')
18
+ // Clear cookies and localStorage to ensure fresh state
19
+ cy.clearCookies()
20
+ cy.clearLocalStorage()
21
+ })
22
+
23
+ describe('LOGIN_001: Owner Login via DevKeyring', { tags: '@smoke' }, () => {
24
+ it('should login as Owner and access dashboard', { tags: '@smoke' }, () => {
25
+ allure.severity('critical')
26
+
27
+ // 1. Visit login page
28
+ cy.visit('/login')
29
+
30
+ // 2. Validate DevKeyring is visible
31
+ devKeyring.validateVisible()
32
+
33
+ // 3. Login as Owner using email
34
+ devKeyring.quickLoginByEmail(users.OWNER)
35
+
36
+ // 4. Validate dashboard access
37
+ cy.url().should('include', '/dashboard')
38
+ cy.get('[data-cy="dashboard-container"]').should('be.visible')
39
+
40
+ cy.log(`✅ Owner login successful (${users.OWNER})`)
41
+ })
42
+ })
43
+
44
+ describe('LOGIN_002: Member Login via DevKeyring', { tags: '@smoke' }, () => {
45
+ it('should login as Member and access dashboard', { tags: '@smoke' }, () => {
46
+ allure.severity('critical')
47
+
48
+ // 1. Visit login page
49
+ cy.visit('/login')
50
+
51
+ // 2. Validate DevKeyring is visible
52
+ devKeyring.validateVisible()
53
+
54
+ // 3. Login as Member using email
55
+ devKeyring.quickLoginByEmail(users.MEMBER)
56
+
57
+ // 4. Validate dashboard access
58
+ cy.url().should('include', '/dashboard')
59
+ cy.get('[data-cy="dashboard-container"]').should('be.visible')
60
+
61
+ cy.log(`✅ Member login successful (${users.MEMBER})`)
62
+ })
63
+ })
64
+
65
+ describe('LOGIN_003: Admin Login via DevKeyring', () => {
66
+ it('should login as Admin and access dashboard', () => {
67
+ // 1. Visit login page
68
+ cy.visit('/login')
69
+
70
+ // 2. Validate DevKeyring is visible
71
+ devKeyring.validateVisible()
72
+
73
+ // 3. Login as Admin using email
74
+ devKeyring.quickLoginByEmail(users.ADMIN)
75
+
76
+ // 4. Validate dashboard access
77
+ cy.url().should('include', '/dashboard')
78
+ cy.get('[data-cy="dashboard-container"]').should('be.visible')
79
+
80
+ cy.log(`✅ Admin login successful (${users.ADMIN})`)
81
+ })
82
+ })
83
+
84
+ describe('LOGOUT_001: User Logout Flow', () => {
85
+ it('should logout successfully and redirect to login', () => {
86
+ // Set desktop viewport to show TopNavbar (requires lg: 1024px+)
87
+ cy.viewport(1280, 800)
88
+
89
+ // 1. Login first as Owner
90
+ cy.visit('/login')
91
+ devKeyring.quickLoginByEmail(users.OWNER)
92
+
93
+ // Wait for dashboard to fully load
94
+ cy.url().should('include', '/dashboard')
95
+ cy.get('[data-cy="dashboard-container"]').should('be.visible')
96
+
97
+ // Wait for user menu to be available (session loaded)
98
+ // TopNavbar uses useAuth() which has loading state
99
+ cy.get('[data-cy="topnav-user-menu-trigger"]', { timeout: 15000 }).should('be.visible')
100
+
101
+ // 2. Logout via user menu
102
+ cy.get('[data-cy="topnav-user-menu-trigger"]').click()
103
+ cy.get('[data-cy="topnav-menu-signOut"]').should('be.visible').click()
104
+
105
+ // 3. Validate redirected to login and DevKeyring is visible again
106
+ cy.url().should('include', '/login')
107
+ devKeyring.validateVisible()
108
+
109
+ cy.log('✅ Logout successful')
110
+ })
111
+ })
112
+
113
+ after(() => {
114
+ cy.log('✅ Authentication tests completed')
115
+ })
116
+ })
@@ -0,0 +1,289 @@
1
+ ---
2
+ feature: Password Reset Flow
3
+ priority: critical
4
+ tags: [auth, password-reset, security, user-flow]
5
+ grepTags: [uat, feat-auth, password-reset]
6
+ coverage: 8
7
+ ---
8
+
9
+ # Password Reset Flow
10
+
11
+ > Tests for the password reset flow including page access, form validation, submission, and error handling. Actual email delivery is not tested as it requires external service integration.
12
+
13
+ ## @test PWD-RESET-001: Access Password Reset Page
14
+
15
+ ### Metadata
16
+ - **Priority:** Critical
17
+ - **Type:** Smoke
18
+ - **Tags:** password-reset, navigation
19
+ - **Grep:** `@smoke`
20
+
21
+ ```gherkin:en
22
+ Scenario: Access password reset page from login
23
+
24
+ Given I am on the login page
25
+ When I click on the forgot password link
26
+ Then I should be on /forgot-password
27
+ And the password reset form should be visible
28
+ And the email input should be visible
29
+ And the submit button should be visible
30
+ ```
31
+
32
+ ```gherkin:es
33
+ Scenario: Acceder a pagina de reset de password desde login
34
+
35
+ Given estoy en la pagina de login
36
+ When hago click en el enlace de olvide mi password
37
+ Then deberia estar en /forgot-password
38
+ And el formulario de reset deberia estar visible
39
+ And el input de email deberia estar visible
40
+ And el boton de enviar deberia estar visible
41
+ ```
42
+
43
+ ### Expected Results
44
+ - Forgot password link works
45
+ - Password reset page loads
46
+ - All form elements visible
47
+
48
+ ---
49
+
50
+ ## @test PWD-RESET-002: Direct URL Access
51
+
52
+ ### Metadata
53
+ - **Priority:** Normal
54
+ - **Type:** Smoke
55
+ - **Tags:** password-reset, direct-access
56
+ - **Grep:** `@smoke`
57
+
58
+ ```gherkin:en
59
+ Scenario: Access password reset page directly via URL
60
+
61
+ Given I visit /forgot-password directly
62
+ Then the password reset container should be visible
63
+ And the email input should be visible
64
+ ```
65
+
66
+ ```gherkin:es
67
+ Scenario: Acceder a pagina de reset directamente via URL
68
+
69
+ Given visito /forgot-password directamente
70
+ Then el contenedor de reset deberia estar visible
71
+ And el input de email deberia estar visible
72
+ ```
73
+
74
+ ### Expected Results
75
+ - Direct URL access works
76
+ - No authentication required
77
+
78
+ ---
79
+
80
+ ## @test PWD-RESET-003: Submit Valid Email
81
+
82
+ ### Metadata
83
+ - **Priority:** Critical
84
+ - **Type:** Smoke
85
+ - **Tags:** password-reset, submit
86
+ - **Grep:** `@smoke`
87
+
88
+ ```gherkin:en
89
+ Scenario: Submit password reset with valid email format
90
+
91
+ Given I am on the password reset page
92
+ When I enter a valid email format (user@example.com)
93
+ And I click the submit button
94
+ Then I should see a success message
95
+ ```
96
+
97
+ ```gherkin:es
98
+ Scenario: Enviar reset de password con email valido
99
+
100
+ Given estoy en la pagina de reset de password
101
+ When ingreso un email con formato valido (user@example.com)
102
+ And hago click en el boton de enviar
103
+ Then deberia ver un mensaje de exito
104
+ ```
105
+
106
+ ### Expected Results
107
+ - Form submits successfully
108
+ - Success message displayed
109
+ - No email enumeration (same message for existing/non-existing)
110
+
111
+ ---
112
+
113
+ ## @test PWD-RESET-004: Validate Empty Email
114
+
115
+ ### Metadata
116
+ - **Priority:** High
117
+ - **Type:** Validation
118
+ - **Tags:** password-reset, validation, empty
119
+
120
+ ```gherkin:en
121
+ Scenario: Show error for empty email field
122
+
123
+ Given I am on the password reset page
124
+ When I click submit without entering an email
125
+ Then I should see a required field error
126
+ ```
127
+
128
+ ```gherkin:es
129
+ Scenario: Mostrar error para campo email vacio
130
+
131
+ Given estoy en la pagina de reset de password
132
+ When hago click en enviar sin ingresar email
133
+ Then deberia ver un error de campo requerido
134
+ ```
135
+
136
+ ### Expected Results
137
+ - Validation error displayed
138
+ - Form not submitted
139
+
140
+ ---
141
+
142
+ ## @test PWD-RESET-005: Validate Invalid Email Format
143
+
144
+ ### Metadata
145
+ - **Priority:** High
146
+ - **Type:** Validation
147
+ - **Tags:** password-reset, validation, format
148
+
149
+ ```gherkin:en
150
+ Scenario: Show error for invalid email format
151
+
152
+ Given I am on the password reset page
153
+ When I enter an invalid email format (not-an-email)
154
+ And I click the submit button
155
+ Then I should see an invalid email error
156
+ ```
157
+
158
+ ```gherkin:es
159
+ Scenario: Mostrar error para formato de email invalido
160
+
161
+ Given estoy en la pagina de reset de password
162
+ When ingreso un formato de email invalido (not-an-email)
163
+ And hago click en el boton de enviar
164
+ Then deberia ver un error de email invalido
165
+ ```
166
+
167
+ ### Expected Results
168
+ - Format validation works
169
+ - Clear error message
170
+
171
+ ---
172
+
173
+ ## @test PWD-RESET-006: Back to Login Link
174
+
175
+ ### Metadata
176
+ - **Priority:** Normal
177
+ - **Type:** Navigation
178
+ - **Tags:** password-reset, navigation
179
+
180
+ ```gherkin:en
181
+ Scenario: Navigate back to login page
182
+
183
+ Given I am on the password reset page
184
+ When I click the back to login link
185
+ Then I should be on the login page
186
+ ```
187
+
188
+ ```gherkin:es
189
+ Scenario: Navegar de vuelta a pagina de login
190
+
191
+ Given estoy en la pagina de reset de password
192
+ When hago click en el enlace de volver a login
193
+ Then deberia estar en la pagina de login
194
+ ```
195
+
196
+ ### Expected Results
197
+ - Back link works
198
+ - Returns to login page
199
+
200
+ ---
201
+
202
+ ## @test PWD-RESET-007: Submit with Known Test Email
203
+
204
+ ### Metadata
205
+ - **Priority:** High
206
+ - **Type:** Regression
207
+ - **Tags:** password-reset, existing-user
208
+
209
+ ```gherkin:en
210
+ Scenario: Handle submission with existing user email
211
+
212
+ Given I am on the password reset page
213
+ When I enter a known test email (carlos.mendoza@nextspark.dev)
214
+ And I click the submit button
215
+ Then I should see a success message
216
+ ```
217
+
218
+ ```gherkin:es
219
+ Scenario: Manejar envio con email de usuario existente
220
+
221
+ Given estoy en la pagina de reset de password
222
+ When ingreso un email de prueba conocido (carlos.mendoza@nextspark.dev)
223
+ And hago click en el boton de enviar
224
+ Then deberia ver un mensaje de exito
225
+ ```
226
+
227
+ ### Expected Results
228
+ - Same success message as non-existing email
229
+ - No email enumeration vulnerability
230
+
231
+ ---
232
+
233
+ ## @test PWD-RESET-008: Form Keyboard Accessibility
234
+
235
+ ### Metadata
236
+ - **Priority:** Normal
237
+ - **Type:** Accessibility
238
+ - **Tags:** password-reset, keyboard, a11y
239
+
240
+ ```gherkin:en
241
+ Scenario: Submit form with Enter key
242
+
243
+ Given I am on the password reset page
244
+ When I enter an email and press Enter
245
+ Then the form should be submitted
246
+ ```
247
+
248
+ ```gherkin:es
249
+ Scenario: Enviar formulario con tecla Enter
250
+
251
+ Given estoy en la pagina de reset de password
252
+ When ingreso un email y presiono Enter
253
+ Then el formulario deberia ser enviado
254
+ ```
255
+
256
+ ### Expected Results
257
+ - Enter key submits form
258
+ - Keyboard navigation works
259
+
260
+ ---
261
+
262
+ ## UI Elements
263
+
264
+ | Element | Selector | Description |
265
+ |---------|----------|-------------|
266
+ | Forgot Password Link | `[data-cy="login-forgot-password"]` | Link on login page |
267
+ | Form | `[data-cy="forgot-password-form"]` | Password reset form |
268
+ | Email Input | `[data-cy="forgot-password-email"]` | Email input field |
269
+ | Submit Button | `[data-cy="forgot-password-submit"]` | Submit button |
270
+ | Success Message | `[data-cy="forgot-password-success"]` | Success message |
271
+ | Error Message | `[data-cy="forgot-password-error"]` | Error message |
272
+ | Back to Login | `[data-cy="forgot-password-back"]` | Back to login link |
273
+
274
+ > Note: Tests use `AuthPOM` from `src/core/AuthPOM.ts` which loads selectors from `fixtures/selectors/auth.json`
275
+
276
+ ---
277
+
278
+ ## Summary
279
+
280
+ | Test ID | Block | Description | Tags |
281
+ |---------|-------|-------------|------|
282
+ | PWD-RESET-001 | Access | Page access from login | `@smoke` |
283
+ | PWD-RESET-002 | Access | Direct URL access | `@smoke` |
284
+ | PWD-RESET-003 | Submit | Submit valid email | `@smoke` |
285
+ | PWD-RESET-004 | Validation | Empty email error | |
286
+ | PWD-RESET-005 | Validation | Invalid format error | |
287
+ | PWD-RESET-006 | Navigation | Back to login | |
288
+ | PWD-RESET-007 | Submit | Existing user email | |
289
+ | PWD-RESET-008 | A11y | Keyboard accessibility | |
@@ -0,0 +1,200 @@
1
+ /// <reference types="cypress" />
2
+
3
+ /**
4
+ * Password Reset Flow Tests
5
+ *
6
+ * Tests the complete password reset flow:
7
+ * - Request password reset link
8
+ * - Validate form fields
9
+ * - Handle errors (invalid email, rate limiting)
10
+ * - Success message display
11
+ *
12
+ * Note: Actual email delivery and token validation are not tested here
13
+ * as they require external email service integration.
14
+ * Tests verify up to the point of email send request.
15
+ *
16
+ * Tags: @uat, @feat-auth, @password-reset
17
+ */
18
+
19
+ import * as allure from 'allure-cypress'
20
+
21
+ import { AuthPOM } from '../../../src/core/AuthPOM'
22
+
23
+ describe('Authentication - Password Reset Flow', {
24
+ tags: ['@uat', '@feat-auth', '@password-reset']
25
+ }, () => {
26
+ const auth = new AuthPOM()
27
+
28
+ beforeEach(() => {
29
+ allure.epic('Authentication')
30
+ allure.feature('Password Reset')
31
+ // Clear any existing session
32
+ cy.clearCookies()
33
+ cy.clearLocalStorage()
34
+ })
35
+
36
+ describe('PWD-RESET-001: Access Password Reset Page', { tags: '@smoke' }, () => {
37
+ it('should access password reset page from login', { tags: '@smoke' }, () => {
38
+ allure.severity('critical')
39
+ allure.story('Page Access')
40
+
41
+ // 1. Visit login page
42
+ auth.visitLogin()
43
+
44
+ // 2. Show email form (forgot password link is inside email form section)
45
+ auth.showEmailLogin()
46
+ auth.waitForLoginForm()
47
+
48
+ // 3. Click on forgot password link
49
+ auth.clickForgotPassword()
50
+
51
+ // 4. Validate password reset page
52
+ cy.url().should('include', '/forgot-password')
53
+ cy.get(auth.selectors.forgotPasswordForm).should('be.visible')
54
+ cy.get(auth.selectors.forgotPasswordEmail).should('be.visible')
55
+ cy.get(auth.selectors.forgotPasswordSubmit).should('be.visible')
56
+
57
+ cy.log('✅ Password reset page accessible')
58
+ })
59
+ })
60
+
61
+ describe('PWD-RESET-002: Direct URL Access', { tags: '@smoke' }, () => {
62
+ it('should access password reset page directly via URL', { tags: '@smoke' }, () => {
63
+ allure.severity('normal')
64
+ allure.story('Direct Access')
65
+
66
+ // 1. Visit directly
67
+ auth.visitForgotPassword()
68
+
69
+ // 2. Validate page elements
70
+ cy.get(auth.selectors.forgotPasswordForm).should('be.visible')
71
+ cy.get(auth.selectors.forgotPasswordEmail).should('be.visible')
72
+
73
+ cy.log('✅ Direct access to password reset works')
74
+ })
75
+ })
76
+
77
+ describe('PWD-RESET-003: Submit Valid Email', { tags: '@smoke' }, () => {
78
+ it('should show success message for valid email format', { tags: '@smoke' }, () => {
79
+ allure.severity('critical')
80
+ allure.story('Submit Request')
81
+
82
+ // 1. Visit password reset page
83
+ auth.visitForgotPassword()
84
+
85
+ // 2. Request password reset
86
+ auth.requestPasswordReset('user@example.com')
87
+
88
+ // 3. Should show success message (even if email doesn't exist for security)
89
+ auth.waitForPasswordResetSuccess()
90
+
91
+ cy.log('✅ Password reset request submitted successfully')
92
+ })
93
+ })
94
+
95
+ describe('PWD-RESET-004: Validate Empty Email', () => {
96
+ it('should show error for empty email field', () => {
97
+ allure.severity('high')
98
+ allure.story('Validation')
99
+
100
+ // 1. Visit password reset page
101
+ auth.visitForgotPassword()
102
+
103
+ // 2. Submit without entering email
104
+ cy.get(auth.selectors.forgotPasswordSubmit).click()
105
+
106
+ // 3. Should show Zod validation error in UI
107
+ // The form uses react-hook-form with zod validation
108
+ // Empty email triggers validation error from zod schema
109
+ cy.contains('.text-destructive', 'Please enter a valid email address').should('be.visible')
110
+
111
+ cy.log('✅ Empty email validation works')
112
+ })
113
+ })
114
+
115
+ describe('PWD-RESET-005: Validate Invalid Email Format', () => {
116
+ it('should show error for invalid email format', () => {
117
+ allure.severity('high')
118
+ allure.story('Validation')
119
+
120
+ // 1. Visit password reset page
121
+ auth.visitForgotPassword()
122
+
123
+ // 2. Enter invalid email format
124
+ cy.get(auth.selectors.forgotPasswordEmail).type('not-an-email')
125
+
126
+ // 3. Submit form
127
+ cy.get(auth.selectors.forgotPasswordSubmit).click()
128
+
129
+ // 4. Should show validation error (HTML5 or custom)
130
+ cy.get(auth.selectors.forgotPasswordEmail).then(($input) => {
131
+ const input = $input[0] as HTMLInputElement
132
+ if (input.validity) {
133
+ expect(input.validity.valid).to.be.false
134
+ }
135
+ })
136
+
137
+ cy.log('✅ Invalid email format validation works')
138
+ })
139
+ })
140
+
141
+ describe('PWD-RESET-006: Back to Login Link', () => {
142
+ it('should navigate back to login page', () => {
143
+ allure.severity('normal')
144
+ allure.story('Navigation')
145
+
146
+ // 1. Visit password reset page
147
+ auth.visitForgotPassword()
148
+
149
+ // 2. Click back to login
150
+ auth.backToLogin()
151
+
152
+ // 3. Should be on login page
153
+ auth.assertOnLoginPage()
154
+
155
+ cy.log('✅ Back to login navigation works')
156
+ })
157
+ })
158
+
159
+ describe('PWD-RESET-007: Submit with Known Test Email', () => {
160
+ it('should handle submission with existing user email', () => {
161
+ allure.severity('high')
162
+ allure.story('Submit Request')
163
+
164
+ // 1. Visit password reset page
165
+ auth.visitForgotPassword()
166
+
167
+ // 2. Request reset for known test email
168
+ auth.requestPasswordReset('carlos.mendoza@nextspark.dev')
169
+
170
+ // 3. Should show success (same message for security - no email enumeration)
171
+ auth.waitForPasswordResetSuccess()
172
+
173
+ cy.log('✅ Password reset for existing user handled correctly')
174
+ })
175
+ })
176
+
177
+ describe('PWD-RESET-008: Form Keyboard Accessibility', () => {
178
+ it('should submit form with Enter key', () => {
179
+ allure.severity('normal')
180
+ allure.story('Accessibility')
181
+
182
+ // 1. Visit password reset page
183
+ auth.visitForgotPassword()
184
+
185
+ // 2. Enter email and press Enter
186
+ cy.get(auth.selectors.forgotPasswordEmail)
187
+ .type('user@example.com{enter}')
188
+
189
+ // 3. Should process submission and show success (async operation)
190
+ // Wait for the success message to appear after API call completes
191
+ auth.waitForPasswordResetSuccess()
192
+
193
+ cy.log('✅ Keyboard submission works')
194
+ })
195
+ })
196
+
197
+ after(() => {
198
+ cy.log('✅ Password reset flow tests completed')
199
+ })
200
+ })