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

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 (221) 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/support/e2e.ts +89 -0
  208. package/tests/cypress.config.ts +165 -0
  209. package/tests/jest/components/post-header.test.tsx +377 -0
  210. package/tests/jest/config/role-config.test.ts +529 -0
  211. package/tests/jest/jest.config.ts +81 -0
  212. package/tests/jest/langchain/COVERAGE.md +372 -0
  213. package/tests/jest/langchain/guardrails.test.ts +465 -0
  214. package/tests/jest/langchain/streaming.test.ts +367 -0
  215. package/tests/jest/langchain/token-tracker.test.ts +455 -0
  216. package/tests/jest/langchain/tracer-callbacks.test.ts +881 -0
  217. package/tests/jest/langchain/tracer.test.ts +823 -0
  218. package/tests/jest/user-roles/role-helpers.test.ts +432 -0
  219. package/tests/jest/validation/categories.test.ts +429 -0
  220. package/tests/jest/validation/posts.test.ts +546 -0
  221. package/tests/tsconfig.json +15 -0
@@ -0,0 +1,260 @@
1
+ /**
2
+ * Documentation Commands for Cypress
3
+ *
4
+ * Custom commands for generating documentation videos with narration.
5
+ * Uses cypress-slow-down for controlled execution speed.
6
+ *
7
+ * @example
8
+ * // In your test file:
9
+ * import '../support/doc-commands'
10
+ *
11
+ * describe('Tutorial: Login', { tags: ['@doc'] }, () => {
12
+ * before(() => {
13
+ * cy.startDocMode(800)
14
+ * })
15
+ *
16
+ * it('shows how to login', () => {
17
+ * cy.narrate('First, navigate to the login page')
18
+ * cy.visit('/login')
19
+ * })
20
+ * })
21
+ */
22
+
23
+ import { slowCypressDown } from 'cypress-slow-down'
24
+ import 'cypress-slow-down/commands'
25
+
26
+ // Store narrations for extraction
27
+ interface NarrationEntry {
28
+ timestamp: number
29
+ time: string // "M:SS" format from start (for subtitles)
30
+ timeMs: number // Milliseconds from start
31
+ stepNumber: number
32
+ text: string
33
+ highlight?: string
34
+ duration: number
35
+ chapter?: string
36
+ }
37
+
38
+ let narrations: NarrationEntry[] = []
39
+ let stepCounter = 0
40
+ let docModeActive = false
41
+ let startTime = 0 // Timestamp when recording started
42
+
43
+ /**
44
+ * Format milliseconds to M:SS or MM:SS string
45
+ */
46
+ function formatTime(ms: number): string {
47
+ const totalSeconds = Math.floor(ms / 1000)
48
+ const minutes = Math.floor(totalSeconds / 60)
49
+ const seconds = totalSeconds % 60
50
+ return `${minutes}:${seconds.toString().padStart(2, '0')}`
51
+ }
52
+
53
+ // Declare custom commands
54
+ declare global {
55
+ namespace Cypress {
56
+ interface Chainable {
57
+ /**
58
+ * Start documentation mode with specified delay between commands
59
+ * @param delayMs - Milliseconds to wait between each command (default: 800)
60
+ */
61
+ startDocMode(delayMs?: number): Chainable<void>
62
+
63
+ /**
64
+ * End documentation mode and save narrations
65
+ */
66
+ endDocMode(): Chainable<void>
67
+
68
+ /**
69
+ * Add narration text for the current step
70
+ * @param text - The narration text to display/speak
71
+ * @param options - Optional settings like highlight selector
72
+ */
73
+ narrate(text: string, options?: { highlight?: string; pause?: number }): Chainable<void>
74
+
75
+ /**
76
+ * Add a chapter/section marker in the narration
77
+ * @param title - Chapter title
78
+ */
79
+ chapter(title: string): Chainable<void>
80
+
81
+ /**
82
+ * Pause for emphasis (used after important actions)
83
+ * @param ms - Milliseconds to pause
84
+ */
85
+ pauseForEmphasis(ms?: number): Chainable<void>
86
+
87
+ /**
88
+ * Highlight an element visually (adds temporary outline)
89
+ * @param selector - Element selector to highlight
90
+ */
91
+ highlightElement(selector: string): Chainable<void>
92
+ }
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Calculate reading time based on text length
98
+ * Average reading speed: ~150-180 words per minute for narration
99
+ * We use ~4 characters = 1 syllable, ~1.5 syllables/second for clear speech
100
+ */
101
+ function calculateNarrationDuration(text: string): number {
102
+ const words = text.split(/\s+/).length
103
+ const wordsPerSecond = 2.5 // Slow, clear narration speed
104
+ const baseTime = (words / wordsPerSecond) * 1000
105
+ // Add minimum time and buffer
106
+ return Math.max(1500, baseTime + 500)
107
+ }
108
+
109
+ /**
110
+ * Start documentation mode - slows down Cypress execution
111
+ */
112
+ Cypress.Commands.add('startDocMode', (delayMs = 800) => {
113
+ docModeActive = true
114
+ narrations = []
115
+ stepCounter = 0
116
+ startTime = Date.now() // Record start time
117
+
118
+ // Activate slow mode
119
+ slowCypressDown(delayMs)
120
+
121
+ // Log start marker (visible in video)
122
+ cy.log('🎬 **DOCUMENTATION MODE STARTED**')
123
+
124
+ // Add initial narration entry
125
+ narrations.push({
126
+ timestamp: startTime,
127
+ time: '0:00',
128
+ timeMs: 0,
129
+ stepNumber: 0,
130
+ text: '--- Documentation Recording Started ---',
131
+ duration: 0,
132
+ })
133
+ })
134
+
135
+ /**
136
+ * End documentation mode and save narrations to file
137
+ */
138
+ Cypress.Commands.add('endDocMode', () => {
139
+ if (!docModeActive) return
140
+
141
+ cy.log('🎬 **DOCUMENTATION MODE ENDED**')
142
+
143
+ // Add final narration entry
144
+ const now = Date.now()
145
+ const elapsedMs = now - startTime
146
+ narrations.push({
147
+ timestamp: now,
148
+ time: formatTime(elapsedMs),
149
+ timeMs: elapsedMs,
150
+ stepNumber: stepCounter + 1,
151
+ text: '--- Documentation Recording Ended ---',
152
+ duration: 0,
153
+ })
154
+
155
+ // Save narrations to file via task
156
+ const specName = Cypress.spec.name.replace('.cy.ts', '').replace('.cy.js', '')
157
+ cy.task('saveNarrations', {
158
+ specName,
159
+ narrations,
160
+ totalDuration: formatTime(elapsedMs),
161
+ totalDurationMs: elapsedMs,
162
+ }, { log: false })
163
+
164
+ cy.log(`🎬 **Total Duration: ${formatTime(elapsedMs)}**`)
165
+
166
+ docModeActive = false
167
+ narrations = []
168
+ stepCounter = 0
169
+ startTime = 0
170
+ })
171
+
172
+ /**
173
+ * Add narration for current step
174
+ */
175
+ Cypress.Commands.add('narrate', (text: string, options?: { highlight?: string; pause?: number }) => {
176
+ stepCounter++
177
+ const duration = calculateNarrationDuration(text)
178
+ const now = Date.now()
179
+ const elapsedMs = now - startTime
180
+ const timeStr = formatTime(elapsedMs)
181
+
182
+ // Store narration data
183
+ narrations.push({
184
+ timestamp: now,
185
+ time: timeStr,
186
+ timeMs: elapsedMs,
187
+ stepNumber: stepCounter,
188
+ text,
189
+ highlight: options?.highlight,
190
+ duration,
191
+ })
192
+
193
+ // Visual feedback in Cypress runner (will show in video)
194
+ cy.log(`🎙️ **[${timeStr}]** ${text}`)
195
+
196
+ // If highlight specified, add visual indicator
197
+ if (options?.highlight) {
198
+ cy.highlightElement(options.highlight)
199
+ }
200
+
201
+ // Wait for narration duration (so video has time for the narration)
202
+ const waitTime = options?.pause ?? duration
203
+ cy.wait(waitTime, { log: false })
204
+ })
205
+
206
+ /**
207
+ * Add chapter marker
208
+ */
209
+ Cypress.Commands.add('chapter', (title: string) => {
210
+ stepCounter++
211
+ const now = Date.now()
212
+ const elapsedMs = now - startTime
213
+ const timeStr = formatTime(elapsedMs)
214
+
215
+ narrations.push({
216
+ timestamp: now,
217
+ time: timeStr,
218
+ timeMs: elapsedMs,
219
+ stepNumber: stepCounter,
220
+ text: `=== ${title} ===`,
221
+ chapter: title,
222
+ duration: 2000,
223
+ })
224
+
225
+ // Large visual marker
226
+ cy.log(`📖 **[${timeStr}] ━━━ ${title.toUpperCase()} ━━━**`)
227
+ cy.wait(2000, { log: false })
228
+ })
229
+
230
+ /**
231
+ * Pause for emphasis after important actions
232
+ */
233
+ Cypress.Commands.add('pauseForEmphasis', (ms = 1500) => {
234
+ cy.log('⏸️ *pause*')
235
+ cy.wait(ms, { log: false })
236
+ })
237
+
238
+ /**
239
+ * Highlight an element with a visual indicator
240
+ */
241
+ Cypress.Commands.add('highlightElement', (selector: string) => {
242
+ cy.get(selector).then($el => {
243
+ // Add highlight class
244
+ $el.css({
245
+ outline: '3px solid #ff6b6b',
246
+ outlineOffset: '2px',
247
+ transition: 'outline 0.3s ease',
248
+ })
249
+
250
+ // Remove highlight after a delay
251
+ cy.wait(800, { log: false }).then(() => {
252
+ $el.css({
253
+ outline: 'none',
254
+ outlineOffset: '0',
255
+ })
256
+ })
257
+ })
258
+ })
259
+
260
+ export {}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Cypress E2E Support File for Theme
3
+ *
4
+ * This file is used when running tests in npm mode (outside monorepo).
5
+ * In monorepo mode, the core support file is used instead via cypress.config.ts.
6
+ *
7
+ * For documentation video commands, install cypress-slow-down:
8
+ * pnpm add -D cypress-slow-down
9
+ * Then uncomment the doc-commands import below.
10
+ */
11
+
12
+ import '@testing-library/cypress/add-commands'
13
+
14
+ // Import @cypress/grep for test filtering by tags
15
+ import registerCypressGrep from '@cypress/grep'
16
+ registerCypressGrep()
17
+
18
+ // Doc commands are optional (require cypress-slow-down)
19
+ // Uncomment if you have cypress-slow-down installed:
20
+ // import './doc-commands'
21
+
22
+ // Global error handling
23
+ Cypress.on('uncaught:exception', (err) => {
24
+ // Ignore React hydration errors
25
+ if (err.message.includes('Hydration')) {
26
+ return false
27
+ }
28
+ // Ignore ResizeObserver errors
29
+ if (err.message.includes('ResizeObserver')) {
30
+ return false
31
+ }
32
+ return true
33
+ })
34
+
35
+ // Global before hook
36
+ beforeEach(() => {
37
+ cy.clearCookies()
38
+ cy.clearLocalStorage()
39
+ })
40
+
41
+ // Type declarations for @cypress/grep and custom commands
42
+ declare global {
43
+ namespace Cypress {
44
+ interface Chainable {
45
+ /**
46
+ * Custom command to make API requests with better error handling
47
+ */
48
+ apiRequest(options: Partial<Cypress.RequestOptions>): Chainable<Cypress.Response<any>>
49
+
50
+ /**
51
+ * Login command for authenticated tests
52
+ */
53
+ login(email: string, password: string): Chainable<void>
54
+ }
55
+ interface SuiteConfigOverrides {
56
+ tags?: string | string[]
57
+ }
58
+ interface TestConfigOverrides {
59
+ tags?: string | string[]
60
+ }
61
+ }
62
+ }
63
+
64
+ // Custom API request command
65
+ Cypress.Commands.add('apiRequest', (options) => {
66
+ const defaultOptions = {
67
+ failOnStatusCode: false,
68
+ timeout: 15000,
69
+ headers: {
70
+ 'Content-Type': 'application/json',
71
+ ...options.headers
72
+ }
73
+ }
74
+ return cy.request({
75
+ ...defaultOptions,
76
+ ...options
77
+ })
78
+ })
79
+
80
+ // Login command for authenticated tests
81
+ Cypress.Commands.add('login', (email: string, password: string) => {
82
+ cy.session([email, password], () => {
83
+ cy.visit('/login')
84
+ cy.get('[data-testid="email-input"], input[name="email"]').type(email)
85
+ cy.get('[data-testid="password-input"], input[name="password"]').type(password)
86
+ cy.get('[data-testid="submit-button"], button[type="submit"]').click()
87
+ cy.url().should('include', '/dashboard')
88
+ })
89
+ })
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Cypress Configuration for Default Theme
3
+ *
4
+ * This config works in both monorepo and npm mode.
5
+ * Run with: NEXT_PUBLIC_ACTIVE_THEME=default pnpm cy:open
6
+ */
7
+
8
+ import { defineConfig } from 'cypress'
9
+ import path from 'path'
10
+ import fs from 'fs'
11
+ import { fileURLToPath } from 'url'
12
+
13
+ // ESM-compatible __dirname
14
+ const __filename = fileURLToPath(import.meta.url)
15
+ const __dirname = path.dirname(__filename)
16
+
17
+ // Paths relative to this config file
18
+ const themeRoot = path.resolve(__dirname, '..')
19
+ const projectRoot = path.resolve(__dirname, '../../../..')
20
+ const narrationsOutputDir = path.join(__dirname, 'cypress/videos/narrations')
21
+
22
+ // Detect if running in npm mode (no packages/core folder) vs monorepo
23
+ const isNpmMode = !fs.existsSync(path.join(projectRoot, 'packages/core'))
24
+
25
+ // Load environment variables
26
+ import dotenv from 'dotenv'
27
+ dotenv.config({ path: path.join(projectRoot, '.env') })
28
+
29
+ // Server port (from .env or default 3000)
30
+ const port = process.env.PORT || 3000
31
+
32
+ export default defineConfig({
33
+ e2e: {
34
+ // Base URL for the application
35
+ baseUrl: `http://localhost:${port}`,
36
+
37
+ // Spec patterns: theme tests (core tests only in monorepo)
38
+ specPattern: isNpmMode
39
+ ? [
40
+ // npm mode: only theme tests
41
+ path.join(__dirname, 'cypress/e2e/**/*.cy.{js,ts}'),
42
+ ]
43
+ : [
44
+ // Monorepo: core tests + theme tests
45
+ path.join(projectRoot, 'packages/core/tests/cypress/e2e/core/**/*.cy.{js,ts}'),
46
+ path.join(__dirname, 'cypress/e2e/**/*.cy.{js,ts}'),
47
+ ],
48
+
49
+ // Support file (theme-local in npm mode, core in monorepo)
50
+ supportFile: isNpmMode
51
+ ? path.join(__dirname, 'cypress/support/e2e.ts')
52
+ : path.join(projectRoot, 'packages/core/tests/cypress/support/e2e.ts'),
53
+
54
+ // Fixtures folder (theme-specific)
55
+ fixturesFolder: path.join(__dirname, 'cypress/fixtures'),
56
+
57
+ // Output folders (theme-specific)
58
+ downloadsFolder: path.join(__dirname, 'cypress/downloads'),
59
+ screenshotsFolder: path.join(__dirname, 'cypress/screenshots'),
60
+ videosFolder: path.join(__dirname, 'cypress/videos'),
61
+
62
+ // Viewport settings
63
+ viewportWidth: 1280,
64
+ viewportHeight: 720,
65
+
66
+ // Video and screenshot settings
67
+ video: true,
68
+ screenshotOnRunFailure: true,
69
+
70
+ // Timeouts
71
+ defaultCommandTimeout: 10000,
72
+ requestTimeout: 10000,
73
+ responseTimeout: 10000,
74
+ pageLoadTimeout: 30000,
75
+
76
+ // Browser settings
77
+ chromeWebSecurity: false,
78
+
79
+ // Test isolation
80
+ testIsolation: true,
81
+
82
+ // Retry settings
83
+ retries: {
84
+ runMode: 1,
85
+ openMode: 0,
86
+ },
87
+
88
+ // Environment variables
89
+ env: {
90
+ // Theme info
91
+ ACTIVE_THEME: 'default',
92
+ THEME_PATH: themeRoot,
93
+
94
+ // Test user credentials
95
+ TEST_USER_EMAIL: 'user@example.com',
96
+ TEST_USER_PASSWORD: 'Testing1234',
97
+
98
+ // Feature flags
99
+ ENABLE_ALLURE: true,
100
+
101
+ // Allure reporting
102
+ allureResultsPath: path.join(__dirname, 'cypress/allure-results'),
103
+
104
+ // API settings
105
+ API_URL: `http://localhost:${port}/api`,
106
+ API_BASE_URL: `http://localhost:${port}`,
107
+
108
+ // @cypress/grep - filter specs by tags
109
+ grepFilterSpecs: true,
110
+ grepOmitFiltered: true,
111
+ },
112
+
113
+ async setupNodeEvents(on, config) {
114
+ // Allure plugin setup (allure-cypress)
115
+ const { allureCypress } = await import('allure-cypress/reporter')
116
+ allureCypress(on, config, {
117
+ resultsDir: path.join(__dirname, 'cypress/allure-results'),
118
+ })
119
+
120
+ // @cypress/grep plugin for test filtering by tags
121
+ const grepPlugin = await import('@cypress/grep/src/plugin.js')
122
+ ;(grepPlugin.default || grepPlugin)(config)
123
+
124
+ // Documentation video tasks
125
+ on('task', {
126
+ /**
127
+ * Save narrations to JSON file for post-processing
128
+ */
129
+ saveNarrations({ specName, narrations }: { specName: string; narrations: unknown[] }) {
130
+ // Ensure output directory exists
131
+ if (!fs.existsSync(narrationsOutputDir)) {
132
+ fs.mkdirSync(narrationsOutputDir, { recursive: true })
133
+ }
134
+
135
+ const filename = `${specName}-narrations.json`
136
+ const filepath = path.join(narrationsOutputDir, filename)
137
+
138
+ fs.writeFileSync(filepath, JSON.stringify(narrations, null, 2))
139
+ console.log(`📝 Narrations saved to: ${filepath}`)
140
+
141
+ return null
142
+ },
143
+
144
+ /**
145
+ * Add narration entry (called per narration)
146
+ */
147
+ addNarration(narration: unknown) {
148
+ // This could be used for real-time streaming to a narration service
149
+ console.log('🎙️ Narration:', narration)
150
+ return null
151
+ },
152
+ })
153
+
154
+ return config
155
+ },
156
+ },
157
+
158
+ // Component testing (future use)
159
+ component: {
160
+ devServer: {
161
+ framework: 'next',
162
+ bundler: 'webpack',
163
+ },
164
+ },
165
+ })