@qwickapps/react-framework 1.3.5 → 1.4.1

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 (320) hide show
  1. package/README.md +1691 -2
  2. package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts +66 -0
  3. package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts.map +1 -0
  4. package/dist/components/ErrorBoundary.d.ts +7 -0
  5. package/dist/components/ErrorBoundary.d.ts.map +1 -1
  6. package/dist/components/Html.d.ts +28 -18
  7. package/dist/components/Html.d.ts.map +1 -1
  8. package/dist/components/Logo.d.ts +12 -35
  9. package/dist/components/Logo.d.ts.map +1 -1
  10. package/dist/components/Markdown.d.ts +18 -13
  11. package/dist/components/Markdown.d.ts.map +1 -1
  12. package/dist/components/QwickApp.d.ts +16 -3
  13. package/dist/components/QwickApp.d.ts.map +1 -1
  14. package/dist/components/QwickIcon.d.ts +23 -0
  15. package/dist/components/QwickIcon.d.ts.map +1 -0
  16. package/dist/components/SafeSpan.d.ts +12 -5
  17. package/dist/components/SafeSpan.d.ts.map +1 -1
  18. package/dist/components/Scaffold.d.ts.map +1 -1
  19. package/dist/components/base/ModelView.d.ts +101 -0
  20. package/dist/components/base/ModelView.d.ts.map +1 -0
  21. package/dist/components/base/index.d.ts +11 -0
  22. package/dist/components/base/index.d.ts.map +1 -0
  23. package/dist/components/blocks/Article.d.ts +12 -2
  24. package/dist/components/blocks/Article.d.ts.map +1 -1
  25. package/dist/components/blocks/Code.d.ts +13 -2
  26. package/dist/components/blocks/Code.d.ts.map +1 -1
  27. package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -1
  28. package/dist/components/blocks/FeatureCard.d.ts.map +1 -1
  29. package/dist/components/blocks/FeatureGrid.d.ts.map +1 -1
  30. package/dist/components/blocks/Footer.d.ts.map +1 -1
  31. package/dist/components/blocks/HeroBlock.d.ts +27 -13
  32. package/dist/components/blocks/HeroBlock.d.ts.map +1 -1
  33. package/dist/components/blocks/Image.d.ts +41 -0
  34. package/dist/components/blocks/Image.d.ts.map +1 -0
  35. package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -1
  36. package/dist/components/blocks/Section.d.ts +16 -2
  37. package/dist/components/blocks/Section.d.ts.map +1 -1
  38. package/dist/components/blocks/Text.d.ts +41 -0
  39. package/dist/components/blocks/Text.d.ts.map +1 -0
  40. package/dist/components/blocks/index.d.ts +4 -0
  41. package/dist/components/blocks/index.d.ts.map +1 -1
  42. package/dist/components/buttons/Button.d.ts +23 -7
  43. package/dist/components/buttons/Button.d.ts.map +1 -1
  44. package/dist/components/forms/FormBlock.d.ts +19 -13
  45. package/dist/components/forms/FormBlock.d.ts.map +1 -1
  46. package/dist/components/index.d.ts +4 -0
  47. package/dist/components/index.d.ts.map +1 -1
  48. package/dist/components/input/ChoiceInputField.d.ts +17 -11
  49. package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
  50. package/dist/components/input/HtmlInputField.d.ts +17 -11
  51. package/dist/components/input/HtmlInputField.d.ts.map +1 -1
  52. package/dist/components/input/SelectInputField.d.ts +16 -10
  53. package/dist/components/input/SelectInputField.d.ts.map +1 -1
  54. package/dist/components/input/SwitchInputField.d.ts +16 -10
  55. package/dist/components/input/SwitchInputField.d.ts.map +1 -1
  56. package/dist/components/input/TextField.d.ts.map +1 -1
  57. package/dist/components/input/TextInputField.d.ts +16 -11
  58. package/dist/components/input/TextInputField.d.ts.map +1 -1
  59. package/dist/components/layout/GridCell.d.ts +23 -6
  60. package/dist/components/layout/GridCell.d.ts.map +1 -1
  61. package/dist/components/layout/GridLayout.d.ts +24 -23
  62. package/dist/components/layout/GridLayout.d.ts.map +1 -1
  63. package/dist/components/pages/FormPage.d.ts.map +1 -1
  64. package/dist/components/pages/Page.d.ts +49 -87
  65. package/dist/components/pages/Page.d.ts.map +1 -1
  66. package/dist/components/pages/index.d.ts +2 -2
  67. package/dist/components/pages/index.d.ts.map +1 -1
  68. package/dist/config/AppConfig.d.ts +49 -0
  69. package/dist/config/AppConfig.d.ts.map +1 -0
  70. package/dist/config/AppConfigBuilder.d.ts +75 -0
  71. package/dist/config/AppConfigBuilder.d.ts.map +1 -0
  72. package/dist/config/index.d.ts +13 -0
  73. package/dist/config/index.d.ts.map +1 -0
  74. package/dist/config/types.d.ts +130 -0
  75. package/dist/config/types.d.ts.map +1 -0
  76. package/dist/config.d.ts +15 -0
  77. package/dist/config.d.ts.map +1 -0
  78. package/dist/config.esm.js +451 -0
  79. package/dist/config.js +455 -0
  80. package/dist/contexts/PrintModeContext.d.ts +27 -0
  81. package/dist/contexts/PrintModeContext.d.ts.map +1 -0
  82. package/dist/contexts/QwickAppContext.d.ts +2 -2
  83. package/dist/contexts/QwickAppContext.d.ts.map +1 -1
  84. package/dist/contexts/index.d.ts +2 -0
  85. package/dist/contexts/index.d.ts.map +1 -1
  86. package/dist/hooks/index.d.ts +2 -0
  87. package/dist/hooks/index.d.ts.map +1 -1
  88. package/dist/hooks/usePrintMode.d.ts +39 -0
  89. package/dist/hooks/usePrintMode.d.ts.map +1 -0
  90. package/dist/index.css +1 -1
  91. package/dist/index.d.ts +1 -0
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.esm.css +1 -1
  94. package/dist/index.esm.js +10951 -6238
  95. package/dist/index.js +11014 -6287
  96. package/dist/schemas/CodeSchema.d.ts +2 -1
  97. package/dist/schemas/CodeSchema.d.ts.map +1 -1
  98. package/dist/schemas/CollapsibleLayoutSchema.d.ts +2 -1
  99. package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -1
  100. package/dist/schemas/ContentSchema.d.ts +2 -1
  101. package/dist/schemas/ContentSchema.d.ts.map +1 -1
  102. package/dist/schemas/GridCellSchema.d.ts +25 -0
  103. package/dist/schemas/GridCellSchema.d.ts.map +1 -0
  104. package/dist/schemas/GridLayoutSchema.d.ts +23 -0
  105. package/dist/schemas/GridLayoutSchema.d.ts.map +1 -0
  106. package/dist/schemas/HtmlSchema.d.ts +14 -0
  107. package/dist/schemas/HtmlSchema.d.ts.map +1 -0
  108. package/dist/schemas/ImageSchema.d.ts +32 -0
  109. package/dist/schemas/ImageSchema.d.ts.map +1 -0
  110. package/dist/schemas/LogoSchema.d.ts +35 -0
  111. package/dist/schemas/LogoSchema.d.ts.map +1 -0
  112. package/dist/schemas/MarkdownSchema.d.ts +14 -0
  113. package/dist/schemas/MarkdownSchema.d.ts.map +1 -0
  114. package/dist/schemas/PageTemplateSchema.d.ts +31 -0
  115. package/dist/schemas/PageTemplateSchema.d.ts.map +1 -0
  116. package/dist/schemas/PrintConfigSchema.d.ts +31 -0
  117. package/dist/schemas/PrintConfigSchema.d.ts.map +1 -0
  118. package/dist/schemas/SectionSchema.d.ts +2 -1
  119. package/dist/schemas/SectionSchema.d.ts.map +1 -1
  120. package/dist/schemas/TextSchema.d.ts +37 -0
  121. package/dist/schemas/TextSchema.d.ts.map +1 -0
  122. package/dist/schemas/ViewModelSchema.d.ts +23 -0
  123. package/dist/schemas/ViewModelSchema.d.ts.map +1 -0
  124. package/dist/schemas/index.d.ts +15 -1
  125. package/dist/schemas/index.d.ts.map +1 -1
  126. package/dist/schemas/transformers/ComponentTransformer.d.ts +116 -0
  127. package/dist/schemas/transformers/ComponentTransformer.d.ts.map +1 -0
  128. package/dist/schemas/transformers/ReactNodeTransformer.d.ts +53 -0
  129. package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -0
  130. package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts +66 -0
  131. package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts.map +1 -0
  132. package/dist/schemas/transformers/registry.d.ts +15 -0
  133. package/dist/schemas/transformers/registry.d.ts.map +1 -0
  134. package/dist/schemas/types/Serializable.d.ts +46 -0
  135. package/dist/schemas/types/Serializable.d.ts.map +1 -0
  136. package/dist/utils/htmlTransform.d.ts.map +1 -1
  137. package/dist/utils/reactUtils.d.ts +12 -3
  138. package/dist/utils/reactUtils.d.ts.map +1 -1
  139. package/package.json +17 -3
  140. package/src/{components/__tests__ → __tests__/components}/AccessibilityProvider.test.tsx +1 -1
  141. package/src/{components/__tests__ → __tests__/components}/Article.test.tsx +1 -1
  142. package/src/{components/__tests__ → __tests__/components}/Breadcrumbs.test.tsx +1 -1
  143. package/src/{components/__tests__ → __tests__/components}/Button.test.tsx +1 -1
  144. package/src/{components/__tests__ → __tests__/components}/CardListGrid.test.tsx +2 -2
  145. package/src/{components/__tests__ → __tests__/components}/ChoiceInputField.test.tsx +1 -1
  146. package/src/{components/__tests__ → __tests__/components}/Code.test.tsx +1 -1
  147. package/src/{components/__tests__ → __tests__/components}/Content.integration.test.tsx +1 -1
  148. package/src/{components/__tests__ → __tests__/components}/Content.test.tsx +1 -1
  149. package/src/{components/__tests__ → __tests__/components}/CoverImageHeader.test.tsx +2 -2
  150. package/src/{components/__tests__ → __tests__/components}/ErrorBoundary.test.tsx +1 -1
  151. package/src/{components/__tests__ → __tests__/components}/FeatureCard.integration.test.tsx +2 -2
  152. package/src/{components/__tests__ → __tests__/components}/FeatureGrid.integration.test.tsx +2 -2
  153. package/src/{components/__tests__ → __tests__/components}/FeatureGrid.test.tsx +2 -2
  154. package/src/{components/__tests__ → __tests__/components}/Footer.test.tsx +4 -4
  155. package/src/{components/__tests__ → __tests__/components}/FormBlock.test.tsx +1 -1
  156. package/src/{components/__tests__ → __tests__/components}/HeroBlock.integration.test.tsx +2 -2
  157. package/src/{components/__tests__ → __tests__/components}/HeroBlock.test.tsx +233 -7
  158. package/src/{components/__tests__ → __tests__/components}/Html.test.tsx +11 -2
  159. package/src/{components/__tests__ → __tests__/components}/HtmlInputField.test.tsx +3 -3
  160. package/src/__tests__/components/Logo.test.js +3 -3
  161. package/src/{components/__tests__ → __tests__/components}/Markdown.test.tsx +1 -1
  162. package/src/{components/__tests__ → __tests__/components}/PageBannerHeader.test.tsx +3 -3
  163. package/src/{components/__tests__ → __tests__/components}/PaletteSwitcher.test.tsx +3 -3
  164. package/src/{components/__tests__ → __tests__/components}/ProductCard.test.tsx +4 -4
  165. package/src/{components/__tests__ → __tests__/components}/SafeSpan.integration.test.tsx +2 -2
  166. package/src/{components/__tests__ → __tests__/components}/SafeSpan.simple.test.tsx +1 -1
  167. package/src/{components/__tests__ → __tests__/components}/SafeSpan.test.tsx +1 -1
  168. package/src/{components/__tests__ → __tests__/components}/Section.integration.test.tsx +1 -1
  169. package/src/{components/__tests__ → __tests__/components}/Section.test.tsx +1 -1
  170. package/src/{components/__tests__ → __tests__/components}/SelectInputField.test.tsx +1 -1
  171. package/src/{components/__tests__ → __tests__/components}/TextInputField.test.tsx +3 -3
  172. package/src/{components/__tests__ → __tests__/components}/ThemeSwitcher.test.tsx +3 -3
  173. package/src/__tests__/components/base/ModelView.test.tsx +220 -0
  174. package/src/__tests__/components/blocks/Code.performance.test.tsx +625 -0
  175. package/src/__tests__/components/blocks/Code.serialization.test.tsx +507 -0
  176. package/src/__tests__/components/blocks/HeroBlock.serialization.test.tsx +414 -0
  177. package/src/__tests__/components/blocks/Image.serialization.test.tsx +257 -0
  178. package/src/__tests__/components/blocks/Section.serialization.test.tsx +553 -0
  179. package/src/__tests__/components/blocks/Text.performance.test.tsx +442 -0
  180. package/src/__tests__/components/blocks/Text.serialization.test.tsx +491 -0
  181. package/src/__tests__/components/buttons/Button.serialization.test.tsx +443 -0
  182. package/src/__tests__/components/input/FormComponents.serialization.test.tsx +482 -0
  183. package/src/__tests__/components/input/SelectInputField.serialization.test.tsx +439 -0
  184. package/src/__tests__/components/input/TextInputField.serialization.test.tsx +359 -0
  185. package/src/{components/layout/CollapsibleLayout/__tests__ → __tests__/components/layout}/CollapsibleLayout.test.tsx +4 -4
  186. package/src/__tests__/components/layout/GridCell.serialization.test.tsx +403 -0
  187. package/src/__tests__/components/layout/GridLayout.serialization.test.tsx +311 -0
  188. package/src/__tests__/hooks/usePrintMode.test.ts +89 -0
  189. package/src/__tests__/schemas/PageTemplateSchema.test.ts +161 -0
  190. package/src/__tests__/schemas/PrintConfigSchema.test.ts +127 -0
  191. package/src/__tests__/schemas/ViewModelSchema.test.ts +80 -0
  192. package/src/__tests__/schemas/transformers/ComponentSerializationPatterns.test.tsx +602 -0
  193. package/src/__tests__/schemas/transformers/ComponentTransformer.htmlPatterns.test.ts +301 -0
  194. package/src/__tests__/schemas/transformers/ComponentTransformer.test.ts +521 -0
  195. package/src/__tests__/schemas/transformers/CrossBrowserCompatibility.test.ts +586 -0
  196. package/src/__tests__/schemas/transformers/MockSerializableComponent.ts +103 -0
  197. package/src/__tests__/schemas/transformers/RealWorldScenarios.test.tsx +1165 -0
  198. package/src/__tests__/schemas/transformers/SerializationErrorHandling.test.ts +602 -0
  199. package/src/__tests__/schemas/transformers/SerializationIntegration.test.tsx +691 -0
  200. package/src/__tests__/schemas/transformers/SerializationPerformance.test.ts +460 -0
  201. package/src/__tests__/schemas/transformers/TestAutomation.test.ts +597 -0
  202. package/src/{utils/__tests__ → __tests__/utils}/nested-dom-fix.test.tsx +1 -1
  203. package/src/components/ErrorBoundary.tsx +8 -8
  204. package/src/components/Html.tsx +147 -44
  205. package/src/components/Logo.tsx +198 -100
  206. package/src/components/Markdown.tsx +125 -16
  207. package/src/components/QwickApp.tsx +64 -31
  208. package/src/components/QwickIcon.tsx +59 -0
  209. package/src/components/SafeSpan.tsx +65 -10
  210. package/src/components/Scaffold.tsx +2 -8
  211. package/src/components/base/ModelView.tsx +199 -0
  212. package/src/components/base/index.ts +11 -0
  213. package/src/components/blocks/Article.tsx +57 -18
  214. package/src/components/blocks/Code.md +529 -0
  215. package/src/components/blocks/Code.tsx +102 -15
  216. package/src/components/blocks/CoverImageHeader.tsx +9 -4
  217. package/src/components/blocks/FeatureCard.tsx +1 -2
  218. package/src/components/blocks/FeatureGrid.tsx +19 -1
  219. package/src/components/blocks/Footer.tsx +13 -1
  220. package/src/components/blocks/HeroBlock.tsx +87 -20
  221. package/src/components/blocks/Image.tsx +395 -0
  222. package/src/components/blocks/PageBannerHeader.tsx +14 -12
  223. package/src/components/blocks/ProductCard.tsx +1 -1
  224. package/src/components/blocks/Section.tsx +113 -8
  225. package/src/components/blocks/Text.tsx +285 -0
  226. package/src/components/blocks/index.ts +4 -0
  227. package/src/components/buttons/Button.tsx +184 -15
  228. package/src/components/forms/FormBlock.tsx +70 -17
  229. package/src/components/index.ts +5 -0
  230. package/src/components/input/ChoiceInputField.tsx +48 -18
  231. package/src/components/input/HtmlInputField.tsx +48 -18
  232. package/src/components/input/SelectInputField.tsx +48 -16
  233. package/src/components/input/SwitchInputField.tsx +48 -17
  234. package/src/components/input/TextField.tsx +41 -1
  235. package/src/components/input/TextInputField.tsx +52 -18
  236. package/src/components/layout/GridCell.tsx +118 -9
  237. package/src/components/layout/GridLayout.tsx +125 -24
  238. package/src/components/pages/FormPage.tsx +0 -1
  239. package/src/components/pages/Page.css +304 -332
  240. package/src/components/pages/Page.tsx +307 -255
  241. package/src/components/pages/index.ts +2 -2
  242. package/src/config/AppConfig.ts +133 -0
  243. package/src/config/AppConfigBuilder.ts +421 -0
  244. package/src/config/__tests__/AppConfig.test.ts +385 -0
  245. package/src/config/__tests__/AppConfigBuilder.test.ts +432 -0
  246. package/src/config/index.ts +24 -0
  247. package/src/config/types.ts +170 -0
  248. package/src/config.ts +25 -0
  249. package/src/contexts/PrintModeContext.tsx +332 -0
  250. package/src/contexts/QwickAppContext.tsx +2 -2
  251. package/src/contexts/index.ts +2 -0
  252. package/src/hooks/index.ts +5 -1
  253. package/src/hooks/usePrintMode.ts +73 -0
  254. package/src/index.ts +3 -0
  255. package/src/schemas/CodeSchema.ts +3 -3
  256. package/src/schemas/CollapsibleLayoutSchema.ts +2 -1
  257. package/src/schemas/ContentSchema.ts +2 -1
  258. package/src/schemas/GridCellSchema.ts +164 -0
  259. package/src/schemas/GridLayoutSchema.ts +133 -0
  260. package/src/schemas/HtmlSchema.ts +47 -0
  261. package/src/schemas/ImageSchema.ts +235 -0
  262. package/src/schemas/LogoSchema.ts +241 -0
  263. package/src/schemas/MarkdownSchema.ts +47 -0
  264. package/src/schemas/PageTemplateSchema.ts +186 -0
  265. package/src/schemas/PrintConfigSchema.ts +207 -0
  266. package/src/schemas/README.md +661 -0
  267. package/src/schemas/SectionSchema.ts +2 -1
  268. package/src/schemas/TextSchema.ts +329 -0
  269. package/src/schemas/ViewModelSchema.ts +115 -0
  270. package/src/schemas/index.ts +21 -2
  271. package/src/schemas/transformers/ComponentTransformer.ts +403 -0
  272. package/src/schemas/transformers/ReactNodeTransformer.ts +236 -0
  273. package/src/schemas/transformers/registry.ts +72 -0
  274. package/src/schemas/types/Serializable.ts +51 -0
  275. package/src/stories/AccessibilityProvider.stories.tsx +253 -253
  276. package/src/stories/Article.stories.tsx +433 -433
  277. package/src/stories/Button.stories.tsx +1 -1
  278. package/src/stories/CardListGrid.stories.tsx +451 -451
  279. package/src/stories/ChoiceInputField.stories.tsx +503 -503
  280. package/src/stories/Code.stories.tsx +1 -1
  281. package/src/stories/CollapsibleLayout.stories.tsx +1414 -1414
  282. package/src/stories/Content.stories.tsx +393 -393
  283. package/src/stories/CoverImageHeader.stories.tsx +701 -701
  284. package/src/stories/DataBinding.advanced.stories.tsx +432 -432
  285. package/src/stories/DataProvider.stories.tsx +1192 -1192
  286. package/src/stories/FeatureCard.stories.tsx +557 -557
  287. package/src/stories/FeatureGrid.stories.tsx +594 -594
  288. package/src/stories/Footer.stories.tsx +640 -640
  289. package/src/stories/FormBlock.stories.tsx +760 -760
  290. package/src/stories/FormComponents.stories.tsx +349 -541
  291. package/src/stories/GridCell.stories.tsx +417 -0
  292. package/src/stories/GridLayout.stories.tsx +353 -0
  293. package/src/stories/HeroBlock.stories.tsx +862 -373
  294. package/src/stories/HtmlInputField.stories.tsx +474 -474
  295. package/src/stories/Image.stories.tsx +819 -0
  296. package/src/stories/Introduction.stories.tsx +667 -667
  297. package/src/stories/LayoutBlocks.stories.tsx +324 -324
  298. package/src/stories/Logo.stories.tsx +165 -6
  299. package/src/stories/Markdown.stories.tsx +137 -137
  300. package/src/stories/ModelView.stories.tsx +477 -0
  301. package/src/stories/Page.stories.tsx +688 -688
  302. package/src/stories/PageBannerHeader.stories.tsx +864 -864
  303. package/src/stories/PaletteSwitcher.stories.tsx +119 -119
  304. package/src/stories/ProductCard.stories.tsx +424 -424
  305. package/src/stories/QwickApp.stories.tsx +368 -368
  306. package/src/stories/ResponsiveMenu.stories.tsx +249 -249
  307. package/src/stories/SafeSpan.stories.tsx +531 -531
  308. package/src/stories/Section.stories.tsx +90 -2
  309. package/src/stories/SelectInputField.stories.tsx +524 -524
  310. package/src/stories/Text.stories.tsx +560 -0
  311. package/src/stories/TextInputField.stories.tsx +443 -443
  312. package/src/stories/ThemeSwitcher.stories.tsx +123 -123
  313. package/src/utils/htmlTransform.tsx +74 -53
  314. package/src/utils/reactUtils.tsx +57 -6
  315. package/dist/index.bundled.css +0 -12
  316. /package/src/{hooks/__tests__ → __tests__/hooks}/useDataBinding.test.tsx.disabled +0 -0
  317. /package/src/{schemas/__tests__ → __tests__/schemas}/builders.test.ts +0 -0
  318. /package/src/{utils/__tests__ → __tests__/utils}/createDataDrivenComponent.test.tsx.disabled +0 -0
  319. /package/src/{utils/__tests__ → __tests__/utils}/htmlTransform.test.tsx +0 -0
  320. /package/src/{utils/__tests__ → __tests__/utils}/optional-logging.test.ts +0 -0
