@nextsparkjs/ai-workflow 0.1.0-beta.86

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 (271) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +86 -0
  3. package/claude/_docs/workflows-optimizations.md +359 -0
  4. package/claude/agents/api-tester.md +636 -0
  5. package/claude/agents/architecture-supervisor.md +1381 -0
  6. package/claude/agents/backend-developer.md +1021 -0
  7. package/claude/agents/backend-validator.md +417 -0
  8. package/claude/agents/bdd-docs-writer.md +737 -0
  9. package/claude/agents/block-developer.md +677 -0
  10. package/claude/agents/code-reviewer.md +1460 -0
  11. package/claude/agents/db-developer.md +721 -0
  12. package/claude/agents/db-validator.md +407 -0
  13. package/claude/agents/demo-video-generator.md +493 -0
  14. package/claude/agents/documentation-writer.md +1291 -0
  15. package/claude/agents/frontend-developer.md +1259 -0
  16. package/claude/agents/frontend-validator.md +777 -0
  17. package/claude/agents/functional-validator.md +630 -0
  18. package/claude/agents/mock-analyst.md +387 -0
  19. package/claude/agents/product-manager.md +971 -0
  20. package/claude/agents/qa-automation.md +1762 -0
  21. package/claude/agents/release-manager.md +634 -0
  22. package/claude/agents/selectors-translator.md +262 -0
  23. package/claude/agents/unit-test-writer.md +785 -0
  24. package/claude/agents/visual-comparator.md +329 -0
  25. package/claude/agents/workflow-maintainer.md +373 -0
  26. package/claude/commands/do/README.md +88 -0
  27. package/claude/commands/do/create-api.md +64 -0
  28. package/claude/commands/do/create-entity.md +66 -0
  29. package/claude/commands/do/create-migration.md +64 -0
  30. package/claude/commands/do/create-plugin.md +56 -0
  31. package/claude/commands/do/create-theme.md +70 -0
  32. package/claude/commands/do/mock-data.md +67 -0
  33. package/claude/commands/do/reset-db.md +71 -0
  34. package/claude/commands/do/setup-scheduled-action.md +75 -0
  35. package/claude/commands/do/sync-code-review.md +117 -0
  36. package/claude/commands/do/update-selectors.md +112 -0
  37. package/claude/commands/do/use-skills.md +90 -0
  38. package/claude/commands/do/validate-blocks.md +69 -0
  39. package/claude/commands/how-to/README.md +261 -0
  40. package/claude/commands/how-to/add-metadata.md +692 -0
  41. package/claude/commands/how-to/add-taxonomies.md +806 -0
  42. package/claude/commands/how-to/add-translations.md +571 -0
  43. package/claude/commands/how-to/create-api.md +577 -0
  44. package/claude/commands/how-to/create-block.md +575 -0
  45. package/claude/commands/how-to/create-child-entities.md +771 -0
  46. package/claude/commands/how-to/create-entity.md +597 -0
  47. package/claude/commands/how-to/create-migrations.md +605 -0
  48. package/claude/commands/how-to/create-plugin.md +654 -0
  49. package/claude/commands/how-to/customize-app.md +481 -0
  50. package/claude/commands/how-to/customize-dashboard.md +553 -0
  51. package/claude/commands/how-to/customize-theme.md +438 -0
  52. package/claude/commands/how-to/define-features-flows.md +632 -0
  53. package/claude/commands/how-to/deploy.md +507 -0
  54. package/claude/commands/how-to/handle-file-uploads.md +681 -0
  55. package/claude/commands/how-to/implement-search.md +1001 -0
  56. package/claude/commands/how-to/install-plugins.md +352 -0
  57. package/claude/commands/how-to/manage-test-coverage.md +984 -0
  58. package/claude/commands/how-to/run-tests.md +400 -0
  59. package/claude/commands/how-to/set-app-languages.md +601 -0
  60. package/claude/commands/how-to/set-plans-and-permissions.md +575 -0
  61. package/claude/commands/how-to/set-scheduled-actions.md +527 -0
  62. package/claude/commands/how-to/set-user-roles-and-permissions.md +550 -0
  63. package/claude/commands/how-to/setup-authentication.md +388 -0
  64. package/claude/commands/how-to/setup-claude-code.md +512 -0
  65. package/claude/commands/how-to/setup-database.md +274 -0
  66. package/claude/commands/how-to/setup-email-providers.md +598 -0
  67. package/claude/commands/how-to/setup-mobile-dev.md +627 -0
  68. package/claude/commands/how-to/start.md +455 -0
  69. package/claude/commands/how-to/use-devtools.md +639 -0
  70. package/claude/commands/how-to/use-superadmin.md +622 -0
  71. package/claude/commands/session/README.md +193 -0
  72. package/claude/commands/session/block-create.md +190 -0
  73. package/claude/commands/session/block-list.md +203 -0
  74. package/claude/commands/session/block-update.md +192 -0
  75. package/claude/commands/session/block-validate.md +218 -0
  76. package/claude/commands/session/close.md +146 -0
  77. package/claude/commands/session/commit.md +174 -0
  78. package/claude/commands/session/db-entity.md +206 -0
  79. package/claude/commands/session/db-fix.md +212 -0
  80. package/claude/commands/session/db-sample.md +206 -0
  81. package/claude/commands/session/demo.md +178 -0
  82. package/claude/commands/session/doc-bdd.md +207 -0
  83. package/claude/commands/session/doc-feature.md +218 -0
  84. package/claude/commands/session/doc-read.md +225 -0
  85. package/claude/commands/session/execute.md +204 -0
  86. package/claude/commands/session/explain.md +202 -0
  87. package/claude/commands/session/fix-bug.md +210 -0
  88. package/claude/commands/session/fix-build.md +182 -0
  89. package/claude/commands/session/fix-test.md +189 -0
  90. package/claude/commands/session/pending.md +232 -0
  91. package/claude/commands/session/refine.md +188 -0
  92. package/claude/commands/session/resume.md +192 -0
  93. package/claude/commands/session/review.md +192 -0
  94. package/claude/commands/session/scope-change.md +181 -0
  95. package/claude/commands/session/start-blocks.md +347 -0
  96. package/claude/commands/session/start.md +476 -0
  97. package/claude/commands/session/status.md +169 -0
  98. package/claude/commands/session/test-fix.md +221 -0
  99. package/claude/commands/session/test-run.md +203 -0
  100. package/claude/commands/session/test-write.md +242 -0
  101. package/claude/commands/session/validate.md +162 -0
  102. package/claude/config/context.json +54 -0
  103. package/claude/config/github.json +69 -0
  104. package/claude/config/github.schema.json +106 -0
  105. package/claude/config/team.json +46 -0
  106. package/claude/config/team.schema.json +106 -0
  107. package/claude/config/workspace.json +49 -0
  108. package/claude/config/workspace.schema.json +64 -0
  109. package/claude/scripts/.gitkeep +0 -0
  110. package/claude/sessions/.gitkeep +0 -0
  111. package/claude/skills/README.md +228 -0
  112. package/claude/skills/accessibility/SKILL.md +573 -0
  113. package/claude/skills/api-bypass-layers/SKILL.md +550 -0
  114. package/claude/skills/asana-integration/SKILL.md +499 -0
  115. package/claude/skills/better-auth/SKILL.md +666 -0
  116. package/claude/skills/billing-subscriptions/SKILL.md +660 -0
  117. package/claude/skills/block-decision-matrix/SKILL.md +359 -0
  118. package/claude/skills/clickup-integration/SKILL.md +434 -0
  119. package/claude/skills/core-theme-responsibilities/SKILL.md +485 -0
  120. package/claude/skills/create-plugin/SKILL.md +425 -0
  121. package/claude/skills/create-theme/SKILL.md +331 -0
  122. package/claude/skills/cypress-api/SKILL.md +511 -0
  123. package/claude/skills/cypress-api/scripts/generate-api-controller.py +329 -0
  124. package/claude/skills/cypress-api/scripts/generate-api-test.py +930 -0
  125. package/claude/skills/cypress-e2e/SKILL.md +526 -0
  126. package/claude/skills/cypress-e2e/scripts/extract-selectors.py +383 -0
  127. package/claude/skills/cypress-e2e/scripts/generate-uat-test.py +788 -0
  128. package/claude/skills/cypress-selectors/SKILL.md +309 -0
  129. package/claude/skills/cypress-selectors/scripts/extract-missing.py +243 -0
  130. package/claude/skills/cypress-selectors/scripts/generate-block-selectors.py +283 -0
  131. package/claude/skills/cypress-selectors/scripts/validate-selectors.py +145 -0
  132. package/claude/skills/database-migrations/SKILL.md +335 -0
  133. package/claude/skills/database-migrations/scripts/generate-sample-data.py +284 -0
  134. package/claude/skills/database-migrations/scripts/validate-migration.py +323 -0
  135. package/claude/skills/design-system/SKILL.md +682 -0
  136. package/claude/skills/documentation/SKILL.md +540 -0
  137. package/claude/skills/entity-api/SKILL.md +482 -0
  138. package/claude/skills/entity-system/SKILL.md +635 -0
  139. package/claude/skills/entity-system/scripts/generate-child-migration.py +298 -0
  140. package/claude/skills/entity-system/scripts/generate-metas-migration.py +233 -0
  141. package/claude/skills/entity-system/scripts/generate-migration.py +382 -0
  142. package/claude/skills/entity-system/scripts/generate-sample-data.py +418 -0
  143. package/claude/skills/entity-system/scripts/scaffold-entity.py +661 -0
  144. package/claude/skills/github/SKILL.md +467 -0
  145. package/claude/skills/i18n-nextintl/SKILL.md +302 -0
  146. package/claude/skills/i18n-nextintl/scripts/add-translation.py +243 -0
  147. package/claude/skills/i18n-nextintl/scripts/extract-hardcoded.py +246 -0
  148. package/claude/skills/i18n-nextintl/scripts/validate-translations.py +260 -0
  149. package/claude/skills/impact-analysis/SKILL.md +203 -0
  150. package/claude/skills/jest-unit/SKILL.md +306 -0
  151. package/claude/skills/jest-unit/references/component-testing.md +371 -0
  152. package/claude/skills/jest-unit/references/mocking-patterns.md +380 -0
  153. package/claude/skills/jest-unit/references/service-hook-testing.md +454 -0
  154. package/claude/skills/jira-integration/SKILL.md +539 -0
  155. package/claude/skills/mock-analysis/SKILL.md +276 -0
  156. package/claude/skills/monorepo-architecture/SKILL.md +162 -0
  157. package/claude/skills/nextjs-api-development/SKILL.md +364 -0
  158. package/claude/skills/nextjs-api-development/scripts/generate-crud-tests.py +456 -0
  159. package/claude/skills/nextjs-api-development/scripts/scaffold-endpoint.py +481 -0
  160. package/claude/skills/nextjs-api-development/scripts/validate-api.py +283 -0
  161. package/claude/skills/notion-integration/SKILL.md +641 -0
  162. package/claude/skills/npm-development-workflow/SKILL.md +480 -0
  163. package/claude/skills/page-builder-blocks/SKILL.md +483 -0
  164. package/claude/skills/page-builder-blocks/scripts/scaffold-block.py +444 -0
  165. package/claude/skills/permissions-system/SKILL.md +619 -0
  166. package/claude/skills/plugins/SKILL.md +340 -0
  167. package/claude/skills/plugins/references/plugin-templates.md +414 -0
  168. package/claude/skills/plugins/references/plugin-testing.md +353 -0
  169. package/claude/skills/plugins/references/plugin-types.md +198 -0
  170. package/claude/skills/plugins/scripts/scaffold-plugin.py +443 -0
  171. package/claude/skills/pom-patterns/SKILL.md +452 -0
  172. package/claude/skills/pom-patterns/scripts/generate-pom.py +392 -0
  173. package/claude/skills/rate-limiting/SKILL.md +342 -0
  174. package/claude/skills/react-best-practices/AGENTS.md +2410 -0
  175. package/claude/skills/react-best-practices/README.md +123 -0
  176. package/claude/skills/react-best-practices/SKILL.md +125 -0
  177. package/claude/skills/react-best-practices/metadata.json +15 -0
  178. package/claude/skills/react-best-practices/rules/_sections.md +46 -0
  179. package/claude/skills/react-best-practices/rules/_template.md +28 -0
  180. package/claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  181. package/claude/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
  182. package/claude/skills/react-best-practices/rules/async-api-routes.md +38 -0
  183. package/claude/skills/react-best-practices/rules/async-defer-await.md +80 -0
  184. package/claude/skills/react-best-practices/rules/async-dependencies.md +36 -0
  185. package/claude/skills/react-best-practices/rules/async-parallel.md +28 -0
  186. package/claude/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
  187. package/claude/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
  188. package/claude/skills/react-best-practices/rules/bundle-conditional.md +31 -0
  189. package/claude/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
  190. package/claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  191. package/claude/skills/react-best-practices/rules/bundle-preload.md +50 -0
  192. package/claude/skills/react-best-practices/rules/client-event-listeners.md +74 -0
  193. package/claude/skills/react-best-practices/rules/client-localstorage-schema.md +71 -0
  194. package/claude/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
  195. package/claude/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
  196. package/claude/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
  197. package/claude/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
  198. package/claude/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
  199. package/claude/skills/react-best-practices/rules/js-cache-storage.md +70 -0
  200. package/claude/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
  201. package/claude/skills/react-best-practices/rules/js-early-exit.md +50 -0
  202. package/claude/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
  203. package/claude/skills/react-best-practices/rules/js-index-maps.md +37 -0
  204. package/claude/skills/react-best-practices/rules/js-length-check-first.md +49 -0
  205. package/claude/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
  206. package/claude/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
  207. package/claude/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  208. package/claude/skills/react-best-practices/rules/rendering-activity.md +26 -0
  209. package/claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  210. package/claude/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
  211. package/claude/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
  212. package/claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  213. package/claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  214. package/claude/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
  215. package/claude/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
  216. package/claude/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
  217. package/claude/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
  218. package/claude/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
  219. package/claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  220. package/claude/skills/react-best-practices/rules/rerender-memo.md +44 -0
  221. package/claude/skills/react-best-practices/rules/rerender-transitions.md +40 -0
  222. package/claude/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
  223. package/claude/skills/react-best-practices/rules/server-cache-lru.md +41 -0
  224. package/claude/skills/react-best-practices/rules/server-cache-react.md +76 -0
  225. package/claude/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
  226. package/claude/skills/react-best-practices/rules/server-serialization.md +38 -0
  227. package/claude/skills/react-patterns/SKILL.md +677 -0
  228. package/claude/skills/registry-system/SKILL.md +331 -0
  229. package/claude/skills/scheduled-actions/SKILL.md +431 -0
  230. package/claude/skills/scope-enforcement/SKILL.md +542 -0
  231. package/claude/skills/scope-enforcement/scripts/validate-scope.py +357 -0
  232. package/claude/skills/server-actions/SKILL.md +493 -0
  233. package/claude/skills/service-layer/SKILL.md +587 -0
  234. package/claude/skills/session-management/SKILL.md +266 -0
  235. package/claude/skills/session-management/scripts/create-session.py +166 -0
  236. package/claude/skills/session-management/scripts/iteration-close.sh +105 -0
  237. package/claude/skills/session-management/scripts/iteration-init.sh +180 -0
  238. package/claude/skills/session-management/scripts/session-archive.sh +87 -0
  239. package/claude/skills/session-management/scripts/session-close.sh +133 -0
  240. package/claude/skills/session-management/scripts/session-init.sh +225 -0
  241. package/claude/skills/session-management/scripts/session-list.sh +163 -0
  242. package/claude/skills/session-management/scripts/split-plan.sh +116 -0
  243. package/claude/skills/shadcn-components/SKILL.md +586 -0
  244. package/claude/skills/shadcn-theming/SKILL.md +446 -0
  245. package/claude/skills/suspense-loading/SKILL.md +280 -0
  246. package/claude/skills/tailwind-theming/SKILL.md +479 -0
  247. package/claude/skills/tanstack-query/SKILL.md +608 -0
  248. package/claude/skills/test-coverage/SKILL.md +239 -0
  249. package/claude/skills/web-design-guidelines/SKILL.md +39 -0
  250. package/claude/skills/zod-validation/SKILL.md +537 -0
  251. package/claude/templates/blocks/progress.md +86 -0
  252. package/claude/templates/iteration/changes.md +61 -0
  253. package/claude/templates/iteration/progress.md +55 -0
  254. package/claude/templates/log.md +31 -0
  255. package/claude/templates/story/context.md +77 -0
  256. package/claude/templates/story/pendings.md +37 -0
  257. package/claude/templates/story/plan.md +299 -0
  258. package/claude/templates/story/requirements.md +109 -0
  259. package/claude/templates/story/scope.json +10 -0
  260. package/claude/templates/story/tests.md +91 -0
  261. package/claude/templates/task/progress.md +58 -0
  262. package/claude/templates/task/requirements.md +54 -0
  263. package/claude/workflows/README.md +154 -0
  264. package/claude/workflows/blocks.md +614 -0
  265. package/claude/workflows/story.md +1207 -0
  266. package/claude/workflows/task.md +927 -0
  267. package/claude/workflows/tweak.md +527 -0
  268. package/cursor/.gitkeep +0 -0
  269. package/package.json +34 -0
  270. package/scripts/setup.mjs +282 -0
  271. package/scripts/sync.mjs +209 -0
