@skyroc/scripts 2.5.1 → 2.5.3

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 (275) hide show
  1. package/README.md +6 -3
  2. package/dist/cli.mjs +2 -2
  3. package/dist/{config-BKkdncJS.mjs → config-DWrHl2hS.mjs} +106 -5
  4. package/dist/index.mjs +1 -1
  5. package/package.json +1 -1
  6. package/templates/admin/README.md +1 -2
  7. package/templates/admin/package.json +9 -2
  8. package/templates/admin/src/App.tsx +2 -2
  9. package/templates/admin/src/assets/svg-icon/logo.svg +1 -1
  10. package/templates/admin/src/config.ts +1 -1
  11. package/templates/admin/src/main.tsx +1 -1
  12. package/templates/admin/uno.config.ts +1 -1
  13. package/templates/admin-root/.agents/skills/component-doc/SKILL.md +304 -0
  14. package/templates/admin-root/.agents/skills/component-refactoring/SKILL.md +483 -0
  15. package/templates/admin-root/.agents/skills/component-refactoring/references/complexity-patterns.md +493 -0
  16. package/templates/admin-root/.agents/skills/component-refactoring/references/component-splitting.md +477 -0
  17. package/templates/admin-root/.agents/skills/component-refactoring/references/hook-extraction.md +317 -0
  18. package/templates/admin-root/.agents/skills/doc-coauthoring/SKILL.md +375 -0
  19. package/templates/admin-root/.agents/skills/feature-dev/SKILL.md +78 -0
  20. package/templates/admin-root/.agents/skills/frontend-code-review/SKILL.md +73 -0
  21. package/templates/admin-root/.agents/skills/frontend-code-review/references/business-logic.md +15 -0
  22. package/templates/admin-root/.agents/skills/frontend-code-review/references/code-quality.md +44 -0
  23. package/templates/admin-root/.agents/skills/frontend-code-review/references/performance.md +45 -0
  24. package/templates/admin-root/.agents/skills/frontend-design/LICENSE.txt +177 -0
  25. package/templates/admin-root/.agents/skills/frontend-design/SKILL.md +42 -0
  26. package/templates/admin-root/.agents/skills/frontend-testing/SKILL.md +325 -0
  27. package/templates/admin-root/.agents/skills/frontend-testing/assets/component-test.template.tsx +293 -0
  28. package/templates/admin-root/.agents/skills/frontend-testing/assets/hook-test.template.ts +207 -0
  29. package/templates/admin-root/.agents/skills/frontend-testing/assets/utility-test.template.ts +154 -0
  30. package/templates/admin-root/.agents/skills/frontend-testing/references/async-testing.md +345 -0
  31. package/templates/admin-root/.agents/skills/frontend-testing/references/checklist.md +205 -0
  32. package/templates/admin-root/.agents/skills/frontend-testing/references/common-patterns.md +449 -0
  33. package/templates/admin-root/.agents/skills/frontend-testing/references/domain-components.md +523 -0
  34. package/templates/admin-root/.agents/skills/frontend-testing/references/mocking.md +512 -0
  35. package/templates/admin-root/.agents/skills/frontend-testing/references/workflow.md +269 -0
  36. package/templates/admin-root/.agents/skills/migrate-nativewind-to-uniwind/SKILL.md +734 -0
  37. package/templates/admin-root/.agents/skills/migrate-oxfmt/SKILL.md +202 -0
  38. package/templates/admin-root/.agents/skills/migrate-oxlint/SKILL.md +196 -0
  39. package/templates/admin-root/.agents/skills/native-component-doc/SKILL.md +245 -0
  40. package/templates/admin-root/.agents/skills/senior-frontend/SKILL.md +209 -0
  41. package/templates/admin-root/.agents/skills/senior-frontend/references/frontend_best_practices.md +103 -0
  42. package/templates/admin-root/.agents/skills/senior-frontend/references/nextjs_optimization_guide.md +103 -0
  43. package/templates/admin-root/.agents/skills/senior-frontend/references/react_patterns.md +103 -0
  44. package/templates/admin-root/.agents/skills/senior-frontend/scripts/bundle_analyzer.py +114 -0
  45. package/templates/admin-root/.agents/skills/senior-frontend/scripts/component_generator.py +114 -0
  46. package/templates/admin-root/.agents/skills/senior-frontend/scripts/frontend_scaffolder.py +114 -0
  47. package/templates/admin-root/.agents/skills/skill-creator/SKILL.md +355 -0
  48. package/templates/admin-root/.agents/skills/skill-creator/references/output-patterns.md +86 -0
  49. package/templates/admin-root/.agents/skills/skill-creator/references/workflows.md +28 -0
  50. package/templates/admin-root/.agents/skills/skill-creator/scripts/init_skill.py +300 -0
  51. package/templates/admin-root/.agents/skills/skill-creator/scripts/package_skill.py +110 -0
  52. package/templates/admin-root/.agents/skills/skill-creator/scripts/quick_validate.py +97 -0
  53. package/templates/admin-root/.agents/skills/skyroc-admin-prd-prototype/SKILL.md +163 -0
  54. package/templates/admin-root/.agents/skills/skyroc-admin-prd-prototype/references/acceptance-checklist.md +75 -0
  55. package/templates/admin-root/.agents/skills/skyroc-admin-prd-prototype/references/evidence-order.md +109 -0
  56. package/templates/admin-root/.agents/skills/skyroc-admin-prd-prototype/references/prd-rules.md +103 -0
  57. package/templates/admin-root/.agents/skills/skyroc-admin-prd-prototype/references/prototype-rules.md +85 -0
  58. package/templates/admin-root/.agents/skills/skyroc-admin-prd-prototype/scripts/verify-prototypes.mjs +144 -0
  59. package/templates/admin-root/.agents/skills/skyroc-admin-prd-prototype/templates/admin-page.html +771 -0
  60. package/templates/admin-root/.agents/skills/skyroc-admin-prd-prototype/templates/prd.md +182 -0
  61. package/templates/admin-root/.agents/skills/ui-ux-pro-max/SKILL.md +292 -0
  62. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/charts.csv +26 -0
  63. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/colors.csv +97 -0
  64. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/icons.csv +101 -0
  65. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/landing.csv +31 -0
  66. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/products.csv +97 -0
  67. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  68. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  69. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  70. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  71. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  72. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  73. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  74. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  75. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  76. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  77. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  78. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  79. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  80. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  81. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/styles.csv +68 -0
  82. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/typography.csv +58 -0
  83. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  84. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  85. package/templates/admin-root/.agents/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  86. package/templates/admin-root/.agents/skills/ui-ux-pro-max/scripts/core.py +253 -0
  87. package/templates/admin-root/.agents/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
  88. package/templates/admin-root/.agents/skills/ui-ux-pro-max/scripts/search.py +114 -0
  89. package/templates/admin-root/.agents/skills/uniwind/SKILL.md +64 -0
  90. package/templates/admin-root/.agents/skills/uniwind/references/component-bindings.md +338 -0
  91. package/templates/admin-root/.agents/skills/uniwind/references/css-and-utilities.md +325 -0
  92. package/templates/admin-root/.agents/skills/uniwind/references/integrations.md +75 -0
  93. package/templates/admin-root/.agents/skills/uniwind/references/pro.md +354 -0
  94. package/templates/admin-root/.agents/skills/uniwind/references/setup.md +144 -0
  95. package/templates/admin-root/.agents/skills/uniwind/references/styling-patterns.md +237 -0
  96. package/templates/admin-root/.agents/skills/uniwind/references/theming.md +309 -0
  97. package/templates/admin-root/.agents/skills/uniwind/references/troubleshooting.md +179 -0
  98. package/templates/admin-root/.agents/skills/uniwind/references/variants-and-selectors.md +224 -0
  99. package/templates/admin-root/.agents/skills/vercel-react-best-practices/AGENTS.md +2934 -0
  100. package/templates/admin-root/.agents/skills/vercel-react-best-practices/SKILL.md +136 -0
  101. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  102. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
  103. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
  104. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
  105. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
  106. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
  107. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
  108. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
  109. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
  110. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
  111. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  112. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  113. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
  114. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
  115. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
  116. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
  117. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
  118. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
  119. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
  120. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
  121. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
  122. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
  123. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
  124. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
  125. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
  126. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
  127. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
  128. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
  129. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  130. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
  131. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  132. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
  133. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
  134. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  135. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  136. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
  137. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
  138. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  139. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
  140. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
  141. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  142. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
  143. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  144. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  145. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
  146. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
  147. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  148. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  149. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
  150. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  151. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
  152. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
  153. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
  154. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
  155. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
  156. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
  157. package/templates/admin-root/.agents/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
  158. package/templates/admin-root/.claude/settings.json +5 -0
  159. package/templates/admin-root/.claude/skills/component-doc/SKILL.md +304 -0
  160. package/templates/admin-root/.claude/skills/component-refactoring/SKILL.md +483 -0
  161. package/templates/admin-root/.claude/skills/component-refactoring/references/complexity-patterns.md +493 -0
  162. package/templates/admin-root/.claude/skills/component-refactoring/references/component-splitting.md +477 -0
  163. package/templates/admin-root/.claude/skills/component-refactoring/references/hook-extraction.md +317 -0
  164. package/templates/admin-root/.claude/skills/doc-coauthoring/SKILL.md +375 -0
  165. package/templates/admin-root/.claude/skills/feature-dev/SKILL.md +78 -0
  166. package/templates/admin-root/.claude/skills/frontend-code-review/SKILL.md +73 -0
  167. package/templates/admin-root/.claude/skills/frontend-code-review/references/business-logic.md +15 -0
  168. package/templates/admin-root/.claude/skills/frontend-code-review/references/code-quality.md +44 -0
  169. package/templates/admin-root/.claude/skills/frontend-code-review/references/performance.md +45 -0
  170. package/templates/admin-root/.claude/skills/frontend-design/LICENSE.txt +177 -0
  171. package/templates/admin-root/.claude/skills/frontend-design/SKILL.md +42 -0
  172. package/templates/admin-root/.claude/skills/frontend-testing/SKILL.md +325 -0
  173. package/templates/admin-root/.claude/skills/frontend-testing/assets/component-test.template.tsx +293 -0
  174. package/templates/admin-root/.claude/skills/frontend-testing/assets/hook-test.template.ts +207 -0
  175. package/templates/admin-root/.claude/skills/frontend-testing/assets/utility-test.template.ts +154 -0
  176. package/templates/admin-root/.claude/skills/frontend-testing/references/async-testing.md +345 -0
  177. package/templates/admin-root/.claude/skills/frontend-testing/references/checklist.md +205 -0
  178. package/templates/admin-root/.claude/skills/frontend-testing/references/common-patterns.md +449 -0
  179. package/templates/admin-root/.claude/skills/frontend-testing/references/domain-components.md +523 -0
  180. package/templates/admin-root/.claude/skills/frontend-testing/references/mocking.md +512 -0
  181. package/templates/admin-root/.claude/skills/frontend-testing/references/workflow.md +269 -0
  182. package/templates/admin-root/.claude/skills/migrate-nativewind-to-uniwind +1 -0
  183. package/templates/admin-root/.claude/skills/migrate-oxfmt +1 -0
  184. package/templates/admin-root/.claude/skills/migrate-oxlint +1 -0
  185. package/templates/admin-root/.claude/skills/native-component-doc/SKILL.md +245 -0
  186. package/templates/admin-root/.claude/skills/senior-frontend/SKILL.md +209 -0
  187. package/templates/admin-root/.claude/skills/senior-frontend/references/frontend_best_practices.md +103 -0
  188. package/templates/admin-root/.claude/skills/senior-frontend/references/nextjs_optimization_guide.md +103 -0
  189. package/templates/admin-root/.claude/skills/senior-frontend/references/react_patterns.md +103 -0
  190. package/templates/admin-root/.claude/skills/senior-frontend/scripts/bundle_analyzer.py +114 -0
  191. package/templates/admin-root/.claude/skills/senior-frontend/scripts/component_generator.py +114 -0
  192. package/templates/admin-root/.claude/skills/senior-frontend/scripts/frontend_scaffolder.py +114 -0
  193. package/templates/admin-root/.claude/skills/skill-creator/SKILL.md +355 -0
  194. package/templates/admin-root/.claude/skills/skill-creator/references/output-patterns.md +86 -0
  195. package/templates/admin-root/.claude/skills/skill-creator/references/workflows.md +28 -0
  196. package/templates/admin-root/.claude/skills/skill-creator/scripts/init_skill.py +300 -0
  197. package/templates/admin-root/.claude/skills/skill-creator/scripts/package_skill.py +110 -0
  198. package/templates/admin-root/.claude/skills/skill-creator/scripts/quick_validate.py +97 -0
  199. package/templates/admin-root/.claude/skills/ui-ux-pro-max/SKILL.md +386 -0
  200. package/templates/admin-root/.claude/skills/ui-ux-pro-max/data +1 -0
  201. package/templates/admin-root/.claude/skills/ui-ux-pro-max/scripts +1 -0
  202. package/templates/admin-root/.claude/skills/uniwind +1 -0
  203. package/templates/admin-root/.claude/skills/vercel-react-best-practices/AGENTS.md +2934 -0
  204. package/templates/admin-root/.claude/skills/vercel-react-best-practices/SKILL.md +136 -0
  205. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  206. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
  207. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
  208. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
  209. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
  210. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
  211. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
  212. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
  213. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
  214. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
  215. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  216. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  217. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
  218. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
  219. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
  220. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
  221. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
  222. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
  223. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
  224. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
  225. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
  226. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
  227. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
  228. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
  229. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
  230. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
  231. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
  232. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
  233. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  234. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
  235. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  236. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
  237. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
  238. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  239. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  240. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
  241. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
  242. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  243. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
  244. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
  245. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  246. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
  247. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  248. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  249. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
  250. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
  251. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  252. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  253. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
  254. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  255. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
  256. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
  257. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
  258. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
  259. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
  260. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
  261. package/templates/admin-root/.claude/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
  262. package/templates/admin-root/.cursor/settings.json +10 -0
  263. package/templates/admin-root/.editorconfig +19 -0
  264. package/templates/admin-root/.gitattributes +16 -0
  265. package/templates/admin-root/.oxfmtrc.json +35 -0
  266. package/templates/admin-root/AGENTS.md +297 -0
  267. package/templates/admin-root/CLAUDE.md +1 -0
  268. package/templates/admin-root/skills-lock.json +27 -0
  269. package/templates/admin-root.manifest.json +1317 -0
  270. package/templates/admin-shell/devtools/AdminDevtools.css +27 -0
  271. package/templates/admin-shell/devtools/AdminDevtools.tsx +253 -0
  272. package/templates/admin-shell/devtools/index.ts +7 -0
  273. package/templates/admin-shell/devtools/jotai.ts +2 -0
  274. package/templates/admin.meta.json +14 -6
  275. package/LICENSE +0 -21