@@ -0,0 +1,597 @@
1
+ /**
2
+ * Test Automation and CI/CD Integration Tests
3
+ *
4
+ * Tests for validating the entire QA pipeline including test automation,
5
+ * CI/CD integration, coverage enforcement, and quality gates.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+
10
+ import { ComponentTransformer } from '../ComponentTransformer';
11
+
12
+ /**
13
+ * QA Execution Summary Generator
14
+ * Provides structured reporting for CI/CD integration
15
+ */
16
+ export interface QALayerResult {
17
+ layer: string;
18
+ status: 'PASS' | 'FAIL' | 'SKIP';
19
+ duration: number;
20
+ issues: number;
21
+ details?: string;
22
+ }
23
+
24
+ export interface QASummary {
25
+ layers: QALayerResult[];
26
+ overallStatus: 'PASS' | 'FAIL';
27
+ totalDuration: number;
28
+ coverage: {
29
+ lines: number;
30
+ functions: number;
31
+ branches: number;
32
+ statements: number;
33
+ };
34
+ suggestions: string[];
35
+ keyFailures: {
36
+ layer: string;
37
+ testFile: string;
38
+ issue: string;
39
+ suggestedFix: string;
40
+ }[];
41
+ }
42
+
43
+ export class QAReporter {
44
+ private results: QALayerResult[] = [];
45
+ private startTime = Date.now();
46
+
47
+ addLayerResult(result: QALayerResult) {
48
+ this.results.push(result);
49
+ }
50
+
51
+ generateSummary(): QASummary {
52
+ const totalDuration = Date.now() - this.startTime;
53
+ const failedLayers = this.results.filter(r => r.status === 'FAIL');
54
+
55
+ return {
56
+ layers: this.results,
57
+ overallStatus: failedLayers.length === 0 ? 'PASS' : 'FAIL',
58
+ totalDuration,
59
+ coverage: {
60
+ lines: 85, // Mock coverage data - would come from real coverage tools
61
+ functions: 90,
62
+ branches: 78,
63
+ statements: 87
64
+ },
65
+ suggestions: this.generateSuggestions(),
66
+ keyFailures: this.generateKeyFailures()
67
+ };
68
+ }
69
+
70
+ private generateSuggestions(): string[] {
71
+ const suggestions: string[] = [];
72
+
73
+ const performanceIssues = this.results.filter(r => r.layer === 'Performance' && r.status === 'FAIL');
74
+ if (performanceIssues.length > 0) {
75
+ suggestions.push('Consider optimizing component deserialization for large datasets');
76
+ }
77
+
78
+ const coverageThreshold = 80;
79
+ // Mock coverage check
80
+ if (85 < coverageThreshold) {
81
+ suggestions.push('Add unit tests for uncovered serialization edge cases');
82
+ }
83
+
84
+ const errorHandlingIssues = this.results.filter(r => r.layer === 'Error Handling' && r.issues > 0);
85
+ if (errorHandlingIssues.length > 0) {
86
+ suggestions.push('Strengthen error boundary integration for unknown components');
87
+ }
88
+
89
+ return suggestions;
90
+ }
91
+
92
+ private generateKeyFailures() {
93
+ return this.results
94
+ .filter(r => r.status === 'FAIL')
95
+ .map(result => ({
96
+ layer: result.layer,
97
+ testFile: `${result.layer}Test.ts`,
98
+ issue: result.details || 'Test failed',
99
+ suggestedFix: this.getSuggestedFix(result.layer)
100
+ }));
101
+ }
102
+
103
+ private getSuggestedFix(layer: string): string {
104
+ const fixes: { [key: string]: string } = {
105
+ 'Lint': 'Run ESLint with --fix flag to auto-correct issues',
106
+ 'Types': 'Review TypeScript errors and add proper type definitions',
107
+ 'Unit': 'Update test assertions to match current implementation',
108
+ 'Integration': 'Verify component registration in test setup',
109
+ 'Performance': 'Profile slow operations and optimize bottlenecks',
110
+ 'Error Handling': 'Add proper error boundaries and graceful degradation'
111
+ };
112
+
113
+ return fixes[layer] || 'Review test output and fix failing assertions';
114
+ }
115
+
116
+ printSummary(summary: QASummary) {
117
+ console.log('\n## QA Execution Summary\n');
118
+
119
+ console.log('### Layers Run');
120
+ summary.layers.forEach(layer => {
121
+ const status = layer.status === 'PASS' ? '✅' : layer.status === 'FAIL' ? '❌' : '⏭️';
122
+ console.log(`- ${layer.layer}: ${status} ${layer.status} (issues: ${layer.issues}) - ${layer.duration}ms`);
123
+ });
124
+
125
+ console.log(`\n### Coverage`);
126
+ console.log(`- Lines: ${summary.coverage.lines}%`);
127
+ console.log(`- Functions: ${summary.coverage.functions}%`);
128
+ console.log(`- Branches: ${summary.coverage.branches}%`);
129
+ console.log(`- Statements: ${summary.coverage.statements}%`);
130
+
131
+ if (summary.keyFailures.length > 0) {
132
+ console.log('\n### Key Failures');
133
+ console.log('| Layer | Test/File | Issue | Suggested Fix |');
134
+ console.log('|-------|-----------|-------|---------------|');
135
+ summary.keyFailures.forEach(failure => {
136
+ console.log(`| ${failure.layer} | ${failure.testFile} | ${failure.issue} | ${failure.suggestedFix} |`);
137
+ });
138
+ }
139
+
140
+ if (summary.suggestions.length > 0) {
141
+ console.log('\n### Suggested Next Improvements');
142
+ summary.suggestions.forEach(suggestion => {
143
+ console.log(`- ${suggestion}`);
144
+ });
145
+ }
146
+
147
+ console.log(`\n### Gate Status`);
148
+ console.log(`OVERALL: ${summary.overallStatus} ${summary.overallStatus === 'PASS' ? '✅' : '❌'}`);
149
+ if (summary.overallStatus === 'FAIL') {
150
+ console.log(`Blockers: ${summary.keyFailures.map(f => f.layer).join(', ')}`);
151
+ }
152
+ }
153
+ }
154
+
155
+ describe('QA Test Automation Integration', () => {
156
+ let reporter: QAReporter;
157
+
158
+ beforeEach(() => {
159
+ reporter = new QAReporter();
160
+ });
161
+
162
+ describe('Test Layer Validation', () => {
163
+ it('should validate lint layer requirements', () => {
164
+ const startTime = Date.now();
165
+ let issues = 0;
166
+
167
+ // Mock lint validation
168
+ try {
169
+ // Simulate ESLint checks
170
+ const mockLintResults = {
171
+ errorCount: 0,
172
+ warningCount: 2,
173
+ fixableErrorCount: 0,
174
+ fixableWarningCount: 1
175
+ };
176
+
177
+ issues = mockLintResults.errorCount;
178
+
179
+ reporter.addLayerResult({
180
+ layer: 'Lint',
181
+ status: mockLintResults.errorCount === 0 ? 'PASS' : 'FAIL',
182
+ duration: Date.now() - startTime,
183
+ issues,
184
+ details: mockLintResults.warningCount > 0 ? `${mockLintResults.warningCount} warnings found` : undefined
185
+ });
186
+
187
+ expect(mockLintResults.errorCount).toBe(0);
188
+ } catch (error) {
189
+ reporter.addLayerResult({
190
+ layer: 'Lint',
191
+ status: 'FAIL',
192
+ duration: Date.now() - startTime,
193
+ issues: 1,
194
+ details: 'Lint process failed'
195
+ });
196
+ throw error;
197
+ }
198
+ });
199
+
200
+ it('should validate type safety layer', () => {
201
+ const startTime = Date.now();
202
+ let issues = 0;
203
+
204
+ try {
205
+ // Mock TypeScript compilation
206
+ const mockTypeCheckResults = {
207
+ errors: [],
208
+ warnings: []
209
+ };
210
+
211
+ issues = mockTypeCheckResults.errors.length;
212
+
213
+ reporter.addLayerResult({
214
+ layer: 'Types',
215
+ status: issues === 0 ? 'PASS' : 'FAIL',
216
+ duration: Date.now() - startTime,
217
+ issues
218
+ });
219
+
220
+ expect(mockTypeCheckResults.errors).toHaveLength(0);
221
+ } catch (error) {
222
+ reporter.addLayerResult({
223
+ layer: 'Types',
224
+ status: 'FAIL',
225
+ duration: Date.now() - startTime,
226
+ issues: 1,
227
+ details: 'Type checking failed'
228
+ });
229
+ throw error;
230
+ }
231
+ });
232
+
233
+ it('should validate unit test layer', () => {
234
+ const startTime = Date.now();
235
+
236
+ // Test core serialization functionality
237
+ ComponentTransformer.clearRegistry();
238
+
239
+ const mockComponent = {
240
+ fromJson: (data: any) => ({ type: 'div', props: { children: data.text } }),
241
+ prototype: { toJson: () => ({ text: 'test' }) }
242
+ };
243
+
244
+ ComponentTransformer.registerComponent('MockComponent', mockComponent as any);
245
+
246
+ const testData = {
247
+ tag: 'MockComponent',
248
+ version: '1.0.0',
249
+ data: { text: 'Unit test' }
250
+ };
251
+
252
+ let issues = 0;
253
+ try {
254
+ const result = ComponentTransformer.deserialize(testData);
255
+ expect(result).toBeDefined();
256
+
257
+ reporter.addLayerResult({
258
+ layer: 'Unit',
259
+ status: 'PASS',
260
+ duration: Date.now() - startTime,
261
+ issues
262
+ });
263
+ } catch (error) {
264
+ issues = 1;
265
+ reporter.addLayerResult({
266
+ layer: 'Unit',
267
+ status: 'FAIL',
268
+ duration: Date.now() - startTime,
269
+ issues,
270
+ details: 'Core serialization unit test failed'
271
+ });
272
+ throw error;
273
+ }
274
+ });
275
+
276
+ it('should validate integration test layer', () => {
277
+ const startTime = Date.now();
278
+ let issues = 0;
279
+
280
+ try {
281
+ // Mock integration test results
282
+ const integrationResults = {
283
+ passed: 8,
284
+ failed: 0,
285
+ total: 8
286
+ };
287
+
288
+ issues = integrationResults.failed;
289
+
290
+ reporter.addLayerResult({
291
+ layer: 'Integration',
292
+ status: issues === 0 ? 'PASS' : 'FAIL',
293
+ duration: Date.now() - startTime,
294
+ issues,
295
+ details: `${integrationResults.passed}/${integrationResults.total} tests passed`
296
+ });
297
+
298
+ expect(integrationResults.failed).toBe(0);
299
+ } catch (error) {
300
+ reporter.addLayerResult({
301
+ layer: 'Integration',
302
+ status: 'FAIL',
303
+ duration: Date.now() - startTime,
304
+ issues: 1,
305
+ details: 'Integration tests failed'
306
+ });
307
+ throw error;
308
+ }
309
+ });
310
+
311
+ it('should validate performance test layer', () => {
312
+ const startTime = Date.now();
313
+ let issues = 0;
314
+
315
+ try {
316
+ // Mock performance benchmarks
317
+ const performanceResults = {
318
+ serializationTime: 25, // ms for 1000 components
319
+ deserializationTime: 45, // ms for 1000 components
320
+ memoryUsage: 15 // MB
321
+ };
322
+
323
+ // Performance thresholds
324
+ const thresholds = {
325
+ maxSerializationTime: 50,
326
+ maxDeserializationTime: 100,
327
+ maxMemoryUsage: 50
328
+ };
329
+
330
+ if (performanceResults.serializationTime > thresholds.maxSerializationTime) issues++;
331
+ if (performanceResults.deserializationTime > thresholds.maxDeserializationTime) issues++;
332
+ if (performanceResults.memoryUsage > thresholds.maxMemoryUsage) issues++;
333
+
334
+ reporter.addLayerResult({
335
+ layer: 'Performance',
336
+ status: issues === 0 ? 'PASS' : 'FAIL',
337
+ duration: Date.now() - startTime,
338
+ issues,
339
+ details: issues > 0 ? 'Performance thresholds exceeded' : 'All benchmarks within limits'
340
+ });
341
+
342
+ expect(issues).toBe(0);
343
+ } catch (error) {
344
+ reporter.addLayerResult({
345
+ layer: 'Performance',
346
+ status: 'FAIL',
347
+ duration: Date.now() - startTime,
348
+ issues: 1,
349
+ details: 'Performance tests failed'
350
+ });
351
+ throw error;
352
+ }
353
+ });
354
+
355
+ it('should validate error handling layer', () => {
356
+ const startTime = Date.now();
357
+ let issues = 0;
358
+
359
+ try {
360
+ // Test error handling scenarios
361
+ ComponentTransformer.clearRegistry();
362
+
363
+ const invalidScenarios = [
364
+ { tag: 'UnknownComponent', version: '1.0.0', data: {} },
365
+ { tag: 'ValidComponent', version: '1.0.0' }, // Missing data
366
+ ];
367
+
368
+ let handledErrors = 0;
369
+ invalidScenarios.forEach(scenario => {
370
+ try {
371
+ ComponentTransformer.deserialize(scenario);
372
+ } catch (error) {
373
+ handledErrors++;
374
+ expect((error as Error).message).toContain('Unknown component');
375
+ }
376
+ });
377
+
378
+ if (handledErrors !== invalidScenarios.length) {
379
+ issues = 1;
380
+ }
381
+
382
+ reporter.addLayerResult({
383
+ layer: 'Error Handling',
384
+ status: issues === 0 ? 'PASS' : 'FAIL',
385
+ duration: Date.now() - startTime,
386
+ issues,
387
+ details: `${handledErrors}/${invalidScenarios.length} error scenarios handled correctly`
388
+ });
389
+
390
+ expect(handledErrors).toBe(invalidScenarios.length);
391
+ } catch (error) {
392
+ reporter.addLayerResult({
393
+ layer: 'Error Handling',
394
+ status: 'FAIL',
395
+ duration: Date.now() - startTime,
396
+ issues: 1,
397
+ details: 'Error handling validation failed'
398
+ });
399
+ throw error;
400
+ }
401
+ });
402
+ });
403
+
404
+ describe('Coverage Enforcement', () => {
405
+ it('should enforce minimum coverage thresholds', () => {
406
+ const mockCoverage = {
407
+ lines: { pct: 87 },
408
+ functions: { pct: 92 },
409
+ branches: { pct: 81 },
410
+ statements: { pct: 89 }
411
+ };
412
+
413
+ const thresholds = {
414
+ lines: 80,
415
+ functions: 80,
416
+ branches: 75,
417
+ statements: 80
418
+ };
419
+
420
+ expect(mockCoverage.lines.pct).toBeGreaterThanOrEqual(thresholds.lines);
421
+ expect(mockCoverage.functions.pct).toBeGreaterThanOrEqual(thresholds.functions);
422
+ expect(mockCoverage.branches.pct).toBeGreaterThanOrEqual(thresholds.branches);
423
+ expect(mockCoverage.statements.pct).toBeGreaterThanOrEqual(thresholds.statements);
424
+ });
425
+
426
+ it('should identify uncovered critical paths', () => {
427
+ const uncoveredPaths = [
428
+ // Mock uncovered paths that would come from coverage analysis
429
+ 'ComponentTransformer.serializeNode - error handling branch',
430
+ 'ComponentTransformer.deserialize - malformed JSON recovery'
431
+ ];
432
+
433
+ // In real implementation, this would parse coverage reports
434
+ expect(uncoveredPaths.length).toBeLessThan(5); // Allow some uncovered paths
435
+
436
+ if (uncoveredPaths.length > 0) {
437
+ console.log('Uncovered critical paths:', uncoveredPaths);
438
+ }
439
+ });
440
+ });
441
+
442
+ describe('Quality Gate Validation', () => {
443
+ it('should validate all quality gates before deployment', () => {
444
+ const qualityGates = [
445
+ { name: 'Zero lint errors', passed: true },
446
+ { name: 'Type safety', passed: true },
447
+ { name: 'All tests passing', passed: true },
448
+ { name: 'Coverage threshold met', passed: true },
449
+ { name: 'Performance benchmarks met', passed: true },
450
+ { name: 'Security scan clean', passed: true },
451
+ { name: 'No known vulnerabilities', passed: true }
452
+ ];
453
+
454
+ const failedGates = qualityGates.filter(gate => !gate.passed);
455
+
456
+ expect(failedGates).toHaveLength(0);
457
+
458
+ if (failedGates.length > 0) {
459
+ console.log('Failed quality gates:', failedGates.map(g => g.name).join(', '));
460
+ }
461
+ });
462
+
463
+ it('should generate comprehensive QA report', () => {
464
+ // Add some mock results for demonstration
465
+ reporter.addLayerResult({
466
+ layer: 'Lint',
467
+ status: 'PASS',
468
+ duration: 150,
469
+ issues: 0
470
+ });
471
+
472
+ reporter.addLayerResult({
473
+ layer: 'Types',
474
+ status: 'PASS',
475
+ duration: 500,
476
+ issues: 0
477
+ });
478
+
479
+ reporter.addLayerResult({
480
+ layer: 'Unit',
481
+ status: 'PASS',
482
+ duration: 2500,
483
+ issues: 0
484
+ });
485
+
486
+ reporter.addLayerResult({
487
+ layer: 'Integration',
488
+ status: 'PASS',
489
+ duration: 5000,
490
+ issues: 0
491
+ });
492
+
493
+ reporter.addLayerResult({
494
+ layer: 'Performance',
495
+ status: 'PASS',
496
+ duration: 3000,
497
+ issues: 0
498
+ });
499
+
500
+ const summary = reporter.generateSummary();
501
+ expect(summary.overallStatus).toBe('PASS');
502
+ expect(summary.layers).toHaveLength(5);
503
+ expect(summary.keyFailures).toHaveLength(0);
504
+
505
+ // Print the summary for CI/CD integration
506
+ reporter.printSummary(summary);
507
+ });
508
+ });
509
+
510
+ describe('CI/CD Pipeline Integration', () => {
511
+ it('should provide structured output for CI systems', () => {
512
+ const summary = reporter.generateSummary();
513
+
514
+ // Structured output that can be consumed by CI/CD systems
515
+ const ciOutput = {
516
+ success: summary.overallStatus === 'PASS',
517
+ duration: summary.totalDuration,
518
+ coverage: summary.coverage,
519
+ failedTests: summary.keyFailures.length,
520
+ suggestions: summary.suggestions.length
521
+ };
522
+
523
+ expect(ciOutput.success).toBe(true);
524
+ expect(ciOutput.duration).toBeLessThan(30000); // Should complete within 30 seconds
525
+ expect(ciOutput.coverage.lines).toBeGreaterThan(80);
526
+ });
527
+
528
+ it('should support parallel test execution', async () => {
529
+ // Simulate parallel test execution
530
+ const parallelTests = [
531
+ () => new Promise(resolve => setTimeout(() => resolve('lint-passed'), 100)),
532
+ () => new Promise(resolve => setTimeout(() => resolve('type-check-passed'), 200)),
533
+ () => new Promise(resolve => setTimeout(() => resolve('unit-tests-passed'), 1500)),
534
+ () => new Promise(resolve => setTimeout(() => resolve('integration-tests-passed'), 3000))
535
+ ];
536
+
537
+ const startTime = Date.now();
538
+ const results = await Promise.all(parallelTests.map(test => test()));
539
+ const duration = Date.now() - startTime;
540
+
541
+ expect(results).toHaveLength(4);
542
+ expect(duration).toBeLessThan(3500); // Should complete in parallel, not sequential
543
+
544
+ results.forEach(result => {
545
+ expect(result).toContain('passed');
546
+ });
547
+ });
548
+ });
549
+
550
+ describe('Test Data Management', () => {
551
+ it('should provide standardized test data for consistent testing', () => {
552
+ const standardTestData = {
553
+ simpleButton: {
554
+ tag: 'Button',
555
+ version: '1.0.0',
556
+ data: { label: 'Click Me', variant: 'primary' }
557
+ },
558
+ complexCard: {
559
+ tag: 'Card',
560
+ version: '1.0.0',
561
+ data: {
562
+ title: 'Test Card',
563
+ content: 'Card content',
564
+ image: { src: 'test.jpg', alt: 'Test image' },
565
+ metadata: { author: 'Tester', date: '2025-01-01' },
566
+ actions: [
567
+ {
568
+ tag: 'Button',
569
+ version: '1.0.0',
570
+ data: { label: 'Action', variant: 'secondary' }
571
+ }
572
+ ]
573
+ }
574
+ },
575
+ largeDataset: Array.from({ length: 1000 }, (_, i) => ({
576
+ tag: 'ListItem',
577
+ version: '1.0.0',
578
+ data: { id: i, text: `Item ${i}` }
579
+ }))
580
+ };
581
+
582
+ // Validate test data structure
583
+ expect(standardTestData.simpleButton.tag).toBe('Button');
584
+ expect(standardTestData.complexCard.data.actions).toHaveLength(1);
585
+ expect(standardTestData.largeDataset).toHaveLength(1000);
586
+
587
+ // Test data should be deterministic
588
+ const regeneratedData = Array.from({ length: 1000 }, (_, i) => ({
589
+ tag: 'ListItem',
590
+ version: '1.0.0',
591
+ data: { id: i, text: `Item ${i}` }
592
+ }));
593
+
594
+ expect(regeneratedData).toEqual(standardTestData.largeDataset);
595
+ });
596
+ });
597
+ });
@@ -2,7 +2,7 @@
2
2
  * Test for DOM nesting fix in HTML transformation
