@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.
- package/package.json +1 -1
- package/tests/cypress/e2e/_devtools/access.bdd.md +262 -0
- package/tests/cypress/e2e/_devtools/access.cy.ts +171 -0
- package/tests/cypress/e2e/_devtools/navigation.bdd.md +261 -0
- package/tests/cypress/e2e/_devtools/navigation.cy.ts +157 -0
- package/tests/cypress/e2e/_devtools/pages.bdd.md +303 -0
- package/tests/cypress/e2e/_devtools/pages.cy.ts +184 -0
- package/tests/cypress/e2e/_docs/README.md +215 -0
- package/tests/cypress/e2e/_docs/tutorials/sector7-superadmin-teams.narration.json +155 -0
- package/tests/cypress/e2e/_docs/tutorials/sector7-superadmin.cy.ts +390 -0
- package/tests/cypress/e2e/_docs/tutorials/teams-system.doc.cy.ts +349 -0
- package/tests/cypress/e2e/_docs/tutorials/teams-system.narration.json +165 -0
- package/tests/cypress/e2e/_selectors/auth.cy.ts +306 -0
- package/tests/cypress/e2e/_selectors/billing.cy.ts +89 -0
- package/tests/cypress/e2e/_selectors/dashboard-mobile.cy.ts +113 -0
- package/tests/cypress/e2e/_selectors/dashboard-navigation.cy.ts +89 -0
- package/tests/cypress/e2e/_selectors/dashboard-sidebar.cy.ts +60 -0
- package/tests/cypress/e2e/_selectors/dashboard-topnav.cy.ts +146 -0
- package/tests/cypress/e2e/_selectors/devtools.cy.ts +210 -0
- package/tests/cypress/e2e/_selectors/global-search.cy.ts +88 -0
- package/tests/cypress/e2e/_selectors/pages-editor.cy.ts +179 -0
- package/tests/cypress/e2e/_selectors/posts-editor.cy.ts +282 -0
- package/tests/cypress/e2e/_selectors/public.cy.ts +112 -0
- package/tests/cypress/e2e/_selectors/settings-api-keys.cy.ts +228 -0
- package/tests/cypress/e2e/_selectors/settings-billing.cy.ts +105 -0
- package/tests/cypress/e2e/_selectors/settings-layout.cy.ts +119 -0
- package/tests/cypress/e2e/_selectors/settings-password.cy.ts +71 -0
- package/tests/cypress/e2e/_selectors/settings-profile.cy.ts +82 -0
- package/tests/cypress/e2e/_selectors/settings-teams.cy.ts +68 -0
- package/tests/cypress/e2e/_selectors/superadmin.cy.ts +185 -0
- package/tests/cypress/e2e/_selectors/tasks.cy.ts +242 -0
- package/tests/cypress/e2e/_selectors/taxonomies.cy.ts +126 -0
- package/tests/cypress/e2e/_selectors/teams.cy.ts +142 -0
- package/tests/cypress/e2e/_superadmin/all-teams.bdd.md +261 -0
- package/tests/cypress/e2e/_superadmin/all-teams.cy.ts +177 -0
- package/tests/cypress/e2e/_superadmin/all-users.bdd.md +406 -0
- package/tests/cypress/e2e/_superadmin/all-users.cy.ts +294 -0
- package/tests/cypress/e2e/_superadmin/dashboard.bdd.md +235 -0
- package/tests/cypress/e2e/_superadmin/dashboard.cy.ts +149 -0
- package/tests/cypress/e2e/_superadmin/subscriptions-overview.bdd.md +290 -0
- package/tests/cypress/e2e/_superadmin/subscriptions-overview.cy.ts +194 -0
- package/tests/cypress/e2e/ai/ai-usage.cy.ts +209 -0
- package/tests/cypress/e2e/ai/chat-api.cy.ts +107 -0
- package/tests/cypress/e2e/ai/guardrails.cy.ts +332 -0
- package/tests/cypress/e2e/api/billing/BillingAPIController.js +319 -0
- package/tests/cypress/e2e/api/billing/check-action.cy.ts +326 -0
- package/tests/cypress/e2e/api/billing/checkout.cy.ts +358 -0
- package/tests/cypress/e2e/api/billing/lifecycle.cy.ts +423 -0
- package/tests/cypress/e2e/api/billing/plans/README.md +345 -0
- package/tests/cypress/e2e/api/billing/plans/business.cy.ts +412 -0
- package/tests/cypress/e2e/api/billing/plans/downgrade.cy.ts +510 -0
- package/tests/cypress/e2e/api/billing/plans/fixtures/billing-plans.json +163 -0
- package/tests/cypress/e2e/api/billing/plans/free.cy.ts +500 -0
- package/tests/cypress/e2e/api/billing/plans/pro.cy.ts +497 -0
- package/tests/cypress/e2e/api/billing/plans/starter.cy.ts +342 -0
- package/tests/cypress/e2e/api/billing/portal.cy.ts +313 -0
- package/tests/cypress/e2e/api/devtools/registries.bdd.md +300 -0
- package/tests/cypress/e2e/api/devtools/registries.cy.ts +368 -0
- package/tests/cypress/e2e/api/entities/blocks-scope.cy.ts +396 -0
- package/tests/cypress/e2e/api/entities/customers-crud.cy.ts +648 -0
- package/tests/cypress/e2e/api/entities/customers-metas.cy.ts +839 -0
- package/tests/cypress/e2e/api/entities/pages-crud.cy.ts +425 -0
- package/tests/cypress/e2e/api/entities/pages-status.cy.ts +335 -0
- package/tests/cypress/e2e/api/entities/post-categories-crud.cy.ts +610 -0
- package/tests/cypress/e2e/api/entities/posts-crud.cy.ts +709 -0
- package/tests/cypress/e2e/api/entities/posts-status.cy.ts +396 -0
- package/tests/cypress/e2e/api/entities/tasks-crud.cy.ts +602 -0
- package/tests/cypress/e2e/api/entities/tasks-metas.cy.ts +878 -0
- package/tests/cypress/e2e/api/entities/users-crud.cy.ts +469 -0
- package/tests/cypress/e2e/api/entities/users-metas.cy.ts +913 -0
- package/tests/cypress/e2e/api/entities/users-security.cy.ts +375 -0
- package/tests/cypress/e2e/api/scheduled-actions/cron-endpoint.bdd.md +375 -0
- package/tests/cypress/e2e/api/scheduled-actions/cron-endpoint.cy.ts +346 -0
- package/tests/cypress/e2e/api/scheduled-actions/devtools-endpoint.bdd.md +451 -0
- package/tests/cypress/e2e/api/scheduled-actions/devtools-endpoint.cy.ts +447 -0
- package/tests/cypress/e2e/api/scheduled-actions/scheduling.bdd.md +649 -0
- package/tests/cypress/e2e/api/scheduled-actions/scheduling.cy.ts +333 -0
- package/tests/cypress/e2e/api/settings/api-keys.crud.cy.ts +923 -0
- package/tests/cypress/e2e/uat/auth/app-roles/developer-login.bdd.md +231 -0
- package/tests/cypress/e2e/uat/auth/app-roles/developer-login.cy.ts +144 -0
- package/tests/cypress/e2e/uat/auth/app-roles/superadmin-login.bdd.md +118 -0
- package/tests/cypress/e2e/uat/auth/app-roles/superadmin-login.cy.ts +84 -0
- package/tests/cypress/e2e/uat/auth/custom-roles/editor-login.bdd.md +288 -0
- package/tests/cypress/e2e/uat/auth/custom-roles/editor-login.cy.ts +188 -0
- package/tests/cypress/e2e/uat/auth/login-logout.bdd.md +160 -0
- package/tests/cypress/e2e/uat/auth/login-logout.cy.ts +116 -0
- package/tests/cypress/e2e/uat/auth/password-reset.bdd.md +289 -0
- package/tests/cypress/e2e/uat/auth/password-reset.cy.ts +200 -0
- package/tests/cypress/e2e/uat/auth/team-roles/admin-login.bdd.md +225 -0
- package/tests/cypress/e2e/uat/auth/team-roles/admin-login.cy.ts +148 -0
- package/tests/cypress/e2e/uat/auth/team-roles/member-login.bdd.md +251 -0
- package/tests/cypress/e2e/uat/auth/team-roles/member-login.cy.ts +163 -0
- package/tests/cypress/e2e/uat/auth/team-roles/owner-login.bdd.md +231 -0
- package/tests/cypress/e2e/uat/auth/team-roles/owner-login.cy.ts +141 -0
- package/tests/cypress/e2e/uat/billing/extended.bdd.md +273 -0
- package/tests/cypress/e2e/uat/billing/extended.cy.ts +209 -0
- package/tests/cypress/e2e/uat/billing/feature-gates.bdd.md +407 -0
- package/tests/cypress/e2e/uat/billing/feature-gates.cy.ts +307 -0
- package/tests/cypress/e2e/uat/billing/page.bdd.md +329 -0
- package/tests/cypress/e2e/uat/billing/page.cy.ts +250 -0
- package/tests/cypress/e2e/uat/billing/status.bdd.md +190 -0
- package/tests/cypress/e2e/uat/billing/status.cy.ts +145 -0
- package/tests/cypress/e2e/uat/billing/team-switch.bdd.md +156 -0
- package/tests/cypress/e2e/uat/billing/team-switch.cy.ts +122 -0
- package/tests/cypress/e2e/uat/billing/usage.bdd.md +218 -0
- package/tests/cypress/e2e/uat/billing/usage.cy.ts +176 -0
- package/tests/cypress/e2e/uat/blocks/hero.bdd.md +124 -0
- package/tests/cypress/e2e/uat/blocks/hero.cy.ts +56 -0
- package/tests/cypress/e2e/uat/devtools/api-tester.cy.ts +390 -0
- package/tests/cypress/e2e/uat/entities/customers/member.bdd.md +275 -0
- package/tests/cypress/e2e/uat/entities/customers/member.cy.ts +122 -0
- package/tests/cypress/e2e/uat/entities/customers/owner.bdd.md +243 -0
- package/tests/cypress/e2e/uat/entities/customers/owner.cy.ts +165 -0
- package/tests/cypress/e2e/uat/entities/pages/block-crud.bdd.md +476 -0
- package/tests/cypress/e2e/uat/entities/pages/block-crud.cy.ts +486 -0
- package/tests/cypress/e2e/uat/entities/pages/block-editor.bdd.md +460 -0
- package/tests/cypress/e2e/uat/entities/pages/block-editor.cy.ts +301 -0
- package/tests/cypress/e2e/uat/entities/pages/list.bdd.md +432 -0
- package/tests/cypress/e2e/uat/entities/pages/list.cy.ts +273 -0
- package/tests/cypress/e2e/uat/entities/pages/public-rendering.bdd.md +696 -0
- package/tests/cypress/e2e/uat/entities/pages/public-rendering.cy.ts +340 -0
- package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.bdd.md +161 -0
- package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.cy.ts +104 -0
- package/tests/cypress/e2e/uat/entities/posts/categories.bdd.md +375 -0
- package/tests/cypress/e2e/uat/entities/posts/categories.cy.ts +241 -0
- package/tests/cypress/e2e/uat/entities/posts/editor.bdd.md +429 -0
- package/tests/cypress/e2e/uat/entities/posts/editor.cy.ts +257 -0
- package/tests/cypress/e2e/uat/entities/posts/list.bdd.md +340 -0
- package/tests/cypress/e2e/uat/entities/posts/list.cy.ts +177 -0
- package/tests/cypress/e2e/uat/entities/posts/public.bdd.md +614 -0
- package/tests/cypress/e2e/uat/entities/posts/public.cy.ts +249 -0
- package/tests/cypress/e2e/uat/entities/tasks/member.bdd.md +222 -0
- package/tests/cypress/e2e/uat/entities/tasks/member.cy.ts +165 -0
- package/tests/cypress/e2e/uat/entities/tasks/owner.bdd.md +419 -0
- package/tests/cypress/e2e/uat/entities/tasks/owner.cy.ts +191 -0
- package/tests/cypress/e2e/uat/roles/editor-role.bdd.md +552 -0
- package/tests/cypress/e2e/uat/roles/editor-role.cy.ts +210 -0
- package/tests/cypress/e2e/uat/roles/member-restrictions.bdd.md +450 -0
- package/tests/cypress/e2e/uat/roles/member-restrictions.cy.ts +189 -0
- package/tests/cypress/e2e/uat/roles/owner-full-crud.bdd.md +530 -0
- package/tests/cypress/e2e/uat/roles/owner-full-crud.cy.ts +247 -0
- package/tests/cypress/e2e/uat/scheduled-actions/devtools-ui.bdd.md +736 -0
- package/tests/cypress/e2e/uat/scheduled-actions/devtools-ui.cy.ts +740 -0
- package/tests/cypress/e2e/uat/teams/roles-matrix.bdd.md +553 -0
- package/tests/cypress/e2e/uat/teams/roles-matrix.cy.ts +185 -0
- package/tests/cypress/e2e/uat/teams/switcher.bdd.md +1151 -0
- package/tests/cypress/e2e/uat/teams/switcher.cy.ts +497 -0
- package/tests/cypress/e2e/uat/teams/team-switcher.md +198 -0
- package/tests/cypress/fixtures/blocks.json +218 -0
- package/tests/cypress/fixtures/entities.json +78 -0
- package/tests/cypress/fixtures/page-builder.json +21 -0
- package/tests/cypress/src/components/CategoriesPOM.ts +382 -0
- package/tests/cypress/src/components/CustomersPOM.ts +439 -0
- package/tests/cypress/src/components/DevKeyringPOM.ts +160 -0
- package/tests/cypress/src/components/EntityForm.ts +375 -0
- package/tests/cypress/src/components/EntityList.ts +389 -0
- package/tests/cypress/src/components/PageBuilderPOM.ts +710 -0
- package/tests/cypress/src/components/PostEditorPOM.ts +370 -0
- package/tests/cypress/src/components/PostsListPOM.ts +223 -0
- package/tests/cypress/src/components/PublicPagePOM.ts +447 -0
- package/tests/cypress/src/components/PublicPostPOM.ts +146 -0
- package/tests/cypress/src/components/TasksPOM.ts +272 -0
- package/tests/cypress/src/components/TeamSwitcherPOM.ts +450 -0
- package/tests/cypress/src/components/index.ts +21 -0
- package/tests/cypress/src/controllers/ApiKeysAPIController.js +178 -0
- package/tests/cypress/src/controllers/BaseAPIController.js +317 -0
- package/tests/cypress/src/controllers/CustomerAPIController.js +251 -0
- package/tests/cypress/src/controllers/PagesAPIController.js +226 -0
- package/tests/cypress/src/controllers/PostsAPIController.js +250 -0
- package/tests/cypress/src/controllers/TaskAPIController.js +240 -0
- package/tests/cypress/src/controllers/UsersAPIController.js +242 -0
- package/tests/cypress/src/controllers/index.js +25 -0
- package/tests/cypress/src/core/AuthPOM.ts +450 -0
- package/tests/cypress/src/core/BasePOM.ts +86 -0
- package/tests/cypress/src/core/BlockEditorBasePOM.ts +576 -0
- package/tests/cypress/src/core/DashboardEntityPOM.ts +692 -0
- package/tests/cypress/src/core/index.ts +14 -0
- package/tests/cypress/src/entities/CustomersPOM.ts +172 -0
- package/tests/cypress/src/entities/PagesPOM.ts +137 -0
- package/tests/cypress/src/entities/PostsPOM.ts +137 -0
- package/tests/cypress/src/entities/TasksPOM.ts +176 -0
- package/tests/cypress/src/entities/index.ts +14 -0
- package/tests/cypress/src/features/BillingPOM.ts +385 -0
- package/tests/cypress/src/features/DashboardPOM.ts +245 -0
- package/tests/cypress/src/features/DevtoolsPOM.ts +739 -0
- package/tests/cypress/src/features/PageBuilderPOM.ts +263 -0
- package/tests/cypress/src/features/PostEditorPOM.ts +313 -0
- package/tests/cypress/src/features/ScheduledActionsPOM.ts +463 -0
- package/tests/cypress/src/features/SettingsPOM.ts +362 -0
- package/tests/cypress/src/features/SuperadminPOM.ts +331 -0
- package/tests/cypress/src/features/SuperadminTeamRolesPOM.ts +285 -0
- package/tests/cypress/src/features/index.ts +28 -0
- package/tests/cypress/src/helpers/ApiInterceptor.ts +177 -0
- package/tests/cypress/src/index.ts +101 -0
- package/tests/cypress/src/pages/dashboard/Dashboard.js +677 -0
- package/tests/cypress/src/pages/dashboard/DashboardPage.js +43 -0
- package/tests/cypress/src/pages/dashboard/DashboardStats.js +546 -0
- package/tests/cypress/src/pages/dashboard/index.js +6 -0
- package/tests/cypress/src/pages/index.js +5 -0
- package/tests/cypress/src/pages/public/FeaturesPage.js +28 -0
- package/tests/cypress/src/pages/public/LandingPage.js +69 -0
- package/tests/cypress/src/pages/public/PricingPage.js +33 -0
- package/tests/cypress/src/pages/public/index.js +6 -0
- package/tests/cypress/src/selectors.ts +46 -0
- package/tests/cypress/src/session-helpers.ts +500 -0
- package/tests/cypress/support/doc-commands.ts +260 -0
- package/tests/cypress/support/e2e.ts +89 -0
- package/tests/cypress.config.ts +165 -0
- package/tests/jest/components/post-header.test.tsx +377 -0
- package/tests/jest/config/role-config.test.ts +529 -0
- package/tests/jest/jest.config.ts +81 -0
- package/tests/jest/langchain/COVERAGE.md +372 -0
- package/tests/jest/langchain/guardrails.test.ts +465 -0
- package/tests/jest/langchain/streaming.test.ts +367 -0
- package/tests/jest/langchain/token-tracker.test.ts +455 -0
- package/tests/jest/langchain/tracer-callbacks.test.ts +881 -0
- package/tests/jest/langchain/tracer.test.ts +823 -0
- package/tests/jest/user-roles/role-helpers.test.ts +432 -0
- package/tests/jest/validation/categories.test.ts +429 -0
- package/tests/jest/validation/posts.test.ts +546 -0
- 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
|
+
})
|