@nextsparkjs/theme-crm 0.1.0-beta.18 → 0.1.0-beta.20

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 (70) hide show
  1. package/package.json +2 -2
  2. package/tests/cypress/e2e/api/activities/activities-crud.cy.ts +686 -0
  3. package/tests/cypress/e2e/api/campaigns/campaigns-crud.cy.ts +592 -0
  4. package/tests/cypress/e2e/api/companies/companies-crud.cy.ts +682 -0
  5. package/tests/cypress/e2e/api/contacts/contacts-crud.cy.ts +668 -0
  6. package/tests/cypress/e2e/api/leads/leads-crud.cy.ts +648 -0
  7. package/tests/cypress/e2e/api/notes/notes-crud.cy.ts +424 -0
  8. package/tests/cypress/e2e/api/opportunities/opportunities-crud.cy.ts +865 -0
  9. package/tests/cypress/e2e/api/pipelines/pipelines-crud.cy.ts +545 -0
  10. package/tests/cypress/e2e/api/products/products-crud.cy.ts +447 -0
  11. package/tests/cypress/e2e/ui/activities/activities-admin.cy.ts +268 -0
  12. package/tests/cypress/e2e/ui/activities/activities-member.cy.ts +257 -0
  13. package/tests/cypress/e2e/ui/activities/activities-owner.cy.ts +268 -0
  14. package/tests/cypress/e2e/ui/companies/companies-admin.cy.ts +188 -0
  15. package/tests/cypress/e2e/ui/companies/companies-member.cy.ts +166 -0
  16. package/tests/cypress/e2e/ui/companies/companies-owner.cy.ts +189 -0
  17. package/tests/cypress/e2e/ui/contacts/contacts-admin.cy.ts +252 -0
  18. package/tests/cypress/e2e/ui/contacts/contacts-member.cy.ts +224 -0
  19. package/tests/cypress/e2e/ui/contacts/contacts-owner.cy.ts +236 -0
  20. package/tests/cypress/e2e/ui/leads/leads-admin.cy.ts +286 -0
  21. package/tests/cypress/e2e/ui/leads/leads-member.cy.ts +193 -0
  22. package/tests/cypress/e2e/ui/leads/leads-owner.cy.ts +210 -0
  23. package/tests/cypress/e2e/ui/opportunities/opportunities-admin.cy.ts +197 -0
  24. package/tests/cypress/e2e/ui/opportunities/opportunities-member.cy.ts +229 -0
  25. package/tests/cypress/e2e/ui/opportunities/opportunities-owner.cy.ts +196 -0
  26. package/tests/cypress/e2e/ui/pipelines/pipelines-admin.cy.ts +320 -0
  27. package/tests/cypress/e2e/ui/pipelines/pipelines-member.cy.ts +262 -0
  28. package/tests/cypress/e2e/ui/pipelines/pipelines-owner.cy.ts +282 -0
  29. package/tests/cypress/fixtures/blocks.json +9 -0
  30. package/tests/cypress/fixtures/entities.json +240 -0
  31. package/tests/cypress/src/components/CRMDataTable.js +223 -0
  32. package/tests/cypress/src/components/CRMMobileNav.js +138 -0
  33. package/tests/cypress/src/components/CRMSidebar.js +145 -0
  34. package/tests/cypress/src/components/CRMTopBar.js +194 -0
  35. package/tests/cypress/src/components/DealCard.js +197 -0
  36. package/tests/cypress/src/components/EntityDetail.ts +290 -0
  37. package/tests/cypress/src/components/EntityForm.ts +357 -0
  38. package/tests/cypress/src/components/EntityList.ts +360 -0
  39. package/tests/cypress/src/components/PipelineKanban.js +204 -0
  40. package/tests/cypress/src/components/StageColumn.js +196 -0
  41. package/tests/cypress/src/components/index.js +13 -0
  42. package/tests/cypress/src/components/index.ts +22 -0
  43. package/tests/cypress/src/controllers/ActivityAPIController.ts +113 -0
  44. package/tests/cypress/src/controllers/BaseAPIController.ts +307 -0
  45. package/tests/cypress/src/controllers/CampaignAPIController.ts +114 -0
  46. package/tests/cypress/src/controllers/CompanyAPIController.ts +112 -0
  47. package/tests/cypress/src/controllers/ContactAPIController.ts +104 -0
  48. package/tests/cypress/src/controllers/LeadAPIController.ts +96 -0
  49. package/tests/cypress/src/controllers/NoteAPIController.ts +130 -0
  50. package/tests/cypress/src/controllers/OpportunityAPIController.ts +134 -0
  51. package/tests/cypress/src/controllers/PipelineAPIController.ts +116 -0
  52. package/tests/cypress/src/controllers/ProductAPIController.ts +113 -0
  53. package/tests/cypress/src/controllers/index.ts +35 -0
  54. package/tests/cypress/src/entities/ActivitiesPOM.ts +130 -0
  55. package/tests/cypress/src/entities/CompaniesPOM.ts +117 -0
  56. package/tests/cypress/src/entities/ContactsPOM.ts +117 -0
  57. package/tests/cypress/src/entities/LeadsPOM.ts +129 -0
  58. package/tests/cypress/src/entities/OpportunitiesPOM.ts +178 -0
  59. package/tests/cypress/src/entities/PipelinesPOM.ts +341 -0
  60. package/tests/cypress/src/entities/index.ts +31 -0
  61. package/tests/cypress/src/forms/OpportunityForm.js +316 -0
  62. package/tests/cypress/src/forms/PipelineForm.js +243 -0
  63. package/tests/cypress/src/forms/index.js +8 -0
  64. package/tests/cypress/src/index.js +22 -0
  65. package/tests/cypress/src/index.ts +68 -0
  66. package/tests/cypress/src/selectors.ts +50 -0
  67. package/tests/cypress/src/session-helpers.ts +94 -0
  68. package/tests/cypress/support/e2e.ts +89 -0
  69. package/tests/cypress.config.ts +165 -0
  70. package/tests/tsconfig.json +15 -0
