@mytechtoday/augment-extensions 1.7.0 → 2.2.0

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 (440) hide show
  1. package/README.md +119 -8
  2. package/augment-extensions/coding-standards/bash/CHANGELOG.md +51 -0
  3. package/augment-extensions/coding-standards/bash/metadata.json +21 -0
  4. package/augment-extensions/coding-standards/c/metadata.json +50 -0
  5. package/augment-extensions/coding-standards/css/CHANGELOG.md +51 -0
  6. package/augment-extensions/coding-standards/css/metadata.json +30 -0
  7. package/augment-extensions/coding-standards/go/CHANGELOG.md +51 -0
  8. package/augment-extensions/coding-standards/go/metadata.json +57 -0
  9. package/augment-extensions/coding-standards/html/CHANGELOG.md +51 -0
  10. package/augment-extensions/coding-standards/html/metadata.json +25 -0
  11. package/augment-extensions/coding-standards/html-css-js/CHANGELOG.md +51 -0
  12. package/augment-extensions/coding-standards/html-css-js/metadata.json +40 -0
  13. package/augment-extensions/coding-standards/js/CHANGELOG.md +51 -0
  14. package/augment-extensions/coding-standards/js/metadata.json +37 -0
  15. package/augment-extensions/coding-standards/php/CHANGELOG.md +51 -0
  16. package/augment-extensions/coding-standards/php/metadata.json +35 -0
  17. package/augment-extensions/coding-standards/powershell/CHANGELOG.md +51 -0
  18. package/augment-extensions/coding-standards/powershell/metadata.json +33 -0
  19. package/augment-extensions/coding-standards/python/CHANGELOG.md +51 -0
  20. package/augment-extensions/coding-standards/python/metadata.json +38 -0
  21. package/augment-extensions/coding-standards/react/CHANGELOG.md +51 -0
  22. package/augment-extensions/coding-standards/react/metadata.json +31 -0
  23. package/augment-extensions/coding-standards/typescript/CHANGELOG.md +39 -0
  24. package/augment-extensions/coding-standards/typescript/README.md +248 -19
  25. package/augment-extensions/coding-standards/typescript/VERSION +2 -0
  26. package/augment-extensions/coding-standards/typescript/examples/biome.json +199 -0
  27. package/augment-extensions/coding-standards/typescript/examples/eslint-flat-config.js +166 -0
  28. package/augment-extensions/coding-standards/typescript/examples/monorepo-config/README.md +47 -0
  29. package/augment-extensions/coding-standards/typescript/examples/monorepo-config/package.json +37 -0
  30. package/augment-extensions/coding-standards/typescript/examples/monorepo-config/pnpm-workspace.yaml +5 -0
  31. package/augment-extensions/coding-standards/typescript/examples/monorepo-config/tsconfig.base.json +50 -0
  32. package/augment-extensions/coding-standards/typescript/examples/monorepo-config/turbo.json +47 -0
  33. package/augment-extensions/coding-standards/typescript/examples/vitest-setup.ts +198 -0
  34. package/augment-extensions/coding-standards/typescript/metadata.json +46 -0
  35. package/augment-extensions/coding-standards/typescript/module.json +25 -7
  36. package/augment-extensions/coding-standards/typescript/rules/architecture.md +1096 -0
  37. package/augment-extensions/coding-standards/typescript/rules/error-handling.md +1174 -0
  38. package/augment-extensions/coding-standards/typescript/rules/modern-features.md +625 -0
  39. package/augment-extensions/coding-standards/typescript/rules/monorepo.md +745 -0
  40. package/augment-extensions/coding-standards/typescript/rules/security-performance.md +850 -0
  41. package/augment-extensions/coding-standards/typescript/rules/testing.md +918 -0
  42. package/augment-extensions/coding-standards/typescript/rules/tooling.md +1071 -0
  43. package/augment-extensions/coding-standards/typescript/rules/type-patterns.md +750 -0
  44. package/augment-extensions/domain-rules/api-design/CHANGELOG.md +51 -0
  45. package/augment-extensions/domain-rules/api-design/metadata.json +32 -0
  46. package/augment-extensions/domain-rules/database/CHANGELOG.md +51 -0
  47. package/augment-extensions/domain-rules/database/metadata.json +50 -0
  48. package/augment-extensions/domain-rules/design/color/themes/catppuccin-latte/CHANGELOG.md +51 -0
  49. package/augment-extensions/domain-rules/design/color/themes/catppuccin-latte/metadata.json +18 -0
  50. package/augment-extensions/domain-rules/design/color/themes/catppuccin-mocha/CHANGELOG.md +51 -0
  51. package/augment-extensions/domain-rules/design/color/themes/catppuccin-mocha/metadata.json +18 -0
  52. package/augment-extensions/domain-rules/design/color/themes/dracula/CHANGELOG.md +51 -0
  53. package/augment-extensions/domain-rules/design/color/themes/dracula/metadata.json +18 -0
  54. package/augment-extensions/domain-rules/design/color/themes/gruvbox-dark/CHANGELOG.md +51 -0
  55. package/augment-extensions/domain-rules/design/color/themes/gruvbox-dark/metadata.json +18 -0
  56. package/augment-extensions/domain-rules/design/color/themes/gruvbox-light/CHANGELOG.md +51 -0
  57. package/augment-extensions/domain-rules/design/color/themes/gruvbox-light/metadata.json +18 -0
  58. package/augment-extensions/domain-rules/design/color/themes/high-contrast/CHANGELOG.md +51 -0
  59. package/augment-extensions/domain-rules/design/color/themes/high-contrast/metadata.json +18 -0
  60. package/augment-extensions/domain-rules/design/color/themes/monokai/CHANGELOG.md +51 -0
  61. package/augment-extensions/domain-rules/design/color/themes/monokai/metadata.json +18 -0
  62. package/augment-extensions/domain-rules/design/color/themes/nord/CHANGELOG.md +51 -0
  63. package/augment-extensions/domain-rules/design/color/themes/nord/metadata.json +18 -0
  64. package/augment-extensions/domain-rules/design/color/themes/one-dark/CHANGELOG.md +51 -0
  65. package/augment-extensions/domain-rules/design/color/themes/one-dark/metadata.json +18 -0
  66. package/augment-extensions/domain-rules/design/color/themes/one-light/CHANGELOG.md +51 -0
  67. package/augment-extensions/domain-rules/design/color/themes/one-light/metadata.json +18 -0
  68. package/augment-extensions/domain-rules/design/color/themes/solarized-dark/CHANGELOG.md +51 -0
  69. package/augment-extensions/domain-rules/design/color/themes/solarized-dark/metadata.json +18 -0
  70. package/augment-extensions/domain-rules/design/color/themes/solarized-light/CHANGELOG.md +51 -0
  71. package/augment-extensions/domain-rules/design/color/themes/solarized-light/metadata.json +18 -0
  72. package/augment-extensions/domain-rules/design/color/themes/tokyo-night/CHANGELOG.md +51 -0
  73. package/augment-extensions/domain-rules/design/color/themes/tokyo-night/metadata.json +18 -0
  74. package/augment-extensions/domain-rules/mcp/CHANGELOG.md +51 -0
  75. package/augment-extensions/domain-rules/mcp/metadata.json +42 -0
  76. package/augment-extensions/domain-rules/security/CHANGELOG.md +51 -0
  77. package/augment-extensions/domain-rules/security/metadata.json +33 -0
  78. package/augment-extensions/domain-rules/seo-sales-marketing/CHANGELOG.md +51 -0
  79. package/augment-extensions/domain-rules/seo-sales-marketing/metadata.json +40 -0
  80. package/augment-extensions/domain-rules/software-architecture/CHANGELOG.md +51 -0
  81. package/augment-extensions/domain-rules/software-architecture/metadata.json +55 -0
  82. package/augment-extensions/domain-rules/wordpress/CHANGELOG.md +51 -0
  83. package/augment-extensions/domain-rules/wordpress/metadata.json +42 -0
  84. package/augment-extensions/domain-rules/wordpress-plugin/CHANGELOG.md +51 -0
  85. package/augment-extensions/domain-rules/wordpress-plugin/metadata.json +70 -0
  86. package/augment-extensions/examples/design-patterns/CHANGELOG.md +51 -0
  87. package/augment-extensions/examples/design-patterns/metadata.json +29 -0
  88. package/augment-extensions/examples/gutenberg-block-plugin/CHANGELOG.md +51 -0
  89. package/augment-extensions/examples/gutenberg-block-plugin/metadata.json +26 -0
  90. package/augment-extensions/examples/rest-api-plugin/CHANGELOG.md +51 -0
  91. package/augment-extensions/examples/rest-api-plugin/metadata.json +27 -0
  92. package/augment-extensions/examples/woocommerce-extension/CHANGELOG.md +51 -0
  93. package/augment-extensions/examples/woocommerce-extension/metadata.json +27 -0
  94. package/augment-extensions/visual-design/metadata.json +34 -0
  95. package/augment-extensions/workflows/adr-support/CHANGELOG.md +51 -0
  96. package/augment-extensions/workflows/adr-support/metadata.json +41 -0
  97. package/augment-extensions/workflows/beads/CHANGELOG.md +51 -0
  98. package/augment-extensions/workflows/beads/metadata.json +23 -0
  99. package/augment-extensions/workflows/beads-integration/CHANGELOG.md +51 -0
  100. package/augment-extensions/workflows/beads-integration/metadata.json +30 -0
  101. package/augment-extensions/workflows/database/CHANGELOG.md +51 -0
  102. package/augment-extensions/workflows/database/metadata.json +30 -0
  103. package/augment-extensions/workflows/wordpress-plugin/CHANGELOG.md +51 -0
  104. package/augment-extensions/workflows/wordpress-plugin/metadata.json +41 -0
  105. package/augment-extensions/writing-standards/literature/shakespeare/CHANGELOG.md +51 -0
  106. package/augment-extensions/writing-standards/literature/shakespeare/metadata.json +60 -0
  107. package/augment-extensions/writing-standards/screenplay/CHANGELOG.md +51 -0
  108. package/augment-extensions/writing-standards/screenplay/cinematic-styles/CHANGELOG.md +51 -0
  109. package/augment-extensions/writing-standards/screenplay/cinematic-styles/comedy-formats/CHANGELOG.md +51 -0
  110. package/augment-extensions/writing-standards/screenplay/cinematic-styles/comedy-formats/metadata.json +24 -0
  111. package/augment-extensions/writing-standards/screenplay/cinematic-styles/comedy-formats/monty-python/CHANGELOG.md +51 -0
  112. package/augment-extensions/writing-standards/screenplay/cinematic-styles/comedy-formats/monty-python/metadata.json +24 -0
  113. package/augment-extensions/writing-standards/screenplay/cinematic-styles/comedy-formats/saturday-night-live/CHANGELOG.md +51 -0
  114. package/augment-extensions/writing-standards/screenplay/cinematic-styles/comedy-formats/saturday-night-live/metadata.json +24 -0
  115. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/CHANGELOG.md +51 -0
  116. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/alfred-hitchcock/CHANGELOG.md +51 -0
  117. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/alfred-hitchcock/metadata.json +24 -0
  118. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/ari-aster/CHANGELOG.md +51 -0
  119. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/ari-aster/metadata.json +24 -0
  120. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/brad-bird/CHANGELOG.md +51 -0
  121. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/brad-bird/metadata.json +24 -0
  122. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/brian-de-palma/CHANGELOG.md +51 -0
  123. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/brian-de-palma/metadata.json +24 -0
  124. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/buster-keaton/CHANGELOG.md +51 -0
  125. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/buster-keaton/metadata.json +24 -0
  126. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/christopher-nolan/CHANGELOG.md +51 -0
  127. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/christopher-nolan/metadata.json +24 -0
  128. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/clint-eastwood/CHANGELOG.md +51 -0
  129. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/clint-eastwood/metadata.json +24 -0
  130. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/coen-brothers/CHANGELOG.md +51 -0
  131. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/coen-brothers/metadata.json +24 -0
  132. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/darren-aronofsky/CHANGELOG.md +51 -0
  133. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/darren-aronofsky/metadata.json +24 -0
  134. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/david-fincher/CHANGELOG.md +51 -0
  135. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/david-fincher/metadata.json +24 -0
  136. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/david-lynch/CHANGELOG.md +51 -0
  137. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/david-lynch/metadata.json +24 -0
  138. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/denis-villeneuve/CHANGELOG.md +51 -0
  139. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/denis-villeneuve/metadata.json +24 -0
  140. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/francis-ford-coppola/CHANGELOG.md +51 -0
  141. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/francis-ford-coppola/metadata.json +24 -0
  142. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/gary-marshall/CHANGELOG.md +51 -0
  143. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/gary-marshall/metadata.json +24 -0
  144. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/george-a-romero/CHANGELOG.md +51 -0
  145. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/george-a-romero/metadata.json +24 -0
  146. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/george-lucas/CHANGELOG.md +51 -0
  147. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/george-lucas/metadata.json +24 -0
  148. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/guillermo-del-toro/CHANGELOG.md +51 -0
  149. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/guillermo-del-toro/metadata.json +24 -0
  150. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/gus-van-sant/CHANGELOG.md +51 -0
  151. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/gus-van-sant/metadata.json +24 -0
  152. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/james-ivory-ismail-merchant/CHANGELOG.md +51 -0
  153. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/james-ivory-ismail-merchant/metadata.json +24 -0
  154. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/jim-jarmusch/CHANGELOG.md +51 -0
  155. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/jim-jarmusch/metadata.json +24 -0
  156. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/john-carpenter/CHANGELOG.md +51 -0
  157. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/john-carpenter/metadata.json +24 -0
  158. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/john-ford/CHANGELOG.md +51 -0
  159. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/john-ford/metadata.json +24 -0
  160. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/john-huston/CHANGELOG.md +51 -0
  161. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/john-huston/metadata.json +24 -0
  162. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/john-landis/CHANGELOG.md +51 -0
  163. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/john-landis/metadata.json +24 -0
  164. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/jonathan-demme/CHANGELOG.md +51 -0
  165. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/jonathan-demme/metadata.json +24 -0
  166. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/joseph-l-mankiewicz/CHANGELOG.md +51 -0
  167. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/joseph-l-mankiewicz/metadata.json +24 -0
  168. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/kathryn-bigelow/CHANGELOG.md +51 -0
  169. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/kathryn-bigelow/metadata.json +24 -0
  170. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/kelly-reichardt/CHANGELOG.md +51 -0
  171. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/kelly-reichardt/metadata.json +24 -0
  172. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/kevin-smith/CHANGELOG.md +51 -0
  173. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/kevin-smith/metadata.json +24 -0
  174. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/linda-shayne/CHANGELOG.md +51 -0
  175. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/linda-shayne/metadata.json +24 -0
  176. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/martin-scorsese/CHANGELOG.md +51 -0
  177. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/martin-scorsese/metadata.json +24 -0
  178. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/mel-brooks/CHANGELOG.md +51 -0
  179. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/mel-brooks/metadata.json +24 -0
  180. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/metadata.json +25 -0
  181. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/michael-curtiz/CHANGELOG.md +51 -0
  182. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/michael-curtiz/metadata.json +24 -0
  183. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/michael-mann/CHANGELOG.md +51 -0
  184. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/michael-mann/metadata.json +24 -0
  185. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/mike-nichols/CHANGELOG.md +51 -0
  186. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/mike-nichols/metadata.json +24 -0
  187. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/orson-welles/CHANGELOG.md +51 -0
  188. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/orson-welles/metadata.json +24 -0
  189. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/park-chan-wook/CHANGELOG.md +51 -0
  190. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/park-chan-wook/metadata.json +24 -0
  191. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/paul-thomas-anderson/CHANGELOG.md +51 -0
  192. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/paul-thomas-anderson/metadata.json +24 -0
  193. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/penny-marshall/CHANGELOG.md +51 -0
  194. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/penny-marshall/metadata.json +24 -0
  195. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/peter-bogdanovich/CHANGELOG.md +51 -0
  196. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/peter-bogdanovich/metadata.json +24 -0
  197. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/quentin-tarantino/CHANGELOG.md +51 -0
  198. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/quentin-tarantino/metadata.json +24 -0
  199. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/richard-linklater/CHANGELOG.md +51 -0
  200. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/richard-linklater/metadata.json +24 -0
  201. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/rob-reiner/CHANGELOG.md +51 -0
  202. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/rob-reiner/metadata.json +24 -0
  203. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/robert-altman/CHANGELOG.md +51 -0
  204. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/robert-altman/metadata.json +24 -0
  205. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/robert-eggers/CHANGELOG.md +51 -0
  206. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/robert-eggers/metadata.json +24 -0
  207. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/robert-zemeckis/CHANGELOG.md +51 -0
  208. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/robert-zemeckis/metadata.json +24 -0
  209. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/sam-peckinpah/CHANGELOG.md +51 -0
  210. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/sam-peckinpah/metadata.json +24 -0
  211. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/sidney-lumet/CHANGELOG.md +51 -0
  212. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/sidney-lumet/metadata.json +24 -0
  213. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/spike-lee/CHANGELOG.md +51 -0
  214. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/spike-lee/metadata.json +24 -0
  215. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/stanley-donen-gene-kelly/CHANGELOG.md +51 -0
  216. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/stanley-donen-gene-kelly/metadata.json +24 -0
  217. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/stanley-kubrick/CHANGELOG.md +51 -0
  218. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/stanley-kubrick/metadata.json +24 -0
  219. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/steve-martin/CHANGELOG.md +51 -0
  220. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/steve-martin/metadata.json +24 -0
  221. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/steven-spielberg/CHANGELOG.md +51 -0
  222. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/steven-spielberg/metadata.json +24 -0
  223. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/sydney-pollack/CHANGELOG.md +51 -0
  224. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/sydney-pollack/metadata.json +24 -0
  225. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/terry-gilliam/CHANGELOG.md +51 -0
  226. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/terry-gilliam/metadata.json +24 -0
  227. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/tim-burton/CHANGELOG.md +51 -0
  228. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/tim-burton/metadata.json +24 -0
  229. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/tobe-hooper/CHANGELOG.md +51 -0
  230. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/tobe-hooper/metadata.json +24 -0
  231. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/wes-anderson/CHANGELOG.md +51 -0
  232. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/wes-anderson/metadata.json +24 -0
  233. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/william-friedkin/CHANGELOG.md +51 -0
  234. package/augment-extensions/writing-standards/screenplay/cinematic-styles/directors/william-friedkin/metadata.json +24 -0
  235. package/augment-extensions/writing-standards/screenplay/cinematic-styles/films/CHANGELOG.md +51 -0
  236. package/augment-extensions/writing-standards/screenplay/cinematic-styles/films/blue-ruin/CHANGELOG.md +51 -0
  237. package/augment-extensions/writing-standards/screenplay/cinematic-styles/films/blue-ruin/metadata.json +24 -0
  238. package/augment-extensions/writing-standards/screenplay/cinematic-styles/films/metadata.json +24 -0
  239. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/CHANGELOG.md +51 -0
  240. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/fast-and-furious/CHANGELOG.md +51 -0
  241. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/fast-and-furious/metadata.json +24 -0
  242. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/harry-potter/CHANGELOG.md +51 -0
  243. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/harry-potter/metadata.json +24 -0
  244. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/james-bond/CHANGELOG.md +51 -0
  245. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/james-bond/metadata.json +24 -0
  246. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/john-wick/CHANGELOG.md +51 -0
  247. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/john-wick/metadata.json +24 -0
  248. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/lord-of-the-rings/CHANGELOG.md +51 -0
  249. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/lord-of-the-rings/metadata.json +24 -0
  250. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/mcu/CHANGELOG.md +51 -0
  251. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/mcu/metadata.json +25 -0
  252. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/metadata.json +25 -0
  253. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/star-trek/CHANGELOG.md +51 -0
  254. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/star-trek/metadata.json +33 -0
  255. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/star-wars/CHANGELOG.md +51 -0
  256. package/augment-extensions/writing-standards/screenplay/cinematic-styles/franchises/star-wars/metadata.json +24 -0
  257. package/augment-extensions/writing-standards/screenplay/cinematic-styles/metadata.json +50 -0
  258. package/augment-extensions/writing-standards/screenplay/cinematic-styles/narrative-theory/CHANGELOG.md +51 -0
  259. package/augment-extensions/writing-standards/screenplay/cinematic-styles/narrative-theory/joseph-campbell/CHANGELOG.md +51 -0
  260. package/augment-extensions/writing-standards/screenplay/cinematic-styles/narrative-theory/joseph-campbell/metadata.json +24 -0
  261. package/augment-extensions/writing-standards/screenplay/cinematic-styles/narrative-theory/metadata.json +24 -0
  262. package/augment-extensions/writing-standards/screenplay/cinematic-styles/producers/CHANGELOG.md +51 -0
  263. package/augment-extensions/writing-standards/screenplay/cinematic-styles/producers/bruckheimer-and-simpson/CHANGELOG.md +51 -0
  264. package/augment-extensions/writing-standards/screenplay/cinematic-styles/producers/bruckheimer-and-simpson/metadata.json +24 -0
  265. package/augment-extensions/writing-standards/screenplay/cinematic-styles/producers/metadata.json +23 -0
  266. package/augment-extensions/writing-standards/screenplay/genres/CHANGELOG.md +51 -0
  267. package/augment-extensions/writing-standards/screenplay/genres/metadata.json +43 -0
  268. package/augment-extensions/writing-standards/screenplay/metadata.json +65 -0
  269. package/augment-extensions/writing-standards/screenplay/styles/CHANGELOG.md +51 -0
  270. package/augment-extensions/writing-standards/screenplay/styles/metadata.json +38 -0
  271. package/augment-extensions/writing-standards/screenplay/themes/CHANGELOG.md +51 -0
  272. package/augment-extensions/writing-standards/screenplay/themes/metadata.json +47 -0
  273. package/cli/dist/__test_health-checker.d.ts +2 -0
  274. package/cli/dist/__test_health-checker.d.ts.map +1 -0
  275. package/cli/dist/__test_health-checker.js +4 -0
  276. package/cli/dist/__test_health-checker.js.map +1 -0
  277. package/cli/dist/__test_template-engine.d.ts +2 -0
  278. package/cli/dist/__test_template-engine.d.ts.map +1 -0
  279. package/cli/dist/__test_template-engine.js +4 -0
  280. package/cli/dist/__test_template-engine.js.map +1 -0
  281. package/cli/dist/cli.js +25 -0
  282. package/cli/dist/cli.js.map +1 -1
  283. package/cli/dist/commands/generate-shot-list/generator/index.d.ts +8 -2
  284. package/cli/dist/commands/generate-shot-list/generator/index.d.ts.map +1 -1
  285. package/cli/dist/commands/generate-shot-list/generator/index.js +28 -3
  286. package/cli/dist/commands/generate-shot-list/generator/index.js.map +1 -1
  287. package/cli/dist/commands/generate-shot-list/generator/types.d.ts +3 -0
  288. package/cli/dist/commands/generate-shot-list/generator/types.d.ts.map +1 -1
  289. package/cli/dist/commands/generate-shot-list/help-text.d.ts +1 -1
  290. package/cli/dist/commands/generate-shot-list/help-text.d.ts.map +1 -1
  291. package/cli/dist/commands/generate-shot-list/help-text.js +48 -5
  292. package/cli/dist/commands/generate-shot-list/help-text.js.map +1 -1
  293. package/cli/dist/commands/generate-shot-list/logger/jsonl-writer.d.ts +11 -1
  294. package/cli/dist/commands/generate-shot-list/logger/jsonl-writer.d.ts.map +1 -1
  295. package/cli/dist/commands/generate-shot-list/logger/jsonl-writer.js +61 -1
  296. package/cli/dist/commands/generate-shot-list/logger/jsonl-writer.js.map +1 -1
  297. package/cli/dist/commands/generate-shot-list/parser/docx-parser.d.ts +29 -0
  298. package/cli/dist/commands/generate-shot-list/parser/docx-parser.d.ts.map +1 -0
  299. package/cli/dist/commands/generate-shot-list/parser/docx-parser.js +111 -0
  300. package/cli/dist/commands/generate-shot-list/parser/docx-parser.js.map +1 -0
  301. package/cli/dist/commands/generate-shot-list/parser/finaldraft-parser.d.ts +18 -0
  302. package/cli/dist/commands/generate-shot-list/parser/finaldraft-parser.d.ts.map +1 -0
  303. package/cli/dist/commands/generate-shot-list/parser/finaldraft-parser.js +184 -0
  304. package/cli/dist/commands/generate-shot-list/parser/finaldraft-parser.js.map +1 -0
  305. package/cli/dist/commands/generate-shot-list/parser/index.d.ts +4 -3
  306. package/cli/dist/commands/generate-shot-list/parser/index.d.ts.map +1 -1
  307. package/cli/dist/commands/generate-shot-list/parser/index.js +54 -3
  308. package/cli/dist/commands/generate-shot-list/parser/index.js.map +1 -1
  309. package/cli/dist/commands/generate-shot-list/parser/pdf-parser.d.ts +24 -0
  310. package/cli/dist/commands/generate-shot-list/parser/pdf-parser.d.ts.map +1 -0
  311. package/cli/dist/commands/generate-shot-list/parser/pdf-parser.js +84 -0
  312. package/cli/dist/commands/generate-shot-list/parser/pdf-parser.js.map +1 -0
  313. package/cli/dist/commands/generate-shot-list/parser/rtf-parser.d.ts +28 -0
  314. package/cli/dist/commands/generate-shot-list/parser/rtf-parser.d.ts.map +1 -0
  315. package/cli/dist/commands/generate-shot-list/parser/rtf-parser.js +143 -0
  316. package/cli/dist/commands/generate-shot-list/parser/rtf-parser.js.map +1 -0
  317. package/cli/dist/commands/generate-shot-list/parser/types.d.ts +9 -6
  318. package/cli/dist/commands/generate-shot-list/parser/types.d.ts.map +1 -1
  319. package/cli/dist/commands/generate-shot-list/parser/types.js.map +1 -1
  320. package/cli/dist/commands/generate-shot-list/style/guideline-parser.d.ts +36 -0
  321. package/cli/dist/commands/generate-shot-list/style/guideline-parser.d.ts.map +1 -0
  322. package/cli/dist/commands/generate-shot-list/style/guideline-parser.js +108 -0
  323. package/cli/dist/commands/generate-shot-list/style/guideline-parser.js.map +1 -0
  324. package/cli/dist/commands/generate-shot-list/style/index.d.ts +39 -0
  325. package/cli/dist/commands/generate-shot-list/style/index.d.ts.map +1 -0
  326. package/cli/dist/commands/generate-shot-list/style/index.js +85 -0
  327. package/cli/dist/commands/generate-shot-list/style/index.js.map +1 -0
  328. package/cli/dist/commands/generate-shot-list/style/style-loader.d.ts +35 -0
  329. package/cli/dist/commands/generate-shot-list/style/style-loader.d.ts.map +1 -0
  330. package/cli/dist/commands/generate-shot-list/style/style-loader.js +178 -0
  331. package/cli/dist/commands/generate-shot-list/style/style-loader.js.map +1 -0
  332. package/cli/dist/commands/generate-shot-list/style/style-merger.d.ts +36 -0
  333. package/cli/dist/commands/generate-shot-list/style/style-merger.d.ts.map +1 -0
  334. package/cli/dist/commands/generate-shot-list/style/style-merger.js +123 -0
  335. package/cli/dist/commands/generate-shot-list/style/style-merger.js.map +1 -0
  336. package/cli/dist/commands/generate-shot-list/style/types.d.ts +105 -0
  337. package/cli/dist/commands/generate-shot-list/style/types.d.ts.map +1 -0
  338. package/cli/dist/commands/generate-shot-list/style/types.js +8 -0
  339. package/cli/dist/commands/generate-shot-list/style/types.js.map +1 -0
  340. package/cli/dist/commands/generate-shot-list.d.ts +1 -0
  341. package/cli/dist/commands/generate-shot-list.d.ts.map +1 -1
  342. package/cli/dist/commands/generate-shot-list.js +44 -1
  343. package/cli/dist/commands/generate-shot-list.js.map +1 -1
  344. package/cli/dist/commands/list.d.ts +1 -0
  345. package/cli/dist/commands/list.d.ts.map +1 -1
  346. package/cli/dist/commands/list.js +21 -5
  347. package/cli/dist/commands/list.js.map +1 -1
  348. package/cli/dist/commands/upgrade.d.ts +15 -0
  349. package/cli/dist/commands/upgrade.d.ts.map +1 -0
  350. package/cli/dist/commands/upgrade.js +229 -0
  351. package/cli/dist/commands/upgrade.js.map +1 -0
  352. package/cli/dist/commands/use.d.ts +15 -0
  353. package/cli/dist/commands/use.d.ts.map +1 -0
  354. package/cli/dist/commands/use.js +180 -0
  355. package/cli/dist/commands/use.js.map +1 -0
  356. package/cli/dist/commands/version-info.d.ts +15 -0
  357. package/cli/dist/commands/version-info.d.ts.map +1 -0
  358. package/cli/dist/commands/version-info.js +194 -0
  359. package/cli/dist/commands/version-info.js.map +1 -0
  360. package/cli/dist/core/compatibility-checker.d.ts +73 -0
  361. package/cli/dist/core/compatibility-checker.d.ts.map +1 -0
  362. package/cli/dist/core/compatibility-checker.js +188 -0
  363. package/cli/dist/core/compatibility-checker.js.map +1 -0
  364. package/cli/dist/core/index.d.ts +9 -0
  365. package/cli/dist/core/index.d.ts.map +1 -0
  366. package/cli/dist/core/index.js +16 -0
  367. package/cli/dist/core/index.js.map +1 -0
  368. package/cli/dist/core/module-loader.d.ts +68 -0
  369. package/cli/dist/core/module-loader.d.ts.map +1 -0
  370. package/cli/dist/core/module-loader.js +137 -0
  371. package/cli/dist/core/module-loader.js.map +1 -0
  372. package/cli/dist/core/version-manager.d.ts +62 -0
  373. package/cli/dist/core/version-manager.d.ts.map +1 -0
  374. package/cli/dist/core/version-manager.js +157 -0
  375. package/cli/dist/core/version-manager.js.map +1 -0
  376. package/cli/dist/core/version-resolver.d.ts +63 -0
  377. package/cli/dist/core/version-resolver.d.ts.map +1 -0
  378. package/cli/dist/core/version-resolver.js +163 -0
  379. package/cli/dist/core/version-resolver.js.map +1 -0
  380. package/cli/dist/gui/app.d.ts +17 -0
  381. package/cli/dist/gui/app.d.ts.map +1 -0
  382. package/cli/dist/gui/app.js +79 -0
  383. package/cli/dist/gui/app.js.map +1 -0
  384. package/cli/dist/gui/components/preview-pane.d.ts +40 -0
  385. package/cli/dist/gui/components/preview-pane.d.ts.map +1 -0
  386. package/cli/dist/gui/components/preview-pane.js +90 -0
  387. package/cli/dist/gui/components/preview-pane.js.map +1 -0
  388. package/cli/dist/gui/components/search-filter.d.ts +26 -0
  389. package/cli/dist/gui/components/search-filter.d.ts.map +1 -0
  390. package/cli/dist/gui/components/search-filter.js +168 -0
  391. package/cli/dist/gui/components/search-filter.js.map +1 -0
  392. package/cli/dist/gui/components/status-bar.d.ts +22 -0
  393. package/cli/dist/gui/components/status-bar.d.ts.map +1 -0
  394. package/cli/dist/gui/components/status-bar.js +58 -0
  395. package/cli/dist/gui/components/status-bar.js.map +1 -0
  396. package/cli/dist/gui/components/tree-navigator.d.ts +30 -0
  397. package/cli/dist/gui/components/tree-navigator.d.ts.map +1 -0
  398. package/cli/dist/gui/components/tree-navigator.js +133 -0
  399. package/cli/dist/gui/components/tree-navigator.js.map +1 -0
  400. package/cli/dist/gui/components/version-selector.d.ts +27 -0
  401. package/cli/dist/gui/components/version-selector.d.ts.map +1 -0
  402. package/cli/dist/gui/components/version-selector.js +110 -0
  403. package/cli/dist/gui/components/version-selector.js.map +1 -0
  404. package/cli/dist/gui/hooks/use-version-loader.d.ts +25 -0
  405. package/cli/dist/gui/hooks/use-version-loader.d.ts.map +1 -0
  406. package/cli/dist/gui/hooks/use-version-loader.js +116 -0
  407. package/cli/dist/gui/hooks/use-version-loader.js.map +1 -0
  408. package/cli/dist/gui/index.d.ts +15 -0
  409. package/cli/dist/gui/index.d.ts.map +1 -0
  410. package/cli/dist/gui/index.js +39 -0
  411. package/cli/dist/gui/index.js.map +1 -0
  412. package/cli/dist/gui/layouts/main-layout.d.ts +14 -0
  413. package/cli/dist/gui/layouts/main-layout.d.ts.map +1 -0
  414. package/cli/dist/gui/layouts/main-layout.js +205 -0
  415. package/cli/dist/gui/layouts/main-layout.js.map +1 -0
  416. package/cli/dist/gui/state/navigation-state.d.ts +39 -0
  417. package/cli/dist/gui/state/navigation-state.d.ts.map +1 -0
  418. package/cli/dist/gui/state/navigation-state.js +151 -0
  419. package/cli/dist/gui/state/navigation-state.js.map +1 -0
  420. package/cli/dist/gui/state/selection-state.d.ts +36 -0
  421. package/cli/dist/gui/state/selection-state.d.ts.map +1 -0
  422. package/cli/dist/gui/state/selection-state.js +132 -0
  423. package/cli/dist/gui/state/selection-state.js.map +1 -0
  424. package/cli/dist/gui/theme.d.ts +50 -0
  425. package/cli/dist/gui/theme.d.ts.map +1 -0
  426. package/cli/dist/gui/theme.js +73 -0
  427. package/cli/dist/gui/theme.js.map +1 -0
  428. package/cli/dist/utils/help.d.ts +13 -0
  429. package/cli/dist/utils/help.d.ts.map +1 -0
  430. package/cli/dist/utils/help.js +137 -0
  431. package/cli/dist/utils/help.js.map +1 -0
  432. package/cli/dist/utils/module-system.d.ts +8 -0
  433. package/cli/dist/utils/module-system.d.ts.map +1 -1
  434. package/cli/dist/utils/module-system.js +38 -3
  435. package/cli/dist/utils/module-system.js.map +1 -1
  436. package/cli/dist/utils/validate-versioning.d.ts +43 -0
  437. package/cli/dist/utils/validate-versioning.d.ts.map +1 -0
  438. package/cli/dist/utils/validate-versioning.js +258 -0
  439. package/cli/dist/utils/validate-versioning.js.map +1 -0
  440. package/package.json +10 -1