@@ -0,0 +1,325 @@
1
+ ---
2
+ name: frontend-testing
3
+ description: Generate Vitest + React Testing Library tests for Dify frontend components, hooks, and utilities. Triggers on testing, spec files, coverage, Vitest, RTL, unit tests, integration tests, or write/review test requests.
4
+ ---
5
+
6
+ # Dify Frontend Testing Skill
7
+
8
+ This skill enables Codex to generate high-quality, comprehensive frontend tests for the Dify project following established conventions and best practices.
9
+
10
+ > **⚠️ Authoritative Source**: This skill is derived from `web/testing/testing.md`. Use Vitest mock/timer APIs (`vi.*`).
11
+
12
+ ## When to Apply This Skill
13
+
14
+ Apply this skill when the user:
15
+
16
+ - Asks to **write tests** for a component, hook, or utility
17
+ - Asks to **review existing tests** for completeness
18
+ - Mentions **Vitest**, **React Testing Library**, **RTL**, or **spec files**
19
+ - Requests **test coverage** improvement
20
+ - Uses `pnpm analyze-component` output as context
21
+ - Mentions **testing**, **unit tests**, or **integration tests** for frontend code
22
+ - Wants to understand **testing patterns** in the Dify codebase
23
+
24
+ **Do NOT apply** when:
25
+
26
+ - User is asking about backend/API tests (Python/pytest)
27
+ - User is asking about E2E tests (Playwright/Cypress)
28
+ - User is only asking conceptual questions without code context
29
+
30
+ ## Quick Reference
31
+
32
+ ### Tech Stack
33
+
34
+ | Tool | Version | Purpose |
35
+ |------|---------|---------|
36
+ | Vitest | 4.0.16 | Test runner |
37
+ | React Testing Library | 16.0 | Component testing |
38
+ | jsdom | - | Test environment |
39
+ | nock | 14.0 | HTTP mocking |
40
+ | TypeScript | 5.x | Type safety |
41
+
42
+ ### Key Commands
43
+
44
+ ```bash
45
+ # Run all tests
46
+ pnpm test
47
+
48
+ # Watch mode
49
+ pnpm test:watch
50
+
51
+ # Run specific file
52
+ pnpm test path/to/file.spec.tsx
53
+
54
+ # Generate coverage report
55
+ pnpm test:coverage
56
+
57
+ # Analyze component complexity
58
+ pnpm analyze-component <path>
59
+
60
+ # Review existing test
61
+ pnpm analyze-component <path> --review
62
+ ```
63
+
64
+ ### File Naming
65
+
66
+ - Test files: `ComponentName.spec.tsx` (same directory as component)
67
+ - Integration tests: `web/__tests__/` directory
68
+
69
+ ## Test Structure Template
70
+
71
+ ```typescript
72
+ import { render, screen, fireEvent, waitFor } from '@testing-library/react'
73
+ import Component from './index'
74
+
75
+ // ✅ Import real project components (DO NOT mock these)
76
+ // import Loading from '@/app/components/base/loading'
77
+ // import { ChildComponent } from './child-component'
78
+
79
+ // ✅ Mock external dependencies only
80
+ vi.mock('@/service/api')
81
+ vi.mock('next/navigation', () => ({
82
+ useRouter: () => ({ push: vi.fn() }),
83
+ usePathname: () => '/test',
84
+ }))
85
+
86
+ // ✅ Zustand stores: Use real stores (auto-mocked globally)
87
+ // Set test state with: useAppStore.setState({ ... })
88
+
89
+ // Shared state for mocks (if needed)
90
+ let mockSharedState = false
91
+
92
+ describe('ComponentName', () => {
93
+ beforeEach(() => {
94
+ vi.clearAllMocks() // ✅ Reset mocks BEFORE each test
95
+ mockSharedState = false // ✅ Reset shared state
96
+ })
97
+
98
+ // Rendering tests (REQUIRED)
99
+ describe('Rendering', () => {
100
+ it('should render without crashing', () => {
101
+ // Arrange
102
+ const props = { title: 'Test' }
103
+
104
+ // Act
105
+ render(<Component {...props} />)
106
+
107
+ // Assert
108
+ expect(screen.getByText('Test')).toBeInTheDocument()
109
+ })
110
+ })
111
+
112
+ // Props tests (REQUIRED)
113
+ describe('Props', () => {
114
+ it('should apply custom className', () => {
115
+ render(<Component className="custom" />)
116
+ expect(screen.getByRole('button')).toHaveClass('custom')
117
+ })
118
+ })
119
+
120
+ // User Interactions
121
+ describe('User Interactions', () => {
122
+ it('should handle click events', () => {
123
+ const handleClick = vi.fn()
124
+ render(<Component onClick={handleClick} />)
125
+
126
+ fireEvent.click(screen.getByRole('button'))
127
+
128
+ expect(handleClick).toHaveBeenCalledTimes(1)
129
+ })
130
+ })
131
+
132
+ // Edge Cases (REQUIRED)
133
+ describe('Edge Cases', () => {
134
+ it('should handle null data', () => {
135
+ render(<Component data={null} />)
136
+ expect(screen.getByText(/no data/i)).toBeInTheDocument()
137
+ })
138
+
139
+ it('should handle empty array', () => {
140
+ render(<Component items={[]} />)
141
+ expect(screen.getByText(/empty/i)).toBeInTheDocument()
142
+ })
143
+ })
144
+ })
145
+ ```
146
+
147
+ ## Testing Workflow (CRITICAL)
148
+
149
+ ### ⚠️ Incremental Approach Required
150
+
151
+ **NEVER generate all test files at once.** For complex components or multi-file directories:
152
+
153
+ 1. **Analyze & Plan**: List all files, order by complexity (simple → complex)
154
+ 1. **Process ONE at a time**: Write test → Run test → Fix if needed → Next
155
+ 1. **Verify before proceeding**: Do NOT continue to next file until current passes
156
+
157
+ ```
158
+ For each file:
159
+ ┌────────────────────────────────────────┐
160
+ │ 1. Write test │
161
+ │ 2. Run: pnpm test <file>.spec.tsx │
162
+ │ 3. PASS? → Mark complete, next file │
163
+ │ FAIL? → Fix first, then continue │
164
+ └────────────────────────────────────────┘
165
+ ```
166
+
167
+ ### Complexity-Based Order
168
+
169
+ Process in this order for multi-file testing:
170
+
171
+ 1. 🟢 Utility functions (simplest)
172
+ 1. 🟢 Custom hooks
173
+ 1. 🟡 Simple components (presentational)
174
+ 1. 🟡 Medium components (state, effects)
175
+ 1. 🔴 Complex components (API, routing)
176
+ 1. 🔴 Integration tests (index files - last)
177
+
178
+ ### When to Refactor First
179
+
180
+ - **Complexity > 50**: Break into smaller pieces before testing
181
+ - **500+ lines**: Consider splitting before testing
182
+ - **Many dependencies**: Extract logic into hooks first
183
+
184
+ > 📖 See `references/workflow.md` for complete workflow details and todo list format.
185
+
186
+ ## Testing Strategy
187
+
188
+ ### Path-Level Testing (Directory Testing)
189
+
190
+ When assigned to test a directory/path, test **ALL content** within that path:
191
+
192
+ - Test all components, hooks, utilities in the directory (not just `index` file)
193
+ - Use incremental approach: one file at a time, verify each before proceeding
194
+ - Goal: 100% coverage of ALL files in the directory
195
+
196
+ ### Integration Testing First
197
+
198
+ **Prefer integration testing** when writing tests for a directory:
199
+
200
+ - ✅ **Import real project components** directly (including base components and siblings)
201
+ - ✅ **Only mock**: API services (`@/service/*`), `next/navigation`, complex context providers
202
+ - ❌ **DO NOT mock** base components (`@/app/components/base/*`)
203
+ - ❌ **DO NOT mock** sibling/child components in the same directory
204
+
205
+ > See [Test Structure Template](#test-structure-template) for correct import/mock patterns.
206
+
207
+ ## Core Principles
208
+
209
+ ### 1. AAA Pattern (Arrange-Act-Assert)
210
+
211
+ Every test should clearly separate:
212
+
213
+ - **Arrange**: Setup test data and render component
214
+ - **Act**: Perform user actions
215
+ - **Assert**: Verify expected outcomes
216
+
217
+ ### 2. Black-Box Testing
218
+
219
+ - Test observable behavior, not implementation details
220
+ - Use semantic queries (getByRole, getByLabelText)
221
+ - Avoid testing internal state directly
222
+ - **Prefer pattern matching over hardcoded strings** in assertions:
223
+
224
+ ```typescript
225
+ // ❌ Avoid: hardcoded text assertions
226
+ expect(screen.getByText('Loading...')).toBeInTheDocument()
227
+
228
+ // ✅ Better: role-based queries
229
+ expect(screen.getByRole('status')).toBeInTheDocument()
230
+
231
+ // ✅ Better: pattern matching
232
+ expect(screen.getByText(/loading/i)).toBeInTheDocument()
233
+ ```
234
+
235
+ ### 3. Single Behavior Per Test
236
+
237
+ Each test verifies ONE user-observable behavior:
238
+
239
+ ```typescript
240
+ // ✅ Good: One behavior
241
+ it('should disable button when loading', () => {
242
+ render(<Button loading />)
243
+ expect(screen.getByRole('button')).toBeDisabled()
244
+ })
245
+
246
+ // ❌ Bad: Multiple behaviors
247
+ it('should handle loading state', () => {
248
+ render(<Button loading />)
249
+ expect(screen.getByRole('button')).toBeDisabled()
250
+ expect(screen.getByText('Loading...')).toBeInTheDocument()
251
+ expect(screen.getByRole('button')).toHaveClass('loading')
252
+ })
253
+ ```
254
+
255
+ ### 4. Semantic Naming
256
+
257
+ Use `should <behavior> when <condition>`:
258
+
259
+ ```typescript
260
+ it('should show error message when validation fails')
261
+ it('should call onSubmit when form is valid')
262
+ it('should disable input when isReadOnly is true')
263
+ ```
264
+
265
+ ## Required Test Scenarios
266
+
267
+ ### Always Required (All Components)
268
+
269
+ 1. **Rendering**: Component renders without crashing
270
+ 1. **Props**: Required props, optional props, default values
271
+ 1. **Edge Cases**: null, undefined, empty values, boundary conditions
272
+
273
+ ### Conditional (When Present)
274
+
275
+ | Feature | Test Focus |
276
+ |---------|-----------|
277
+ | `useState` | Initial state, transitions, cleanup |
278
+ | `useEffect` | Execution, dependencies, cleanup |
279
+ | Event handlers | All onClick, onChange, onSubmit, keyboard |
280
+ | API calls | Loading, success, error states |
281
+ | Routing | Navigation, params, query strings |
282
+ | `useCallback`/`useMemo` | Referential equality |
283
+ | Context | Provider values, consumer behavior |
284
+ | Forms | Validation, submission, error display |
285
+
286
+ ## Coverage Goals (Per File)
287
+
288
+ For each test file generated, aim for:
289
+
290
+ - ✅ **100%** function coverage
291
+ - ✅ **100%** statement coverage
292
+ - ✅ **>95%** branch coverage
293
+ - ✅ **>95%** line coverage
294
+
295
+ > **Note**: For multi-file directories, process one file at a time with full coverage each. See `references/workflow.md`.
296
+
297
+ ## Detailed Guides
298
+
299
+ For more detailed information, refer to:
300
+
301
+ - `references/workflow.md` - **Incremental testing workflow** (MUST READ for multi-file testing)
302
+ - `references/mocking.md` - Mock patterns, Zustand store testing, and best practices
303
+ - `references/async-testing.md` - Async operations and API calls
304
+ - `references/domain-components.md` - Workflow, Dataset, Configuration testing
305
+ - `references/common-patterns.md` - Frequently used testing patterns
306
+ - `references/checklist.md` - Test generation checklist and validation steps
307
+
308
+ ## Authoritative References
309
+
310
+ ### Primary Specification (MUST follow)
311
+
312
+ - **`web/testing/testing.md`** - The canonical testing specification. This skill is derived from this document.
313
+
314
+ ### Reference Examples in Codebase
315
+
316
+ - `web/utils/classnames.spec.ts` - Utility function tests
317
+ - `web/app/components/base/button/index.spec.tsx` - Component tests
318
+ - `web/__mocks__/provider-context.ts` - Mock factory example
319
+
320
+ ### Project Configuration
321
+
322
+ - `web/vitest.config.ts` - Vitest configuration
323
+ - `web/vitest.setup.ts` - Test environment setup
324
+ - `web/scripts/analyze-component.js` - Component analysis tool
325
+ - Modules are not mocked automatically. Global mocks live in `web/vitest.setup.ts` (for example `react-i18next`, `next/image`); mock other modules like `ky` or `mime` locally in test files.
@@ -0,0 +1,293 @@
1
+ /**
2
+ * Test Template for React Components
3
+ *
4
+ * WHY THIS STRUCTURE?
5
+ * - Organized sections make tests easy to navigate and maintain
6
+ * - Mocks at top ensure consistent test isolation
7
+ * - Factory functions reduce duplication and improve readability
8
+ * - describe blocks group related scenarios for better debugging
9
+ *
10
+ * INSTRUCTIONS:
11
+ * 1. Replace `ComponentName` with your component name
12
+ * 2. Update import path
13
+ * 3. Add/remove test sections based on component features (use analyze-component)
14
+ * 4. Follow AAA pattern: Arrange → Act → Assert
15
+ *
16
+ * RUN FIRST: pnpm analyze-component <path> to identify required test scenarios
17
+ */
18
+
19
+ import { render, screen, fireEvent, waitFor } from '@testing-library/react'
20
+ import userEvent from '@testing-library/user-event'
21
+ // import ComponentName from './index'
22
+
23
+ // ============================================================================
24
+ // Mocks
25
+ // ============================================================================
26
+ // WHY: Mocks must be hoisted to top of file (Vitest requirement).
27
+ // They run BEFORE imports, so keep them before component imports.
28
+
29
+ // i18n (automatically mocked)
30
+ // WHY: Global mock in web/vitest.setup.ts is auto-loaded by Vitest setup
31
+ // The global mock provides: useTranslation, Trans, useMixedTranslation, useGetLanguage
32
+ // No explicit mock needed for most tests
33
+ //
34
+ // Override only if custom translations are required:
35
+ // import { createReactI18nextMock } from '@/test/i18n-mock'
36
+ // vi.mock('react-i18next', () => createReactI18nextMock({
37
+ // 'my.custom.key': 'Custom Translation',
38
+ // 'button.save': 'Save',
39
+ // }))
40
+
41
+ // Router (if component uses useRouter, usePathname, useSearchParams)
42
+ // WHY: Isolates tests from Next.js routing, enables testing navigation behavior
43
+ // const mockPush = vi.fn()
44
+ // vi.mock('next/navigation', () => ({
45
+ // useRouter: () => ({ push: mockPush }),
46
+ // usePathname: () => '/test-path',
47
+ // }))
48
+
49
+ // API services (if component fetches data)
50
+ // WHY: Prevents real network calls, enables testing all states (loading/success/error)
51
+ // vi.mock('@/service/api')
52
+ // import * as api from '@/service/api'
53
+ // const mockedApi = vi.mocked(api)
54
+
55
+ // Shared mock state (for portal/dropdown components)
56
+ // WHY: Portal components like PortalToFollowElem need shared state between
57
+ // parent and child mocks to correctly simulate open/close behavior
58
+ // let mockOpenState = false
59
+
60
+ // ============================================================================
61
+ // Test Data Factories
62
+ // ============================================================================
63
+ // WHY FACTORIES?
64
+ // - Avoid hard-coded test data scattered across tests
65
+ // - Easy to create variations with overrides
66
+ // - Type-safe when using actual types from source
67
+ // - Single source of truth for default test values
68
+
69
+ // const createMockProps = (overrides = {}) => ({
70
+ // // Default props that make component render successfully
71
+ // ...overrides,
72
+ // })
73
+
74
+ // const createMockItem = (overrides = {}) => ({
75
+ // id: 'item-1',
76
+ // name: 'Test Item',
77
+ // ...overrides,
78
+ // })
79
+
80
+ // ============================================================================
81
+ // Test Helpers
82
+ // ============================================================================
83
+
84
+ // const renderComponent = (props = {}) => {
85
+ // return render(<ComponentName {...createMockProps(props)} />)
86
+ // }
87
+
88
+ // ============================================================================
89
+ // Tests
90
+ // ============================================================================
91
+
92
+ describe('ComponentName', () => {
93
+ // WHY beforeEach with clearAllMocks?
94
+ // - Ensures each test starts with clean slate
95
+ // - Prevents mock call history from leaking between tests
96
+ // - MUST be beforeEach (not afterEach) to reset BEFORE assertions like toHaveBeenCalledTimes
97
+ beforeEach(() => {
98
+ vi.clearAllMocks()
99
+ // Reset shared mock state if used (CRITICAL for portal/dropdown tests)
100
+ // mockOpenState = false
101
+ })
102
+
103
+ // --------------------------------------------------------------------------
104
+ // Rendering Tests (REQUIRED - Every component MUST have these)
105
+ // --------------------------------------------------------------------------
106
+ // WHY: Catches import errors, missing providers, and basic render issues
107
+ describe('Rendering', () => {
108
+ it('should render without crashing', () => {
109
+ // Arrange - Setup data and mocks
110
+ // const props = createMockProps()
111
+
112
+ // Act - Render the component
113
+ // render(<ComponentName {...props} />)
114
+
115
+ // Assert - Verify expected output
116
+ // Prefer getByRole for accessibility; it's what users "see"
117
+ // expect(screen.getByRole('...')).toBeInTheDocument()
118
+ })
119
+
120
+ it('should render with default props', () => {
121
+ // WHY: Verifies component works without optional props
122
+ // render(<ComponentName />)
123
+ // expect(screen.getByText('...')).toBeInTheDocument()
124
+ })
125
+ })
126
+
127
+ // --------------------------------------------------------------------------
128
+ // Props Tests (REQUIRED - Every component MUST test prop behavior)
129
+ // --------------------------------------------------------------------------
130
+ // WHY: Props are the component's API contract. Test them thoroughly.
131
+ describe('Props', () => {
132
+ it('should apply custom className', () => {
133
+ // WHY: Common pattern in Dify - components should merge custom classes
134
+ // render(<ComponentName className="custom-class" />)
135
+ // expect(screen.getByTestId('component')).toHaveClass('custom-class')
136
+ })
137
+
138
+ it('should use default values for optional props', () => {
139
+ // WHY: Verifies TypeScript defaults work at runtime
140
+ // render(<ComponentName />)
141
+ // expect(screen.getByRole('...')).toHaveAttribute('...', 'default-value')
142
+ })
143
+ })
144
+
145
+ // --------------------------------------------------------------------------
146
+ // User Interactions (if component has event handlers - on*, handle*)
147
+ // --------------------------------------------------------------------------
148
+ // WHY: Event handlers are core functionality. Test from user's perspective.
149
+ describe('User Interactions', () => {
150
+ it('should call onClick when clicked', async () => {
151
+ // WHY userEvent over fireEvent?
152
+ // - userEvent simulates real user behavior (focus, hover, then click)
153
+ // - fireEvent is lower-level, doesn't trigger all browser events
154
+ // const user = userEvent.setup()
155
+ // const handleClick = vi.fn()
156
+ // render(<ComponentName onClick={handleClick} />)
157
+ //
158
+ // await user.click(screen.getByRole('button'))
159
+ //
160
+ // expect(handleClick).toHaveBeenCalledTimes(1)
161
+ })
162
+
163
+ it('should call onChange when value changes', async () => {
164
+ // const user = userEvent.setup()
165
+ // const handleChange = vi.fn()
166
+ // render(<ComponentName onChange={handleChange} />)
167
+ //
168
+ // await user.type(screen.getByRole('textbox'), 'new value')
169
+ //
170
+ // expect(handleChange).toHaveBeenCalled()
171
+ })
172
+ })
173
+
174
+ // --------------------------------------------------------------------------
175
+ // State Management (if component uses useState/useReducer)
176
+ // --------------------------------------------------------------------------
177
+ // WHY: Test state through observable UI changes, not internal state values
178
+ describe('State Management', () => {
179
+ it('should update state on interaction', async () => {
180
+ // WHY test via UI, not state?
181
+ // - State is implementation detail; UI is what users see
182
+ // - If UI works correctly, state must be correct
183
+ // const user = userEvent.setup()
184
+ // render(<ComponentName />)
185
+ //
186
+ // // Initial state - verify what user sees
187
+ // expect(screen.getByText('Initial')).toBeInTheDocument()
188
+ //
189
+ // // Trigger state change via user action
190
+ // await user.click(screen.getByRole('button'))
191
+ //
192
+ // // New state - verify UI updated
193
+ // expect(screen.getByText('Updated')).toBeInTheDocument()
194
+ })
195
+ })
196
+
197
+ // --------------------------------------------------------------------------
198
+ // Async Operations (if component fetches data - useQuery, fetch)
199
+ // --------------------------------------------------------------------------
200
+ // WHY: Async operations have 3 states users experience: loading, success, error
201
+ describe('Async Operations', () => {
202
+ it('should show loading state', () => {
203
+ // WHY never-resolving promise?
204
+ // - Keeps component in loading state for assertion
205
+ // - Alternative: use fake timers
206
+ // mockedApi.fetchData.mockImplementation(() => new Promise(() => {}))
207
+ // render(<ComponentName />)
208
+ //
209
+ // expect(screen.getByText(/loading/i)).toBeInTheDocument()
210
+ })
211
+
212
+ it('should show data on success', async () => {
213
+ // WHY waitFor?
214
+ // - Component updates asynchronously after fetch resolves
215
+ // - waitFor retries assertion until it passes or times out
216
+ // mockedApi.fetchData.mockResolvedValue({ items: ['Item 1'] })
217
+ // render(<ComponentName />)
218
+ //
219
+ // await waitFor(() => {
220
+ // expect(screen.getByText('Item 1')).toBeInTheDocument()
221
+ // })
222
+ })
223
+
224
+ it('should show error on failure', async () => {
225
+ // mockedApi.fetchData.mockRejectedValue(new Error('Network error'))
226
+ // render(<ComponentName />)
227
+ //
228
+ // await waitFor(() => {
229
+ // expect(screen.getByText(/error/i)).toBeInTheDocument()
230
+ // })
231
+ })
232
+ })
233
+
234
+ // --------------------------------------------------------------------------
235
+ // Edge Cases (REQUIRED - Every component MUST handle edge cases)
236
+ // --------------------------------------------------------------------------
237
+ // WHY: Real-world data is messy. Components must handle:
238
+ // - Null/undefined from API failures or optional fields
239
+ // - Empty arrays/strings from user clearing data
240
+ // - Boundary values (0, MAX_INT, special characters)
241
+ describe('Edge Cases', () => {
242
+ it('should handle null value', () => {
243
+ // WHY test null specifically?
244
+ // - API might return null for missing data
245
+ // - Prevents "Cannot read property of null" in production
246
+ // render(<ComponentName value={null} />)
247
+ // expect(screen.getByText(/no data/i)).toBeInTheDocument()
248
+ })
249
+
250
+ it('should handle undefined value', () => {
251
+ // WHY test undefined separately from null?
252
+ // - TypeScript treats them differently
253
+ // - Optional props are undefined, not null
254
+ // render(<ComponentName value={undefined} />)
255
+ // expect(screen.getByText(/no data/i)).toBeInTheDocument()
256
+ })
257
+
258
+ it('should handle empty array', () => {
259
+ // WHY: Empty state often needs special UI (e.g., "No items yet")
260
+ // render(<ComponentName items={[]} />)
261
+ // expect(screen.getByText(/empty/i)).toBeInTheDocument()
262
+ })
263
+
264
+ it('should handle empty string', () => {
265
+ // WHY: Empty strings are truthy in JS but visually empty
266
+ // render(<ComponentName text="" />)
267
+ // expect(screen.getByText(/placeholder/i)).toBeInTheDocument()
268
+ })
269
+ })
270
+
271
+ // --------------------------------------------------------------------------
272
+ // Accessibility (optional but recommended for Dify's enterprise users)
273
+ // --------------------------------------------------------------------------
274
+ // WHY: Dify has enterprise customers who may require accessibility compliance
275
+ describe('Accessibility', () => {
276
+ it('should have accessible name', () => {
277
+ // WHY getByRole with name?
278
+ // - Tests that screen readers can identify the element
279
+ // - Enforces proper labeling practices
280
+ // render(<ComponentName label="Test Label" />)
281
+ // expect(screen.getByRole('button', { name: /test label/i })).toBeInTheDocument()
282
+ })
283
+
284
+ it('should support keyboard navigation', async () => {
285
+ // WHY: Some users can't use a mouse
286
+ // const user = userEvent.setup()
287
+ // render(<ComponentName />)
288
+ //
289
+ // await user.tab()
290
+ // expect(screen.getByRole('button')).toHaveFocus()
291
+ })
292
+ })
293
+ })