@@ -0,0 +1,353 @@
1
+ # Plugin Testing Reference
2
+
3
+ Testing patterns for plugins: unit tests, E2E tests, and Page Object Models.
4
+
5
+ ## Unit Tests (Jest)
6
+
7
+ ### Core Plugin Logic
8
+
9
+ ```typescript
10
+ // contents/plugins/my-plugin/__tests__/my-plugin.test.ts
11
+ import { MyPluginCore } from '../lib/core'
12
+
13
+ describe('MyPluginCore', () => {
14
+ let core: MyPluginCore
15
+
16
+ beforeEach(() => {
17
+ core = new MyPluginCore({
18
+ apiKey: 'test-key',
19
+ timeout: 5000,
20
+ maxRetries: 3
21
+ })
22
+ })
23
+
24
+ describe('initialization', () => {
25
+ it('should initialize with valid config', async () => {
26
+ await expect(core.initialize()).resolves.not.toThrow()
27
+ })
28
+
29
+ it('should throw with invalid config', async () => {
30
+ const invalid = new MyPluginCore({ apiKey: '' })
31
+ await expect(invalid.initialize()).rejects.toThrow()
32
+ })
33
+ })
34
+
35
+ describe('processing', () => {
36
+ it('should process valid input', async () => {
37
+ await core.initialize()
38
+ const result = await core.process({ data: 'test' })
39
+ expect(result.success).toBe(true)
40
+ })
41
+
42
+ it('should handle errors gracefully', async () => {
43
+ await core.initialize()
44
+ const result = await core.process({ data: '' })
45
+ expect(result.success).toBe(false)
46
+ expect(result.error).toBeDefined()
47
+ })
48
+ })
49
+ })
50
+ ```
51
+
52
+ ### Hook Testing
53
+
54
+ ```typescript
55
+ // contents/plugins/my-plugin/__tests__/hooks.test.ts
56
+ import { renderHook, waitFor } from '@testing-library/react'
57
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
58
+ import { useMyPlugin } from '../hooks/useMyPlugin'
59
+
60
+ const createWrapper = () => {
61
+ const queryClient = new QueryClient({
62
+ defaultOptions: { queries: { retry: false } }
63
+ })
64
+ return ({ children }: { children: React.ReactNode }) => (
65
+ <QueryClientProvider client={queryClient}>
66
+ {children}
67
+ </QueryClientProvider>
68
+ )
69
+ }
70
+
71
+ describe('useMyPlugin', () => {
72
+ beforeEach(() => {
73
+ global.fetch = jest.fn()
74
+ })
75
+
76
+ it('should fetch data successfully', async () => {
77
+ (global.fetch as jest.Mock).mockResolvedValueOnce({
78
+ ok: true,
79
+ json: async () => ({ data: 'test' })
80
+ })
81
+
82
+ const { result } = renderHook(() => useMyPlugin(), {
83
+ wrapper: createWrapper()
84
+ })
85
+
86
+ await waitFor(() => {
87
+ expect(result.current.isSuccess).toBe(true)
88
+ })
89
+
90
+ expect(result.current.data).toEqual({ data: 'test' })
91
+ })
92
+
93
+ it('should handle fetch error', async () => {
94
+ (global.fetch as jest.Mock).mockResolvedValueOnce({
95
+ ok: false
96
+ })
97
+
98
+ const { result } = renderHook(() => useMyPlugin(), {
99
+ wrapper: createWrapper()
100
+ })
101
+
102
+ await waitFor(() => {
103
+ expect(result.current.isError).toBe(true)
104
+ })
105
+ })
106
+ })
107
+ ```
108
+
109
+ ### Component Testing
110
+
111
+ ```typescript
112
+ // contents/plugins/my-plugin/__tests__/MyWidget.test.tsx
113
+ import { render, screen, fireEvent } from '@testing-library/react'
114
+ import { MyWidget } from '../components/MyWidget'
115
+
116
+ // Mock the hook
117
+ jest.mock('../hooks/useMyPlugin', () => ({
118
+ useMyPlugin: () => ({
119
+ data: { value: 'test data' },
120
+ isLoading: false,
121
+ error: null
122
+ })
123
+ }))
124
+
125
+ describe('MyWidget', () => {
126
+ it('should render widget with title', () => {
127
+ render(<MyWidget title="Test Title" />)
128
+ expect(screen.getByText('Test Title')).toBeInTheDocument()
129
+ })
130
+
131
+ it('should display content when data is loaded', () => {
132
+ render(<MyWidget title="Test" />)
133
+ expect(screen.getByTestId('my-plugin-content')).toBeInTheDocument()
134
+ })
135
+
136
+ it('should call onAction when button is clicked', () => {
137
+ const onAction = jest.fn()
138
+ render(<MyWidget title="Test" onAction={onAction} />)
139
+
140
+ fireEvent.click(screen.getByTestId('my-plugin-action-btn'))
141
+ expect(onAction).toHaveBeenCalledTimes(1)
142
+ })
143
+ })
144
+ ```
145
+
146
+ ---
147
+
148
+ ## E2E Tests (Cypress)
149
+
150
+ ### Basic E2E Test
151
+
152
+ ```typescript
153
+ // contents/themes/default/tests/cypress/e2e/uat/my-plugin.cy.ts
154
+ import { MyPluginPOM } from '../../src/features/MyPluginPOM'
155
+
156
+ describe('My Plugin E2E', {
157
+ tags: ['@uat', '@feat-my-plugin', '@smoke']
158
+ }, () => {
159
+ let pom: MyPluginPOM
160
+
161
+ beforeEach(() => {
162
+ cy.session('plugin-test', () => {
163
+ cy.login('testuser@example.com', 'password123')
164
+ })
165
+ cy.visit('/dashboard')
166
+ pom = new MyPluginPOM()
167
+ })
168
+
169
+ it('should display plugin widget', () => {
170
+ pom.shouldBeVisible()
171
+ pom.shouldHaveTitle('My Plugin')
172
+ })
173
+
174
+ it('should complete full workflow', () => {
175
+ pom.shouldBeVisible()
176
+ pom.enterData('test data')
177
+ pom.clickProcessButton()
178
+ pom.shouldShowSuccess()
179
+ })
180
+
181
+ it('should handle errors gracefully', () => {
182
+ pom.enterData('') // Invalid input
183
+ pom.clickProcessButton()
184
+ pom.shouldShowError('Validation error')
185
+ })
186
+ })
187
+ ```
188
+
189
+ ### Page Object Model
190
+
191
+ ```typescript
192
+ // contents/themes/default/tests/cypress/src/features/MyPluginPOM.ts
193
+ import { BasePOM } from '../BasePOM'
194
+
195
+ export class MyPluginPOM extends BasePOM {
196
+ private selectors = {
197
+ widget: '[data-cy="my-plugin-widget"]',
198
+ title: '[data-cy="my-plugin-title"]',
199
+ input: '[data-cy="my-plugin-input"]',
200
+ processBtn: '[data-cy="my-plugin-action-btn"]',
201
+ loading: '[data-cy="my-plugin-loading"]',
202
+ success: '[data-cy="my-plugin-success"]',
203
+ error: '[data-cy="my-plugin-error"]',
204
+ content: '[data-cy="my-plugin-content"]'
205
+ }
206
+
207
+ // Assertions
208
+ shouldBeVisible() {
209
+ cy.get(this.selectors.widget).should('be.visible')
210
+ return this
211
+ }
212
+
213
+ shouldHaveTitle(title: string) {
214
+ cy.get(this.selectors.title).should('contain', title)
215
+ return this
216
+ }
217
+
218
+ shouldShowSuccess() {
219
+ cy.get(this.selectors.success).should('be.visible')
220
+ return this
221
+ }
222
+
223
+ shouldShowError(message: string) {
224
+ cy.get(this.selectors.error)
225
+ .should('be.visible')
226
+ .and('contain', message)
227
+ return this
228
+ }
229
+
230
+ shouldShowLoading() {
231
+ cy.get(this.selectors.loading).should('be.visible')
232
+ return this
233
+ }
234
+
235
+ // Actions
236
+ enterData(data: string) {
237
+ cy.get(this.selectors.input).clear().type(data)
238
+ return this
239
+ }
240
+
241
+ clickProcessButton() {
242
+ cy.get(this.selectors.processBtn).click()
243
+ return this
244
+ }
245
+
246
+ // Waits
247
+ waitForLoading() {
248
+ cy.get(this.selectors.loading).should('not.exist')
249
+ return this
250
+ }
251
+
252
+ waitForContent() {
253
+ cy.get(this.selectors.content).should('be.visible')
254
+ return this
255
+ }
256
+ }
257
+ ```
258
+
259
+ ---
260
+
261
+ ## API Tests (Cypress)
262
+
263
+ ```typescript
264
+ // contents/themes/default/tests/cypress/e2e/api/my-plugin-api.cy.ts
265
+ import { BaseAPIController } from '../../src/controllers/BaseAPIController'
266
+
267
+ describe('My Plugin API', {
268
+ tags: ['@api', '@feat-my-plugin']
269
+ }, () => {
270
+ const BASE_URL = Cypress.env('API_URL')
271
+ const API_KEY = Cypress.env('SUPERADMIN_API_KEY')
272
+ let api: BaseAPIController
273
+
274
+ before(() => {
275
+ api = new BaseAPIController(BASE_URL, API_KEY)
276
+ })
277
+
278
+ describe('POST /api/plugin/my-plugin/process', () => {
279
+ it('should process valid input', () => {
280
+ cy.request({
281
+ method: 'POST',
282
+ url: `${BASE_URL}/api/plugin/my-plugin/process`,
283
+ headers: {
284
+ 'Authorization': `Bearer ${API_KEY}`,
285
+ 'Content-Type': 'application/json'
286
+ },
287
+ body: {
288
+ data: 'test input'
289
+ }
290
+ }).then((response) => {
291
+ expect(response.status).to.eq(200)
292
+ expect(response.body.success).to.be.true
293
+ expect(response.body.data).to.exist
294
+ })
295
+ })
296
+
297
+ it('should reject invalid input', () => {
298
+ cy.request({
299
+ method: 'POST',
300
+ url: `${BASE_URL}/api/plugin/my-plugin/process`,
301
+ headers: {
302
+ 'Authorization': `Bearer ${API_KEY}`,
303
+ 'Content-Type': 'application/json'
304
+ },
305
+ body: {
306
+ data: '' // Invalid
307
+ },
308
+ failOnStatusCode: false
309
+ }).then((response) => {
310
+ expect(response.status).to.eq(400)
311
+ expect(response.body.success).to.be.false
312
+ })
313
+ })
314
+
315
+ it('should require authentication', () => {
316
+ cy.request({
317
+ method: 'POST',
318
+ url: `${BASE_URL}/api/plugin/my-plugin/process`,
319
+ body: { data: 'test' },
320
+ failOnStatusCode: false
321
+ }).then((response) => {
322
+ expect(response.status).to.eq(401)
323
+ })
324
+ })
325
+ })
326
+ })
327
+ ```
328
+
329
+ ---
330
+
331
+ ## Coverage Requirements
332
+
333
+ | Test Type | Minimum Coverage | Target |
334
+ |-----------|------------------|--------|
335
+ | Unit Tests (Jest) | 80% | 90% |
336
+ | E2E Tests (Cypress) | Critical paths | Happy + Error paths |
337
+ | API Tests | All endpoints | All methods + auth |
338
+
339
+ ### Running Tests
340
+
341
+ ```bash
342
+ # Unit tests
343
+ pnpm test --filter=@nextsparkjs/plugin-my-plugin
344
+
345
+ # E2E tests
346
+ pnpm cypress:run --spec "**/my-plugin.cy.ts"
347
+
348
+ # API tests
349
+ pnpm cypress:run --spec "**/my-plugin-api.cy.ts"
350
+
351
+ # All plugin tests
352
+ pnpm test:plugin my-plugin
353
+ ```
@@ -0,0 +1,198 @@
1
+ # Plugin Types Reference
2
+
3
+ Detailed structures and examples for each plugin type.
4
+
5
+ ## 1. Utility Plugin
6
+
7
+ Simple utilities and helper functions. Minimal structure.
8
+
9
+ ```
10
+ my-utility-plugin/
11
+ ├── package.json
12
+ ├── plugin.config.ts
13
+ ├── README.md
14
+ ├── .env.example
15
+ ├── lib/
16
+ │ ├── utils.ts
17
+ │ └── helpers.ts
18
+ └── types/
19
+ └── utility.types.ts
20
+ ```
21
+
22
+ ### Example: String Utilities Plugin
23
+
24
+ ```typescript
25
+ // plugin.config.ts
26
+ export const stringUtilsConfig: PluginConfig = {
27
+ name: 'string-utils',
28
+ version: '1.0.0',
29
+ displayName: 'String Utilities',
30
+ description: 'Common string manipulation functions',
31
+ enabled: true,
32
+ dependencies: [],
33
+ services: {
34
+ capitalize: undefined,
35
+ slugify: undefined,
36
+ truncate: undefined
37
+ }
38
+ }
39
+
40
+ // lib/utils.ts
41
+ export function capitalize(str: string): string {
42
+ return str.charAt(0).toUpperCase() + str.slice(1)
43
+ }
44
+
45
+ export function slugify(str: string): string {
46
+ return str.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]/g, '')
47
+ }
48
+
49
+ export function truncate(str: string, length: number): string {
50
+ return str.length > length ? str.slice(0, length) + '...' : str
51
+ }
52
+ ```
53
+
54
+ ---
55
+
56
+ ## 2. Service Plugin
57
+
58
+ Feature-rich plugins with full stack integration including components, hooks, API endpoints.
59
+
60
+ ```
61
+ my-service-plugin/
62
+ ├── package.json
63
+ ├── plugin.config.ts
64
+ ├── README.md
65
+ ├── .env.example
66
+ ├── types/
67
+ │ └── plugin.types.ts
68
+ ├── lib/
69
+ │ ├── core.ts
70
+ │ └── client.ts
71
+ ├── hooks/
72
+ │ └── usePlugin.ts
73
+ ├── components/
74
+ │ ├── PluginWidget.tsx
75
+ │ └── PluginSettings.tsx
76
+ ├── providers/
77
+ │ └── PluginProvider.tsx
78
+ ├── api/
79
+ │ ├── data/route.ts
80
+ │ └── process/route.ts
81
+ ├── entities/ # If plugin has its own entities
82
+ │ └── my-entity/
83
+ │ ├── messages/
84
+ │ └── migrations/
85
+ └── docs/
86
+ └── 01-getting-started/
87
+ ```
88
+
89
+ ### Example: AI Chat Plugin
90
+
91
+ ```typescript
92
+ // plugin.config.ts
93
+ export const aiChatConfig: PluginConfig = {
94
+ name: 'ai-chat',
95
+ version: '1.0.0',
96
+ displayName: 'AI Chat',
97
+ description: 'AI-powered chat functionality',
98
+ enabled: true,
99
+ dependencies: [],
100
+
101
+ components: {
102
+ ChatWidget: undefined,
103
+ ChatHistory: undefined,
104
+ ChatInput: undefined
105
+ },
106
+
107
+ services: {
108
+ useChat: undefined,
109
+ useChatHistory: undefined
110
+ },
111
+
112
+ hooks: {
113
+ async onLoad() {
114
+ console.log('[AI Chat] Validating API keys...')
115
+ },
116
+ async onActivate() {
117
+ console.log('[AI Chat] Initializing chat service...')
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
123
+ ---
124
+
125
+ ## 3. Configuration Plugin
126
+
127
+ Settings and configuration management. Focuses on schema validation and persistence.
128
+
129
+ ```
130
+ my-config-plugin/
131
+ ├── package.json
132
+ ├── plugin.config.ts
133
+ ├── README.md
134
+ ├── .env.example
135
+ ├── lib/
136
+ │ ├── config-loader.ts
137
+ │ └── config-validator.ts
138
+ ├── types/
139
+ │ └── config.types.ts
140
+ ├── schemas/
141
+ │ └── settings.schema.ts
142
+ └── components/
143
+ └── SettingsForm.tsx
144
+ ```
145
+
146
+ ### Example: Theme Configuration Plugin
147
+
148
+ ```typescript
149
+ // plugin.config.ts
150
+ export const themeConfigPlugin: PluginConfig = {
151
+ name: 'theme-config',
152
+ version: '1.0.0',
153
+ displayName: 'Theme Configuration',
154
+ description: 'Manage theme colors, fonts, and styling',
155
+ enabled: true,
156
+ dependencies: [],
157
+
158
+ components: {
159
+ ThemeSettings: undefined,
160
+ ColorPicker: undefined,
161
+ FontSelector: undefined
162
+ },
163
+
164
+ services: {
165
+ useThemeConfig: undefined,
166
+ useUpdateTheme: undefined
167
+ }
168
+ }
169
+
170
+ // schemas/settings.schema.ts
171
+ import { z } from 'zod'
172
+
173
+ export const ThemeSettingsSchema = z.object({
174
+ primaryColor: z.string().regex(/^#[0-9A-F]{6}$/i),
175
+ secondaryColor: z.string().regex(/^#[0-9A-F]{6}$/i),
176
+ fontFamily: z.enum(['inter', 'roboto', 'poppins']),
177
+ fontSize: z.enum(['sm', 'md', 'lg']),
178
+ borderRadius: z.number().min(0).max(24)
179
+ })
180
+
181
+ export type ThemeSettings = z.infer<typeof ThemeSettingsSchema>
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Choosing the Right Type
187
+
188
+ | Requirement | Utility | Service | Configuration |
189
+ |-------------|---------|---------|---------------|
190
+ | Pure functions only | ✅ | ❌ | ❌ |
191
+ | UI components | ❌ | ✅ | ✅ |
192
+ | API endpoints | ❌ | ✅ | ⚠️ |
193
+ | Database entities | ❌ | ✅ | ⚠️ |
194
+ | User settings | ❌ | ⚠️ | ✅ |
195
+ | External API integration | ⚠️ | ✅ | ❌ |
196
+ | Real-time features | ❌ | ✅ | ❌ |
197
+
198
+ Legend: ✅ Primary use case | ⚠️ Possible but not typical | ❌ Not appropriate