@@ -0,0 +1,918 @@
1
+ # TypeScript Testing Strategies
2
+
3
+ Comprehensive guide to testing TypeScript applications covering unit, integration, and end-to-end testing patterns.
4
+
5
+ ## Table of Contents
6
+ - [Testing Pyramid](#testing-pyramid)
7
+ - [Unit Testing](#unit-testing)
8
+ - [Integration Testing](#integration-testing)
9
+ - [End-to-End Testing](#end-to-end-testing)
10
+ - [Snapshot vs Assertion Testing](#snapshot-vs-assertion-testing)
11
+ - [Property-Based Testing](#property-based-testing)
12
+ - [Test Organization Patterns](#test-organization-patterns)
13
+ - [MSW for API Mocking](#msw-for-api-mocking)
14
+ - [Best Practices](#best-practices)
15
+
16
+ ---
17
+
18
+ ## Testing Pyramid
19
+
20
+ The testing pyramid guides test distribution:
21
+
22
+ ```
23
+ /\
24
+ /E2E\ ← Few (5-10%)
25
+ /------\
26
+ / INT \ ← Some (20-30%)
27
+ /----------\
28
+ / UNIT \ ← Many (60-75%)
29
+ /--------------\
30
+ ```
31
+
32
+ **Principles:**
33
+ - **Unit tests**: Fast, isolated, many
34
+ - **Integration tests**: Medium speed, test component interactions
35
+ - **E2E tests**: Slow, expensive, critical user flows only
36
+
37
+ ---
38
+
39
+ ## Unit Testing
40
+
41
+ ### Basic Unit Test Structure
42
+
43
+ ```typescript
44
+ // user-service.test.ts
45
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
46
+ import { UserService } from './user-service';
47
+ import type { UserRepository } from './user-repository';
48
+
49
+ describe('UserService', () => {
50
+ let userService: UserService;
51
+ let mockRepository: UserRepository;
52
+
53
+ beforeEach(() => {
54
+ // Setup fresh mocks for each test
55
+ mockRepository = {
56
+ findById: vi.fn(),
57
+ save: vi.fn(),
58
+ delete: vi.fn()
59
+ };
60
+ userService = new UserService(mockRepository);
61
+ });
62
+
63
+ describe('getUser', () => {
64
+ it('should return user when found', async () => {
65
+ // Arrange
66
+ const mockUser = { id: '1', name: 'John Doe', email: 'john@example.com' };
67
+ mockRepository.findById.mockResolvedValue(mockUser);
68
+
69
+ // Act
70
+ const result = await userService.getUser('1');
71
+
72
+ // Assert
73
+ expect(result).toEqual(mockUser);
74
+ expect(mockRepository.findById).toHaveBeenCalledWith('1');
75
+ expect(mockRepository.findById).toHaveBeenCalledTimes(1);
76
+ });
77
+
78
+ it('should throw error when user not found', async () => {
79
+ // Arrange
80
+ mockRepository.findById.mockResolvedValue(null);
81
+
82
+ // Act & Assert
83
+ await expect(userService.getUser('999')).rejects.toThrow('User not found');
84
+ });
85
+ });
86
+ });
87
+ ```
88
+
89
+ ### Testing Async Code
90
+
91
+ ```typescript
92
+ // async-operations.test.ts
93
+ import { describe, it, expect } from 'vitest';
94
+ import { fetchUserData, retryOperation } from './async-operations';
95
+
96
+ describe('Async Operations', () => {
97
+ it('should handle async/await', async () => {
98
+ const data = await fetchUserData('123');
99
+ expect(data).toBeDefined();
100
+ });
101
+
102
+ it('should handle promise rejection', async () => {
103
+ await expect(fetchUserData('invalid')).rejects.toThrow('Invalid user ID');
104
+ });
105
+
106
+ it('should retry failed operations', async () => {
107
+ let attempts = 0;
108
+ const operation = vi.fn(async () => {
109
+ attempts++;
110
+ if (attempts < 3) throw new Error('Temporary failure');
111
+ return 'success';
112
+ });
113
+
114
+ const result = await retryOperation(operation, { maxRetries: 3 });
115
+ expect(result).toBe('success');
116
+ expect(operation).toHaveBeenCalledTimes(3);
117
+ });
118
+ });
119
+ ```
120
+
121
+ ### Testing React Components
122
+
123
+ ```typescript
124
+ // button.test.tsx
125
+ import { describe, it, expect, vi } from 'vitest';
126
+ import { render, screen, fireEvent } from '@testing-library/react';
127
+ import { Button } from './button';
128
+
129
+ describe('Button', () => {
130
+ it('should render with text', () => {
131
+ render(<Button>Click me</Button>);
132
+ expect(screen.getByRole('button')).toHaveTextContent('Click me');
133
+ });
134
+
135
+ it('should call onClick when clicked', () => {
136
+ const handleClick = vi.fn();
137
+ render(<Button onClick={handleClick}>Click me</Button>);
138
+
139
+ fireEvent.click(screen.getByRole('button'));
140
+ expect(handleClick).toHaveBeenCalledTimes(1);
141
+ });
142
+
143
+ it('should be disabled when disabled prop is true', () => {
144
+ render(<Button disabled>Click me</Button>);
145
+ expect(screen.getByRole('button')).toBeDisabled();
146
+ });
147
+
148
+ it('should apply custom className', () => {
149
+ render(<Button className="custom-class">Click me</Button>);
150
+ expect(screen.getByRole('button')).toHaveClass('custom-class');
151
+ });
152
+ });
153
+ ```
154
+
155
+ ### Testing Database Integration
156
+
157
+ ```typescript
158
+ // user-repository.integration.test.ts
159
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
160
+ import { UserRepository } from './user-repository';
161
+ import { createTestDatabase, cleanupDatabase } from '../test-utils/db';
162
+
163
+ describe('UserRepository Integration', () => {
164
+ let repository: UserRepository;
165
+ let db: Database;
166
+
167
+ beforeEach(async () => {
168
+ db = await createTestDatabase();
169
+ repository = new UserRepository(db);
170
+ });
171
+
172
+ afterEach(async () => {
173
+ await cleanupDatabase(db);
174
+ });
175
+
176
+ it('should save and retrieve user', async () => {
177
+ const user = { name: 'John Doe', email: 'john@example.com' };
178
+
179
+ const saved = await repository.save(user);
180
+ expect(saved.id).toBeDefined();
181
+
182
+ const retrieved = await repository.findById(saved.id);
183
+ expect(retrieved).toEqual(saved);
184
+ });
185
+
186
+ it('should update existing user', async () => {
187
+ const user = await repository.save({ name: 'John', email: 'john@example.com' });
188
+
189
+ const updated = await repository.save({ ...user, name: 'Jane' });
190
+ expect(updated.name).toBe('Jane');
191
+ expect(updated.id).toBe(user.id);
192
+ });
193
+ });
194
+ ```
195
+
196
+ ---
197
+
198
+ ## End-to-End Testing
199
+
200
+ ### Playwright E2E Tests
201
+
202
+ ```typescript
203
+ // login.e2e.test.ts
204
+ import { test, expect } from '@playwright/test';
205
+
206
+ test.describe('Login Flow', () => {
207
+ test('should login successfully with valid credentials', async ({ page }) => {
208
+ await page.goto('/login');
209
+
210
+ await page.fill('input[name="email"]', 'user@example.com');
211
+ await page.fill('input[name="password"]', 'password123');
212
+ await page.click('button[type="submit"]');
213
+
214
+ await expect(page).toHaveURL('/dashboard');
215
+ await expect(page.locator('h1')).toContainText('Welcome');
216
+ });
217
+
218
+ test('should show error with invalid credentials', async ({ page }) => {
219
+ await page.goto('/login');
220
+
221
+ await page.fill('input[name="email"]', 'wrong@example.com');
222
+ await page.fill('input[name="password"]', 'wrongpass');
223
+ await page.click('button[type="submit"]');
224
+
225
+ await expect(page.locator('.error-message')).toContainText('Invalid credentials');
226
+ });
227
+ });
228
+ ```
229
+
230
+ ### Cypress E2E Tests
231
+
232
+ ```typescript
233
+ // checkout.cy.ts
234
+ describe('Checkout Flow', () => {
235
+ beforeEach(() => {
236
+ cy.visit('/products');
237
+ });
238
+
239
+ it('should complete purchase', () => {
240
+ // Add item to cart
241
+ cy.get('[data-testid="product-1"]').click();
242
+ cy.get('[data-testid="add-to-cart"]').click();
243
+
244
+ // Go to checkout
245
+ cy.get('[data-testid="cart-icon"]').click();
246
+ cy.get('[data-testid="checkout-button"]').click();
247
+
248
+ // Fill shipping info
249
+ cy.get('input[name="address"]').type('123 Main St');
250
+ cy.get('input[name="city"]').type('New York');
251
+ cy.get('input[name="zip"]').type('10001');
252
+
253
+ // Submit order
254
+ cy.get('button[type="submit"]').click();
255
+
256
+ // Verify success
257
+ cy.url().should('include', '/order-confirmation');
258
+ cy.contains('Order placed successfully').should('be.visible');
259
+ });
260
+ });
261
+ ```
262
+
263
+ ---
264
+
265
+ ## Snapshot vs Assertion Testing
266
+
267
+ ### Snapshot Testing
268
+
269
+ **Use for:**
270
+ - Component rendering output
271
+ - API response structures
272
+ - Configuration objects
273
+ - Error messages
274
+
275
+ ```typescript
276
+ // component-snapshot.test.tsx
277
+ import { describe, it, expect } from 'vitest';
278
+ import { render } from '@testing-library/react';
279
+ import { UserCard } from './user-card';
280
+
281
+ describe('UserCard Snapshots', () => {
282
+ it('should match snapshot', () => {
283
+ const { container } = render(
284
+ <UserCard
285
+ name="John Doe"
286
+ email="john@example.com"
287
+ role="admin"
288
+ />
289
+ );
290
+ expect(container).toMatchSnapshot();
291
+ });
292
+
293
+ it('should match inline snapshot', () => {
294
+ const config = {
295
+ apiUrl: 'https://api.example.com',
296
+ timeout: 5000,
297
+ retries: 3
298
+ };
299
+ expect(config).toMatchInlineSnapshot(`
300
+ {
301
+ "apiUrl": "https://api.example.com",
302
+ "retries": 3,
303
+ "timeout": 5000,
304
+ }
305
+ `);
306
+ });
307
+ });
308
+ ```
309
+
310
+ ### Assertion Testing
311
+
312
+ **Use for:**
313
+ - Business logic
314
+ - Calculations
315
+ - State changes
316
+ - Specific behaviors
317
+
318
+ ```typescript
319
+ // assertion-testing.test.ts
320
+ import { describe, it, expect } from 'vitest';
321
+ import { calculateDiscount, validateEmail } from './utils';
322
+
323
+ describe('Assertion Testing', () => {
324
+ it('should calculate discount correctly', () => {
325
+ expect(calculateDiscount(100, 0.1)).toBe(10);
326
+ expect(calculateDiscount(50, 0.2)).toBe(10);
327
+ expect(calculateDiscount(0, 0.5)).toBe(0);
328
+ });
329
+
330
+ it('should validate email format', () => {
331
+ expect(validateEmail('user@example.com')).toBe(true);
332
+ expect(validateEmail('invalid-email')).toBe(false);
333
+ expect(validateEmail('')).toBe(false);
334
+ });
335
+ });
336
+ ```
337
+
338
+ **When to use each:**
339
+
340
+ | Snapshot Testing | Assertion Testing |
341
+ |-----------------|-------------------|
342
+ | UI component output | Business logic |
343
+ | Large data structures | Specific values |
344
+ | Regression detection | Behavior verification |
345
+ | Quick to write | More explicit |
346
+ | Can be brittle | More maintainable |
347
+
348
+ ---
349
+
350
+ ## Property-Based Testing
351
+
352
+ Property-based testing generates random inputs to test invariants.
353
+
354
+ ### Using fast-check
355
+
356
+ ```typescript
357
+ // property-based.test.ts
358
+ import { describe, it, expect } from 'vitest';
359
+ import fc from 'fast-check';
360
+ import { sortArray, reverseString, addNumbers } from './utils';
361
+
362
+ describe('Property-Based Testing', () => {
363
+ it('sorting should be idempotent', () => {
364
+ fc.assert(
365
+ fc.property(fc.array(fc.integer()), (arr) => {
366
+ const sorted1 = sortArray(arr);
367
+ const sorted2 = sortArray(sorted1);
368
+ expect(sorted1).toEqual(sorted2);
369
+ })
370
+ );
371
+ });
372
+
373
+ it('reversing twice should return original', () => {
374
+ fc.assert(
375
+ fc.property(fc.string(), (str) => {
376
+ const reversed = reverseString(reverseString(str));
377
+ expect(reversed).toBe(str);
378
+ })
379
+ );
380
+ });
381
+
382
+ it('addition should be commutative', () => {
383
+ fc.assert(
384
+ fc.property(fc.integer(), fc.integer(), (a, b) => {
385
+ expect(addNumbers(a, b)).toBe(addNumbers(b, a));
386
+ })
387
+ );
388
+ });
389
+
390
+ it('array length should be preserved after mapping', () => {
391
+ fc.assert(
392
+ fc.property(fc.array(fc.anything()), (arr) => {
393
+ const mapped = arr.map(x => x);
394
+ expect(mapped.length).toBe(arr.length);
395
+ })
396
+ );
397
+ });
398
+ });
399
+ ```
400
+
401
+ ### Custom Generators
402
+
403
+ ```typescript
404
+ // custom-generators.test.ts
405
+ import fc from 'fast-check';
406
+
407
+ // Custom user generator
408
+ const userArbitrary = fc.record({
409
+ id: fc.uuid(),
410
+ name: fc.string({ minLength: 1, maxLength: 50 }),
411
+ email: fc.emailAddress(),
412
+ age: fc.integer({ min: 18, max: 120 }),
413
+ role: fc.constantFrom('admin', 'user', 'guest')
414
+ });
415
+
416
+ describe('User Validation', () => {
417
+ it('should validate all generated users', () => {
418
+ fc.assert(
419
+ fc.property(userArbitrary, (user) => {
420
+ expect(user.age).toBeGreaterThanOrEqual(18);
421
+ expect(user.email).toContain('@');
422
+ expect(['admin', 'user', 'guest']).toContain(user.role);
423
+ })
424
+ );
425
+ });
426
+ });
427
+ ```
428
+
429
+ ---
430
+
431
+ ## Test Organization Patterns
432
+
433
+ ### File Structure
434
+
435
+ ```
436
+ src/
437
+ ├── components/
438
+ │ ├── button/
439
+ │ │ ├── button.tsx
440
+ │ │ ├── button.test.tsx # Unit tests
441
+ │ │ └── button.stories.tsx # Storybook
442
+ │ └── user-profile/
443
+ │ ├── user-profile.tsx
444
+ │ ├── user-profile.test.tsx
445
+ │ └── user-profile.integration.test.tsx
446
+ ├── services/
447
+ │ ├── user-service.ts
448
+ │ └── user-service.test.ts
449
+ └── __tests__/
450
+ ├── integration/ # Integration tests
451
+ │ └── api.integration.test.ts
452
+ └── e2e/ # E2E tests
453
+ └── checkout.e2e.test.ts
454
+ ```
455
+
456
+ ### Test Naming Conventions
457
+
458
+ ```typescript
459
+ // ✅ Good - Descriptive test names
460
+ describe('UserService', () => {
461
+ describe('getUser', () => {
462
+ it('should return user when found', () => {});
463
+ it('should throw UserNotFoundError when user does not exist', () => {});
464
+ it('should cache user data after first fetch', () => {});
465
+ });
466
+
467
+ describe('createUser', () => {
468
+ it('should create user with valid data', () => {});
469
+ it('should throw ValidationError when email is invalid', () => {});
470
+ it('should hash password before saving', () => {});
471
+ });
472
+ });
473
+
474
+ // ❌ Bad - Vague test names
475
+ describe('UserService', () => {
476
+ it('works', () => {});
477
+ it('test1', () => {});
478
+ it('should handle errors', () => {});
479
+ });
480
+ ```
481
+
482
+ ### Test Helpers and Utilities
483
+
484
+ ```typescript
485
+ // test-utils/factories.ts
486
+ export const createMockUser = (overrides?: Partial<User>): User => ({
487
+ id: '123',
488
+ name: 'Test User',
489
+ email: 'test@example.com',
490
+ role: 'user',
491
+ ...overrides
492
+ });
493
+
494
+ export const createMockProduct = (overrides?: Partial<Product>): Product => ({
495
+ id: '456',
496
+ name: 'Test Product',
497
+ price: 99.99,
498
+ stock: 10,
499
+ ...overrides
500
+ });
501
+
502
+ // test-utils/render.tsx
503
+ import { render, RenderOptions } from '@testing-library/react';
504
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
505
+
506
+ export const renderWithProviders = (
507
+ ui: React.ReactElement,
508
+ options?: RenderOptions
509
+ ) => {
510
+ const queryClient = new QueryClient({
511
+ defaultOptions: {
512
+ queries: { retry: false },
513
+ mutations: { retry: false }
514
+ }
515
+ });
516
+
517
+ return render(
518
+ <QueryClientProvider client={queryClient}>
519
+ {ui}
520
+ </QueryClientProvider>,
521
+ options
522
+ );
523
+ };
524
+ ```
525
+
526
+ ---
527
+
528
+ ## MSW for API Mocking
529
+
530
+ Mock Service Worker (MSW) intercepts network requests for testing.
531
+
532
+ ### Setup
533
+
534
+ ```typescript
535
+ // test-utils/msw-setup.ts
536
+ import { setupServer } from 'msw/node';
537
+ import { http, HttpResponse } from 'msw';
538
+
539
+ export const handlers = [
540
+ // GET request
541
+ http.get('/api/users/:id', ({ params }) => {
542
+ return HttpResponse.json({
543
+ id: params.id,
544
+ name: 'John Doe',
545
+ email: 'john@example.com'
546
+ });
547
+ }),
548
+
549
+ // POST request
550
+ http.post('/api/users', async ({ request }) => {
551
+ const body = await request.json();
552
+ return HttpResponse.json(
553
+ { id: '123', ...body },
554
+ { status: 201 }
555
+ );
556
+ }),
557
+
558
+ // Error response
559
+ http.get('/api/users/error', () => {
560
+ return HttpResponse.json(
561
+ { error: 'User not found' },
562
+ { status: 404 }
563
+ );
564
+ }),
565
+
566
+ // Delayed response
567
+ http.get('/api/slow', async () => {
568
+ await delay(1000);
569
+ return HttpResponse.json({ data: 'slow response' });
570
+ })
571
+ ];
572
+
573
+ export const server = setupServer(...handlers);
574
+ ```
575
+
576
+ ### Test Setup
577
+
578
+ ```typescript
579
+ // vitest.setup.ts
580
+ import { beforeAll, afterEach, afterAll } from 'vitest';
581
+ import { server } from './test-utils/msw-setup';
582
+
583
+ beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
584
+ afterEach(() => server.resetHandlers());
585
+ afterAll(() => server.close());
586
+ ```
587
+
588
+ ### Using MSW in Tests
589
+
590
+ ```typescript
591
+ // api-client.test.ts
592
+ import { describe, it, expect } from 'vitest';
593
+ import { server } from './test-utils/msw-setup';
594
+ import { http, HttpResponse } from 'msw';
595
+ import { fetchUser, createUser } from './api-client';
596
+
597
+ describe('API Client', () => {
598
+ it('should fetch user successfully', async () => {
599
+ const user = await fetchUser('123');
600
+
601
+ expect(user).toEqual({
602
+ id: '123',
603
+ name: 'John Doe',
604
+ email: 'john@example.com'
605
+ });
606
+ });
607
+
608
+ it('should handle 404 errors', async () => {
609
+ server.use(
610
+ http.get('/api/users/:id', () => {
611
+ return HttpResponse.json(
612
+ { error: 'Not found' },
613
+ { status: 404 }
614
+ );
615
+ })
616
+ );
617
+
618
+ await expect(fetchUser('999')).rejects.toThrow('Not found');
619
+ });
620
+
621
+ it('should create user', async () => {
622
+ const newUser = { name: 'Jane Doe', email: 'jane@example.com' };
623
+ const created = await createUser(newUser);
624
+
625
+ expect(created).toMatchObject(newUser);
626
+ expect(created.id).toBeDefined();
627
+ });
628
+
629
+ it('should handle network errors', async () => {
630
+ server.use(
631
+ http.get('/api/users/:id', () => {
632
+ return HttpResponse.error();
633
+ })
634
+ );
635
+
636
+ await expect(fetchUser('123')).rejects.toThrow('Network error');
637
+ });
638
+ });
639
+ ```
640
+
641
+ ### Advanced MSW Patterns
642
+
643
+ ```typescript
644
+ // Dynamic responses based on request
645
+ http.get('/api/search', ({ request }) => {
646
+ const url = new URL(request.url);
647
+ const query = url.searchParams.get('q');
648
+
649
+ if (!query) {
650
+ return HttpResponse.json({ results: [] });
651
+ }
652
+
653
+ return HttpResponse.json({
654
+ results: mockSearchResults.filter(r =>
655
+ r.title.toLowerCase().includes(query.toLowerCase())
656
+ )
657
+ });
658
+ });
659
+
660
+ // Stateful mocking
661
+ let users: User[] = [];
662
+
663
+ http.post('/api/users', async ({ request }) => {
664
+ const user = await request.json();
665
+ const newUser = { id: String(users.length + 1), ...user };
666
+ users.push(newUser);
667
+ return HttpResponse.json(newUser, { status: 201 });
668
+ });
669
+
670
+ http.get('/api/users', () => {
671
+ return HttpResponse.json(users);
672
+ });
673
+
674
+ // Request validation
675
+ http.post('/api/users', async ({ request }) => {
676
+ const body = await request.json();
677
+
678
+ if (!body.email || !body.name) {
679
+ return HttpResponse.json(
680
+ { error: 'Email and name are required' },
681
+ { status: 400 }
682
+ );
683
+ }
684
+
685
+ return HttpResponse.json({ id: '123', ...body }, { status: 201 });
686
+ });
687
+ ```
688
+
689
+ ---
690
+
691
+ ## Best Practices
692
+
693
+ ### DO ✅
694
+
695
+ **Write tests first (TDD)**
696
+ ```typescript
697
+ // 1. Write failing test
698
+ it('should calculate total price', () => {
699
+ expect(calculateTotal([10, 20, 30])).toBe(60);
700
+ });
701
+
702
+ // 2. Implement minimal code to pass
703
+ function calculateTotal(prices: number[]): number {
704
+ return prices.reduce((sum, price) => sum + price, 0);
705
+ }
706
+
707
+ // 3. Refactor
708
+ ```
709
+
710
+ **Use AAA pattern (Arrange, Act, Assert)**
711
+ ```typescript
712
+ it('should add item to cart', () => {
713
+ // Arrange
714
+ const cart = new ShoppingCart();
715
+ const item = { id: '1', name: 'Product', price: 10 };
716
+
717
+ // Act
718
+ cart.addItem(item);
719
+
720
+ // Assert
721
+ expect(cart.items).toHaveLength(1);
722
+ expect(cart.total).toBe(10);
723
+ });
724
+ ```
725
+
726
+ **Test behavior, not implementation**
727
+ ```typescript
728
+ // ✅ Good - Tests behavior
729
+ it('should display user name after login', async () => {
730
+ render(<App />);
731
+ await userEvent.type(screen.getByLabelText('Email'), 'user@example.com');
732
+ await userEvent.click(screen.getByRole('button', { name: 'Login' }));
733
+
734
+ expect(screen.getByText('Welcome, John')).toBeInTheDocument();
735
+ });
736
+
737
+ // ❌ Bad - Tests implementation
738
+ it('should call setState with user data', () => {
739
+ const setState = vi.fn();
740
+ // Testing internal implementation details
741
+ });
742
+ ```
743
+
744
+ **Keep tests independent**
745
+ ```typescript
746
+ // ✅ Good - Each test is independent
747
+ describe('UserService', () => {
748
+ let service: UserService;
749
+
750
+ beforeEach(() => {
751
+ service = new UserService();
752
+ });
753
+
754
+ it('test 1', () => { /* ... */ });
755
+ it('test 2', () => { /* ... */ });
756
+ });
757
+
758
+ // ❌ Bad - Tests depend on each other
759
+ describe('UserService', () => {
760
+ let user: User;
761
+
762
+ it('should create user', () => {
763
+ user = service.create({ name: 'John' });
764
+ });
765
+
766
+ it('should update user', () => {
767
+ service.update(user.id, { name: 'Jane' }); // Depends on previous test
768
+ });
769
+ });
770
+ ```
771
+
772
+ **Use descriptive test names**
773
+ ```typescript
774
+ // ✅ Good
775
+ it('should throw ValidationError when email is missing', () => {});
776
+ it('should return cached data on second request', () => {});
777
+ it('should retry failed requests up to 3 times', () => {});
778
+
779
+ // ❌ Bad
780
+ it('test email', () => {});
781
+ it('caching works', () => {});
782
+ it('retries', () => {});
783
+ ```
784
+
785
+ ### DON'T ❌
786
+
787
+ **Don't test external libraries**
788
+ ```typescript
789
+ // ❌ Bad - Testing React itself
790
+ it('useState should update state', () => {
791
+ // Don't test React's functionality
792
+ });
793
+
794
+ // ✅ Good - Test your code
795
+ it('should update count when button is clicked', () => {
796
+ // Test your component's behavior
797
+ });
798
+ ```
799
+
800
+ **Don't use real external services**
801
+ ```typescript
802
+ // ❌ Bad - Real API call
803
+ it('should fetch user', async () => {
804
+ const user = await fetch('https://api.example.com/users/1');
805
+ // Slow, unreliable, requires network
806
+ });
807
+
808
+ // ✅ Good - Mocked API
809
+ it('should fetch user', async () => {
810
+ server.use(
811
+ http.get('/api/users/1', () => HttpResponse.json(mockUser))
812
+ );
813
+ const user = await fetchUser('1');
814
+ });
815
+ ```
816
+
817
+ **Don't test too many things at once**
818
+ ```typescript
819
+ // ❌ Bad - Testing multiple behaviors
820
+ it('should handle user lifecycle', async () => {
821
+ const user = await createUser({ name: 'John' });
822
+ await updateUser(user.id, { name: 'Jane' });
823
+ await deleteUser(user.id);
824
+ // Too much in one test
825
+ });
826
+
827
+ // ✅ Good - Separate tests
828
+ it('should create user', async () => { /* ... */ });
829
+ it('should update user', async () => { /* ... */ });
830
+ it('should delete user', async () => { /* ... */ });
831
+ ```
832
+
833
+ ---
834
+
835
+ ## Summary
836
+
837
+ **Key Takeaways:**
838
+
839
+ 1. **Follow the testing pyramid** - Many unit tests, some integration tests, few E2E tests
840
+ 2. **Use MSW for API mocking** - Intercept network requests at the network level
841
+ 3. **Write descriptive test names** - Tests should document behavior
842
+ 4. **Keep tests independent** - Each test should run in isolation
843
+ 5. **Test behavior, not implementation** - Focus on what, not how
844
+ 6. **Use property-based testing** - For testing invariants and edge cases
845
+ 7. **Organize tests logically** - Co-locate tests with source code
846
+ 8. **Use snapshots sparingly** - Prefer explicit assertions for critical logic
847
+ 9. **Mock external dependencies** - Keep tests fast and reliable
848
+ 10. **Practice TDD** - Write tests first, then implement
849
+
850
+ **Testing Checklist:**
851
+
852
+ - [ ] Unit tests for all business logic
853
+ - [ ] Integration tests for component interactions
854
+ - [ ] E2E tests for critical user flows
855
+ - [ ] API mocking with MSW
856
+ - [ ] Test coverage > 80%
857
+ - [ ] All tests pass in CI/CD
858
+ - [ ] Tests run in < 10 seconds (unit tests)
859
+ - [ ] No flaky tests
860
+ - [ ] Tests are maintainable and readable
861
+
862
+ ---
863
+
864
+ ## References
865
+
866
+ - [Vitest Documentation](https://vitest.dev/)
867
+ - [Testing Library](https://testing-library.com/)
868
+ - [MSW Documentation](https://mswjs.io/)
869
+ - [Playwright](https://playwright.dev/)
870
+ - [fast-check](https://fast-check.dev/)
871
+ - [Kent C. Dodds - Testing Best Practices](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library)
872
+
873
+
874
+ ---
875
+
876
+ ## Integration Testing
877
+
878
+ ### Testing Component Integration
879
+
880
+ ```typescript
881
+ // user-profile.integration.test.tsx
882
+ import { describe, it, expect, beforeEach } from 'vitest';
883
+ import { render, screen, waitFor } from '@testing-library/react';
884
+ import { UserProfile } from './user-profile';
885
+ import { setupServer } from 'msw/node';
886
+ import { http, HttpResponse } from 'msw';
887
+
888
+ const server = setupServer(
889
+ http.get('/api/users/:id', ({ params }) => {
890
+ return HttpResponse.json({
891
+ id: params.id,
892
+ name: 'John Doe',
893
+ email: 'john@example.com'
894
+ });
895
+ })
896
+ );
897
+
898
+ beforeAll(() => server.listen());
899
+ afterEach(() => server.resetHandlers());
900
+ afterAll(() => server.close());
901
+
902
+ describe('UserProfile Integration', () => {
903
+ it('should fetch and display user data', async () => {
904
+ render(<UserProfile userId="123" />);
905
+
906
+ // Initially shows loading
907
+ expect(screen.getByText(/loading/i)).toBeInTheDocument();
908
+
909
+ // Wait for data to load
910
+ await waitFor(() => {
911
+ expect(screen.getByText('John Doe')).toBeInTheDocument();
912
+ });
913
+
914
+ expect(screen.getByText('john@example.com')).toBeInTheDocument();
915
+ });
916
+ });
917
+ ```
918
+