3
3
  */
4
4
 
5
- import { transformHtmlToReact, defaultMarkdownRules } from '../htmlTransform';
5
+ import { transformHtmlToReact, defaultMarkdownRules } from '../../utils/htmlTransform';
6
6
 
7
7
  describe('DOM nesting fix', () => {
8
8
  it('should fix invalid paragraph nesting with block elements', () => {
@@ -1,6 +1,14 @@
1
1
  import React, { Component, ErrorInfo, ReactNode } from 'react';
2
2
  import { Button } from './buttons/Button';
3
3
 
4
+ declare global {
5
+ interface Window {
6
+ qwickapps?: {
7
+ logError?: (error: Error, errorInfo: ErrorInfo) => void;
8
+ };
9
+ }
10
+ }
11
+
4
12
  interface Props {
5
13
  children: ReactNode;
6
14
  fallback?: ReactNode;
@@ -129,10 +137,6 @@ export class ErrorBoundary extends Component<Props, State> {
129
137
  <Button
130
138
  variant="contained"
131
139
  onClick={this.handleRetry}
132
- style={{
133
- backgroundColor: '#dc2626',
134
- color: 'white'
135
- }}
136
140
  >
137
141
  Try Again
138
142
  </Button>
@@ -140,10 +144,6 @@ export class ErrorBoundary extends Component<Props, State> {
140
144
  <Button
141
145
  variant="outlined"
142
146
  onClick={this.handleRefresh}
143
- style={{
144
- borderColor: '#dc2626',
145
- color: '#dc2626'
146
- }}
147
147
  >
148
148
  Refresh Page
149
149
  </Button>