@@ -0,0 +1,94 @@
1
+ /**
2
+ * CRM Theme Session Helpers
3
+ *
4
+ * Direct login functions for CRM theme tests using CRM-specific users.
5
+ * These helpers don't depend on ACTIVE_THEME environment variable.
6
+ */
7
+
8
+ import { DevKeyring } from '../../../../../../test/cypress/src/classes/components/auth/DevKeyring.js'
9
+
10
+ /**
11
+ * CRM Test Users - hardcoded for CRM theme tests
12
+ */
13
+ export const CRM_USERS = {
14
+ OWNER: 'crm_owner_roberto@nextspark.dev', // CEO
15
+ ADMIN: 'crm_admin_sofia@nextspark.dev', // Sales Manager
16
+ MEMBER: 'crm_member_miguel@nextspark.dev', // Sales Rep
17
+ LAURA: 'crm_member_laura@nextspark.dev', // Marketing
18
+ } as const
19
+
20
+ /**
21
+ * Login as CRM Owner (CEO)
22
+ * Session is cached and reused across tests
23
+ */
24
+ export function loginAsCrmOwner() {
25
+ cy.session('crm-owner-session', () => {
26
+ cy.visit('/login')
27
+ const devKeyring = new DevKeyring()
28
+ devKeyring.validateVisible()
29
+ devKeyring.quickLoginByEmail(CRM_USERS.OWNER)
30
+ cy.url().should('include', '/dashboard')
31
+ }, {
32
+ validate: () => {
33
+ cy.visit('/dashboard')
34
+ cy.url().should('include', '/dashboard')
35
+ }
36
+ })
37
+ }
38
+
39
+ /**
40
+ * Login as CRM Admin (Sales Manager)
41
+ * Session is cached and reused across tests
42
+ */
43
+ export function loginAsCrmAdmin() {
44
+ cy.session('crm-admin-session', () => {
45
+ cy.visit('/login')
46
+ const devKeyring = new DevKeyring()
47
+ devKeyring.validateVisible()
48
+ devKeyring.quickLoginByEmail(CRM_USERS.ADMIN)
49
+ cy.url().should('include', '/dashboard')
50
+ }, {
51
+ validate: () => {
52
+ cy.visit('/dashboard')
53
+ cy.url().should('include', '/dashboard')
54
+ }
55
+ })
56
+ }
57
+
58
+ /**
59
+ * Login as CRM Member (Sales Rep)
60
+ * Session is cached and reused across tests
61
+ */
62
+ export function loginAsCrmMember() {
63
+ cy.session('crm-member-session', () => {
64
+ cy.visit('/login')
65
+ const devKeyring = new DevKeyring()
66
+ devKeyring.validateVisible()
67
+ devKeyring.quickLoginByEmail(CRM_USERS.MEMBER)
68
+ cy.url().should('include', '/dashboard')
69
+ }, {
70
+ validate: () => {
71
+ cy.visit('/dashboard')
72
+ cy.url().should('include', '/dashboard')
73
+ }
74
+ })
75
+ }
76
+
77
+ /**
78
+ * Login as CRM Laura (Marketing)
79
+ * Session is cached and reused across tests
80
+ */
81
+ export function loginAsCrmLaura() {
82
+ cy.session('crm-laura-session', () => {
83
+ cy.visit('/login')
84
+ const devKeyring = new DevKeyring()
85
+ devKeyring.validateVisible()
86
+ devKeyring.quickLoginByEmail(CRM_USERS.LAURA)
87
+ cy.url().should('include', '/dashboard')
88
+ }, {
89
+ validate: () => {
90
+ cy.visit('/dashboard')
91
+ cy.url().should('include', '/dashboard')
92
+ }
93
+ })
94
+ }
@@ -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 crm 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: 'crm',
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
+ })
@@ -0,0 +1,15 @@
1
+ {
2
+ "extends": "../../../../tsconfig.cypress.json",
3
+ "compilerOptions": {
4
+ "baseUrl": "../../../..",
5
+ "paths": {
6
+ "@/*": ["./*"],
7
+ "@/core/*": ["./core/*"],
8
+ "@/contents/*": ["./contents/*"]
9
+ }
10
+ },
11
+ "include": [
12
+ "../../../../cypress.d.ts",
13
+ "cypress/**/*.ts"
14
+ ]
15
+ }