testeranto 0.167.0 → 0.171.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 (181) hide show
  1. package/dist/common/src/NavBar.js +45 -0
  2. package/dist/common/src/PM/main.js +81 -59
  3. package/dist/common/src/Pure.js +16 -14
  4. package/dist/common/src/ReportServer.js +48 -5
  5. package/dist/common/src/Web.js +35 -20
  6. package/dist/common/src/components/SunriseAnimation.test/implementation.js +1 -0
  7. package/dist/common/src/components/SunriseAnimation.test/index.js +1 -0
  8. package/dist/common/src/components/SunriseAnimation.test/interface.js +1 -0
  9. package/dist/common/src/components/SunriseAnimation.test/specification.js +1 -0
  10. package/dist/common/src/components/TestStatusBadge.js +55 -0
  11. package/dist/common/src/components/pure/ProjectPageView.js +204 -0
  12. package/dist/common/src/components/pure/ProjectPageView.test/adapter.js +20 -0
  13. package/dist/common/src/components/pure/ProjectPageView.test/implementation.js +71 -0
  14. package/dist/common/src/components/pure/ProjectPageView.test/index.js +10 -0
  15. package/dist/common/src/components/pure/ProjectPageView.test/specification.js +19 -0
  16. package/dist/common/src/components/pure/ProjectPageView.test/types.js +2 -0
  17. package/dist/common/src/lib/BaseSuite.js +3 -3
  18. package/dist/common/src/lib/BaseSuite.test/test.js +1 -1
  19. package/dist/common/src/lib/abstractBase.js +41 -14
  20. package/dist/common/src/lib/baseBuilder.test/baseBuilder.test.adapter.js +1 -1
  21. package/dist/common/src/lib/pmProxy.js +185 -64
  22. package/dist/common/testeranto.config.js +6 -0
  23. package/dist/common/tsconfig.common.tsbuildinfo +1 -1
  24. package/dist/module/src/App.js +3 -3
  25. package/dist/module/src/PM/main.js +81 -59
  26. package/dist/module/src/ProjectsPage.js +1 -110
  27. package/dist/module/src/Pure.js +16 -14
  28. package/dist/module/src/ReportServer.js +48 -5
  29. package/dist/module/src/TestPage.js +45 -16
  30. package/dist/module/src/Web.js +35 -20
  31. package/dist/module/src/components/SunriseAnimation.test/implementation.js +1 -0
  32. package/dist/module/src/components/SunriseAnimation.test/index.js +1 -0
  33. package/dist/module/src/components/SunriseAnimation.test/interface.js +1 -0
  34. package/dist/module/src/components/SunriseAnimation.test/specification.js +1 -0
  35. package/dist/module/src/components/pure/ProjectPageView.js +197 -0
  36. package/dist/module/src/components/pure/ProjectPageView.test/adapter.js +17 -0
  37. package/dist/module/src/components/pure/ProjectPageView.test/implementation.js +68 -0
  38. package/dist/module/src/components/pure/ProjectPageView.test/index.js +5 -0
  39. package/dist/module/src/components/pure/ProjectPageView.test/specification.js +15 -0
  40. package/dist/module/src/components/pure/ProjectPageView.test/types.js +1 -0
  41. package/dist/module/src/components/pure/ProjectsPageView.js +58 -0
  42. package/dist/module/src/components/pure/TestPageView.js +136 -0
  43. package/dist/module/src/components/stateful/ProjectPage.js +63 -0
  44. package/dist/module/src/components/stateful/ProjectsPage.js +55 -0
  45. package/dist/module/src/components/stateful/TestPage.js +82 -0
  46. package/dist/module/src/lib/BaseSuite.js +3 -3
  47. package/dist/module/src/lib/BaseSuite.test/test.js +1 -1
  48. package/dist/module/src/lib/abstractBase.js +41 -14
  49. package/dist/module/src/lib/baseBuilder.test/baseBuilder.test.adapter.js +1 -1
  50. package/dist/module/src/lib/pmProxy.js +185 -64
  51. package/dist/module/testeranto.config.js +6 -0
  52. package/dist/module/tsconfig.module.tsbuildinfo +1 -1
  53. package/dist/prebuild/App.js +541 -495
  54. package/dist/prebuild/ReportServer.mjs +44 -4
  55. package/dist/prebuild/run.mjs +67 -39
  56. package/dist/types/src/NavBar.d.ts +19 -0
  57. package/dist/types/src/PM/index.d.ts +3 -1
  58. package/dist/types/src/PM/main.d.ts +0 -4
  59. package/dist/types/src/PM/node.d.ts +2 -2
  60. package/dist/types/src/components/SunriseAnimation.test/interface.d.ts +0 -0
  61. package/dist/types/src/components/SunriseAnimation.test/specification.d.ts +0 -0
  62. package/dist/types/src/components/TestStatusBadge.d.ts +15 -0
  63. package/dist/types/src/components/pure/ProjectPageView.d.ts +14 -0
  64. package/dist/types/src/components/pure/ProjectPageView.test/adapter.d.ts +3 -0
  65. package/dist/types/src/components/pure/ProjectPageView.test/implementation.d.ts +3 -0
  66. package/dist/types/src/components/pure/ProjectPageView.test/index.d.ts +3 -0
  67. package/dist/types/src/components/pure/ProjectPageView.test/specification.d.ts +3 -0
  68. package/dist/types/src/components/pure/ProjectPageView.test/types.d.ts +39 -0
  69. package/dist/types/src/lib/BaseSuite.d.ts +2 -0
  70. package/dist/types/src/lib/abstractBase.d.ts +12 -0
  71. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  72. package/package.json +3 -2
  73. package/src/App.tsx +5 -9
  74. package/src/PM/index.ts +1 -1
  75. package/src/PM/main.ts +87 -82
  76. package/src/PM/node.ts +2 -2
  77. package/src/ProjectsPage.tsx +1 -164
  78. package/src/Pure.ts +16 -16
  79. package/src/ReportServer.ts +49 -6
  80. package/src/TestPage.tsx +78 -5
  81. package/src/Web.ts +35 -35
  82. package/src/components/SunriseAnimation.test/implementation.ts +0 -0
  83. package/src/components/SunriseAnimation.test/index.ts +0 -0
  84. package/src/components/SunriseAnimation.test/interface.ts +0 -0
  85. package/src/components/SunriseAnimation.test/specification.ts +0 -0
  86. package/src/components/pure/ProjectPageView.test/adapter.ts +21 -0
  87. package/src/components/pure/ProjectPageView.test/implementation.tsx +84 -0
  88. package/src/components/pure/ProjectPageView.test/index.ts +8 -0
  89. package/src/components/pure/ProjectPageView.test/specification.ts +31 -0
  90. package/src/components/pure/ProjectPageView.test/types.ts +55 -0
  91. package/src/components/pure/ProjectPageView.tsx +332 -0
  92. package/src/components/pure/ProjectsPageView.tsx +99 -0
  93. package/src/components/pure/TestPageView.tsx +278 -0
  94. package/src/components/stateful/ProjectPage.tsx +83 -0
  95. package/src/components/stateful/ProjectsPage.tsx +73 -0
  96. package/src/components/stateful/TestPage.tsx +107 -0
  97. package/src/lib/BaseSuite.test/test.ts +1 -1
  98. package/src/lib/BaseSuite.ts +9 -4
  99. package/src/lib/abstractBase.ts +45 -14
  100. package/src/lib/baseBuilder.test/baseBuilder.test.adapter.ts +1 -1
  101. package/src/lib/pmProxy.ts +184 -87
  102. package/testeranto/App.js +541 -495
  103. package/testeranto/bundles/node/allTests/{chunk-4ONUZRZ4.mjs → chunk-3EUGBAOM.mjs} +1 -1
  104. package/testeranto/bundles/node/allTests/{chunk-IDCUSTSM.mjs → chunk-E75CSRER.mjs} +246 -115
  105. package/testeranto/bundles/node/allTests/{chunk-NQEP7SN4.mjs → chunk-M6DO7VMB.mjs} +1 -1
  106. package/testeranto/bundles/node/allTests/metafile.json +34 -34
  107. package/testeranto/bundles/node/allTests/src/lib/BaseSuite.test/node.test.mjs +4 -4
  108. package/testeranto/bundles/node/allTests/src/lib/baseBuilder.test/baseBuilder.test.node.mjs +3 -3
  109. package/testeranto/bundles/node/allTests/src/lib/classBuilder.test/classBuilder.test.mjs +3 -3
  110. package/testeranto/bundles/node/allTests/src/lib/core.test/core.test.mjs +2 -17
  111. package/testeranto/bundles/node/allTests/src/lib/pmProxy.test/index.mjs +2 -2
  112. package/testeranto/bundles/pure/allTests/{chunk-5SBJWHSZ.mjs → chunk-KHDVEHF7.mjs} +2 -17
  113. package/testeranto/bundles/pure/allTests/{chunk-4ULDTZFU.mjs → chunk-VMUSFSZM.mjs} +246 -115
  114. package/testeranto/bundles/pure/allTests/metafile.json +57 -27
  115. package/testeranto/bundles/pure/allTests/src/Pure.test.mjs +2 -2
  116. package/testeranto/bundles/pure/allTests/src/lib/BaseSuite.test/pure.test.mjs +3 -3
  117. package/testeranto/bundles/pure/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure.mjs +2 -29
  118. package/testeranto/bundles/web/allTests/chunk-HPYA4YZC.mjs +2283 -0
  119. package/testeranto/bundles/web/allTests/{chunk-TU3MJSSI.mjs → chunk-RLDR6LJN.mjs} +302 -127
  120. package/testeranto/bundles/web/allTests/{chunk-46E6YGGN.mjs → chunk-U7AW26HL.mjs} +292 -142
  121. package/testeranto/bundles/web/allTests/metafile.json +15062 -43
  122. package/testeranto/bundles/web/allTests/src/components/pure/ProjectPageView.test/index.html +19 -0
  123. package/testeranto/bundles/web/allTests/src/components/pure/ProjectPageView.test/index.mjs +37524 -0
  124. package/testeranto/bundles/web/allTests/src/lib/BaseSuite.test/web.test.mjs +20 -2
  125. package/testeranto/bundles/web/allTests/src/lib/baseBuilder.test/baseBuilder.test.web.mjs +26 -2
  126. package/testeranto/reports/allTests/config.json +8 -0
  127. package/testeranto/reports/allTests/src/Pure.test/pure/type_errors.txt +9 -3
  128. package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/bdd_errors.txt +1 -0
  129. package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/lint_errors.txt +13 -0
  130. package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/logs.txt +50 -0
  131. package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/message.txt +2 -0
  132. package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/prompt.txt +17 -0
  133. package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/tests.json +32 -0
  134. package/testeranto/reports/allTests/src/components/pure/ProjectPageView.test/index/web/type_errors.txt +68 -0
  135. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node.test/node/logs.txt +22 -39
  136. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node.test/node/tests.json +6 -3
  137. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node.test/node/type_errors.txt +8 -1
  138. package/testeranto/reports/allTests/src/lib/BaseSuite.test/pure.test/pure/tests.json +6 -3
  139. package/testeranto/reports/allTests/src/lib/BaseSuite.test/pure.test/pure/type_errors.txt +9 -3
  140. package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/logs.txt +66 -55
  141. package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/prompt.txt +2 -2
  142. package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/tests.json +6 -3
  143. package/testeranto/reports/allTests/src/lib/BaseSuite.test/web.test/web/type_errors.txt +10 -5
  144. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/logs.txt +16 -48
  145. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/tests.json +18 -9
  146. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/type_errors.txt +8 -1
  147. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/type_errors.txt +10 -5
  148. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/logs.txt +62 -33
  149. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/prompt.txt +2 -2
  150. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/tests.json +18 -9
  151. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/web/type_errors.txt +10 -5
  152. package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/logs.txt +37 -50
  153. package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/tests.json +36 -18
  154. package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/type_errors.txt +8 -1
  155. package/testeranto/reports/allTests/src/lib/core.test/core.test/node/logs.txt +2 -2
  156. package/testeranto/reports/allTests/src/lib/core.test/core.test/node/type_errors.txt +9 -3
  157. package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/logs.txt +21 -36
  158. package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/tests.json +28 -14
  159. package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/type_errors.txt +8 -1
  160. package/testeranto/reports/allTests/summary.json +15 -8
  161. package/testeranto/reportsweb_build_errors +25 -0
  162. package/testeranto.config.ts +7 -0
  163. package/tsc.log +100 -26
  164. package/dist/tsconfig.tsbuildinfo +0 -1
  165. package/testeranto/bundles/node/allTests/chunk-FFBRDUBH.mjs +0 -677
  166. package/testeranto/bundles/node/allTests/chunk-H2IBV7SY.mjs +0 -113
  167. package/testeranto/bundles/node/allTests/chunk-ZHOULXPN.mjs +0 -252
  168. package/testeranto/bundles/pure/allTests/chunk-CSMXYJ65.mjs +0 -200
  169. package/testeranto/bundles/pure/allTests/chunk-QK4IXLF6.mjs +0 -674
  170. package/testeranto/bundles/web/allTests/src/lib/BaseSuite.test/web.test/manifest.json +0 -1
  171. package/testeranto/bundles/web/allTests/src/lib/baseBuilder.test/baseBuilder.test.web/manifest.json +0 -1
  172. package/testeranto/reports/allTests/src/Pure.test/pure/manifest.json +0 -1
  173. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node.test/node/manifest.json +0 -1
  174. package/testeranto/reports/allTests/src/lib/BaseSuite.test/pure.test/pure/manifest.json +0 -1
  175. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.node/node/manifest.json +0 -1
  176. package/testeranto/reports/allTests/src/lib/baseBuilder.test/baseBuilder.test.pure/pure/manifest.json +0 -1
  177. package/testeranto/reports/allTests/src/lib/classBuilder.test/classBuilder.test/node/manifest.json +0 -1
  178. package/testeranto/reports/allTests/src/lib/core.test/core.test/node/manifest.json +0 -1
  179. package/testeranto/reports/allTests/src/lib/pmProxy.test/index/node/manifest.json +0 -1
  180. /package/{testeranto/reports/allTests/src/Pure.test/pure/logs.txt → dist/types/src/components/SunriseAnimation.test/implementation.d.ts} +0 -0
  181. /package/{testeranto/reports/allTests/src/lib/BaseSuite.test/pure.test/pure/logs.txt → dist/types/src/components/SunriseAnimation.test/index.d.ts} +0 -0
package/testeranto/App.js CHANGED
@@ -2383,9 +2383,9 @@
2383
2383
  if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === "function") {
2384
2384
  __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
2385
2385
  }
2386
- var React87 = require_react();
2386
+ var React91 = require_react();
2387
2387
  var Scheduler = require_scheduler();
2388
- var ReactSharedInternals = React87.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2388
+ var ReactSharedInternals = React91.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2389
2389
  var suppressWarning = false;
2390
2390
  function setSuppressWarning(newSuppressWarning) {
2391
2391
  {
@@ -3990,7 +3990,7 @@
3990
3990
  {
3991
3991
  if (props.value == null) {
3992
3992
  if (typeof props.children === "object" && props.children !== null) {
3993
- React87.Children.forEach(props.children, function(child) {
3993
+ React91.Children.forEach(props.children, function(child) {
3994
3994
  if (child == null) {
3995
3995
  return;
3996
3996
  }
@@ -12437,7 +12437,7 @@
12437
12437
  }
12438
12438
  }
12439
12439
  var fakeInternalInstance = {};
12440
- var emptyRefsObject = new React87.Component().refs;
12440
+ var emptyRefsObject = new React91.Component().refs;
12441
12441
  var didWarnAboutStateAssignmentForComponent;
12442
12442
  var didWarnAboutUninitializedState;
12443
12443
  var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
@@ -23609,7 +23609,7 @@
23609
23609
  if (true) {
23610
23610
  (function() {
23611
23611
  "use strict";
23612
- var React87 = require_react();
23612
+ var React91 = require_react();
23613
23613
  var REACT_ELEMENT_TYPE = Symbol.for("react.element");
23614
23614
  var REACT_PORTAL_TYPE = Symbol.for("react.portal");
23615
23615
  var REACT_FRAGMENT_TYPE = Symbol.for("react.fragment");
@@ -23635,7 +23635,7 @@
23635
23635
  }
23636
23636
  return null;
23637
23637
  }
23638
- var ReactSharedInternals = React87.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
23638
+ var ReactSharedInternals = React91.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
23639
23639
  function error(format) {
23640
23640
  {
23641
23641
  {
@@ -25317,7 +25317,7 @@
25317
25317
  });
25318
25318
 
25319
25319
  // src/App.tsx
25320
- var import_react63 = __toESM(require_react(), 1);
25320
+ var import_react66 = __toESM(require_react(), 1);
25321
25321
  var import_client = __toESM(require_client(), 1);
25322
25322
 
25323
25323
  // node_modules/react-router/dist/development/chunk-EF7DTUVF.mjs
@@ -27681,8 +27681,11 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
27681
27681
  // node_modules/react-router/dist/development/index.mjs
27682
27682
  "use client";
27683
27683
 
27684
- // src/ProjectsPage.tsx
27685
- var import_react57 = __toESM(require_react(), 1);
27684
+ // src/components/stateful/TestPage.tsx
27685
+ var import_react59 = __toESM(require_react(), 1);
27686
+
27687
+ // src/components/pure/TestPageView.tsx
27688
+ var import_react58 = __toESM(require_react(), 1);
27686
27689
 
27687
27690
  // node_modules/@babel/runtime/helpers/esm/extends.js
27688
27691
  function _extends() {
@@ -28616,7 +28619,6 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
28616
28619
  })
28617
28620
  });
28618
28621
  });
28619
- TransitionWrapper.displayName = "TransitionWrapper";
28620
28622
  var TransitionWrapper_default = TransitionWrapper;
28621
28623
 
28622
28624
  // node_modules/react-bootstrap/esm/Collapse.js
@@ -28629,8 +28631,8 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
28629
28631
  const offset = `offset${dimension[0].toUpperCase()}${dimension.slice(1)}`;
28630
28632
  const value = elem[offset];
28631
28633
  const margins = MARGINS[dimension];
28632
- return value + // @ts-expect-error TODO
28633
- parseInt(css_default(elem, margins[0]), 10) + // @ts-expect-error TODO
28634
+ return value + // @ts-ignore
28635
+ parseInt(css_default(elem, margins[0]), 10) + // @ts-ignore
28634
28636
  parseInt(css_default(elem, margins[1]), 10);
28635
28637
  }
28636
28638
  var collapseStyles = {
@@ -28696,7 +28698,6 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
28696
28698
  })
28697
28699
  });
28698
28700
  });
28699
- Collapse.displayName = "Collapse";
28700
28701
  var Collapse_default = Collapse;
28701
28702
 
28702
28703
  // node_modules/react-bootstrap/esm/Alert.js
@@ -28733,14 +28734,11 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
28733
28734
  var React19 = __toESM(require_react());
28734
28735
  var import_classnames2 = __toESM(require_classnames());
28735
28736
  var import_jsx_runtime4 = __toESM(require_jsx_runtime());
28736
- var divWithClassName_default = (className) => (
28737
- // eslint-disable-next-line react/display-name
28738
- /* @__PURE__ */ React19.forwardRef((p, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", {
28739
- ...p,
28740
- ref,
28741
- className: (0, import_classnames2.default)(p.className, className)
28742
- }))
28743
- );
28737
+ var divWithClassName_default = (className) => /* @__PURE__ */ React19.forwardRef((p, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", {
28738
+ ...p,
28739
+ ref,
28740
+ className: (0, import_classnames2.default)(p.className, className)
28741
+ }));
28744
28742
 
28745
28743
  // node_modules/react-bootstrap/esm/AlertHeading.js
28746
28744
  var import_jsx_runtime5 = __toESM(require_jsx_runtime());
@@ -29566,7 +29564,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
29566
29564
  }
29567
29565
  function $b5e257d569688ac6$var$useLegacySSRSafeId(defaultId) {
29568
29566
  let ctx = (0, import_react30.useContext)($b5e257d569688ac6$var$SSRContext);
29569
- if (ctx === $b5e257d569688ac6$var$defaultContext && !$b5e257d569688ac6$var$canUseDOM && true)
29567
+ if (ctx === $b5e257d569688ac6$var$defaultContext && !$b5e257d569688ac6$var$canUseDOM)
29570
29568
  console.warn("When server rendering, you must wrap your application in an <SSRProvider> to ensure consistent ids are generated between the client and server.");
29571
29569
  let counter = $b5e257d569688ac6$var$useCounter(!!defaultId);
29572
29570
  let prefix = ctx === $b5e257d569688ac6$var$defaultContext && false ? "react-aria" : `react-aria${ctx.prefix}`;
@@ -30715,6 +30713,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
30715
30713
  var React53 = __toESM(require_react());
30716
30714
  "use client";
30717
30715
  var ModalContext = /* @__PURE__ */ React53.createContext({
30716
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
30718
30717
  onHide() {
30719
30718
  }
30720
30719
  });
@@ -30806,7 +30805,6 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
30806
30805
  })]
30807
30806
  });
30808
30807
  });
30809
- AbstractModalHeader.displayName = "AbstractModalHeader";
30810
30808
  var AbstractModalHeader_default = AbstractModalHeader;
30811
30809
 
30812
30810
  // node_modules/react-bootstrap/esm/ModalHeader.js
@@ -31740,6 +31738,9 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
31740
31738
  // node_modules/react-bootstrap/esm/Tab.js
31741
31739
  var import_prop_types4 = __toESM(require_prop_types());
31742
31740
 
31741
+ // node_modules/react-bootstrap/esm/TabContainer.js
31742
+ var React76 = __toESM(require_react());
31743
+
31743
31744
  // node_modules/@restart/ui/esm/Tabs.js
31744
31745
  var React75 = __toESM(require_react());
31745
31746
  var import_react55 = __toESM(require_react());
@@ -31922,11 +31923,11 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
31922
31923
  var TabContainer_default = TabContainer;
31923
31924
 
31924
31925
  // node_modules/react-bootstrap/esm/TabContent.js
31925
- var React76 = __toESM(require_react());
31926
+ var React77 = __toESM(require_react());
31926
31927
  var import_classnames41 = __toESM(require_classnames());
31927
31928
  var import_jsx_runtime60 = __toESM(require_jsx_runtime());
31928
31929
  "use client";
31929
- var TabContent = /* @__PURE__ */ React76.forwardRef(({
31930
+ var TabContent = /* @__PURE__ */ React77.forwardRef(({
31930
31931
  className,
31931
31932
  bsPrefix,
31932
31933
  as: Component4 = "div",
@@ -31944,10 +31945,10 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
31944
31945
 
31945
31946
  // node_modules/react-bootstrap/esm/TabPane.js
31946
31947
  var import_classnames42 = __toESM(require_classnames());
31947
- var React77 = __toESM(require_react());
31948
+ var React78 = __toESM(require_react());
31948
31949
  var import_jsx_runtime61 = __toESM(require_jsx_runtime());
31949
31950
  "use client";
31950
- var TabPane = /* @__PURE__ */ React77.forwardRef(({
31951
+ var TabPane = /* @__PURE__ */ React78.forwardRef(({
31951
31952
  bsPrefix,
31952
31953
  transition,
31953
31954
  ...props
@@ -32031,10 +32032,10 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32031
32032
 
32032
32033
  // node_modules/react-bootstrap/esm/Table.js
32033
32034
  var import_classnames43 = __toESM(require_classnames());
32034
- var React78 = __toESM(require_react());
32035
+ var React79 = __toESM(require_react());
32035
32036
  var import_jsx_runtime62 = __toESM(require_jsx_runtime());
32036
32037
  "use client";
32037
- var Table = /* @__PURE__ */ React78.forwardRef(({
32038
+ var Table = /* @__PURE__ */ React79.forwardRef(({
32038
32039
  bsPrefix,
32039
32040
  className,
32040
32041
  striped,
@@ -32065,7 +32066,6 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32065
32066
  }
32066
32067
  return table;
32067
32068
  });
32068
- Table.displayName = "Table";
32069
32069
  var Table_default = Table;
32070
32070
 
32071
32071
  // src/NavBar.tsx
@@ -32124,118 +32124,8 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32124
32124
  })), rightContent && /* @__PURE__ */ import_react56.default.createElement(Nav_default2, null, rightContent))));
32125
32125
  };
32126
32126
 
32127
- // src/ProjectsPage.tsx
32128
- var ProjectsPage = () => {
32129
- const [projects, setProjects] = (0, import_react57.useState)([]);
32130
- const [summaries, setSummaries] = (0, import_react57.useState)({});
32131
- const [loading, setLoading] = (0, import_react57.useState)(true);
32132
- const [error, setError] = (0, import_react57.useState)(null);
32133
- const navigate = useNavigate();
32134
- const [configs, setConfigs] = (0, import_react57.useState)({});
32135
- (0, import_react57.useEffect)(() => {
32136
- const fetchProjects = async () => {
32137
- try {
32138
- const projectsRes = await fetch(`projects.json`);
32139
- const projectNames = await projectsRes.json();
32140
- const projectsData = await Promise.all(
32141
- projectNames.map(async (name) => {
32142
- const [summaryRes, nodeRes, webRes, pureRes, configRes] = await Promise.all([
32143
- fetch(`reports/${name}/summary.json`),
32144
- fetch(`bundles/node/${name}/metafile.json`),
32145
- fetch(`bundles/web/${name}/metafile.json`),
32146
- fetch(`bundles/pure/${name}/metafile.json`),
32147
- fetch(`reports/${name}/config.json`)
32148
- ]);
32149
- const [summary, nodeData, webData, pureData, configData] = await Promise.all([
32150
- summaryRes.json(),
32151
- nodeRes.ok ? nodeRes.json() : { errors: ["Failed to load node build logs"] },
32152
- webRes.ok ? webRes.json() : { errors: ["Failed to load web build logs"] },
32153
- pureRes.ok ? pureRes.json() : { errors: ["Failed to load pure build logs"] },
32154
- configRes.json()
32155
- ]);
32156
- setSummaries((prev) => ({ ...prev, [name]: summary }));
32157
- setConfigs((prev) => ({ ...prev, [name]: configData }));
32158
- return {
32159
- name,
32160
- testCount: Object.keys(summary).length,
32161
- nodeStatus: nodeData.errors?.length ? "failed" : nodeData.warnings?.length ? "warning" : "success",
32162
- webStatus: webData.errors?.length ? "failed" : webData.warnings?.length ? "warning" : "success",
32163
- pureStatus: pureData.errors?.length ? "failed" : pureData.warnings?.length ? "warning" : "success",
32164
- config: Object.keys(configData).length
32165
- };
32166
- })
32167
- );
32168
- setProjects(projectsData);
32169
- } catch (err) {
32170
- setError(err instanceof Error ? err.message : "Unknown error");
32171
- } finally {
32172
- setLoading(false);
32173
- }
32174
- };
32175
- fetchProjects();
32176
- }, []);
32177
- const getStatusIcon = (status) => {
32178
- switch (status) {
32179
- case "success":
32180
- return "\u2705";
32181
- case "failed":
32182
- return "\u274C";
32183
- case "warning":
32184
- return "\u26A0\uFE0F";
32185
- default:
32186
- return "\u2753";
32187
- }
32188
- };
32189
- if (loading)
32190
- return /* @__PURE__ */ import_react57.default.createElement("div", null, "Loading projects...");
32191
- if (error)
32192
- return /* @__PURE__ */ import_react57.default.createElement(Alert_default, { variant: "danger" }, "Error: ", error);
32193
- console.log(configs);
32194
- return /* @__PURE__ */ import_react57.default.createElement("div", { className: "p-3" }, /* @__PURE__ */ import_react57.default.createElement(NavBar, { title: "Testeranto", backLink: null }), /* @__PURE__ */ import_react57.default.createElement(Table_default, { striped: true, bordered: true, hover: true, responsive: true }, /* @__PURE__ */ import_react57.default.createElement("thead", null, /* @__PURE__ */ import_react57.default.createElement("tr", null, /* @__PURE__ */ import_react57.default.createElement("th", null, "Project"), /* @__PURE__ */ import_react57.default.createElement("th", null, "Tests"), /* @__PURE__ */ import_react57.default.createElement("th", null, "Node"), /* @__PURE__ */ import_react57.default.createElement("th", null, "Web"), /* @__PURE__ */ import_react57.default.createElement("th", null, "Pure"))), /* @__PURE__ */ import_react57.default.createElement("tbody", null, projects.map((project) => /* @__PURE__ */ import_react57.default.createElement("tr", { key: project.name }, /* @__PURE__ */ import_react57.default.createElement("td", null, /* @__PURE__ */ import_react57.default.createElement("a", { href: "#", onClick: (e) => {
32195
- e.preventDefault();
32196
- navigate(`/projects/${project.name}`);
32197
- } }, project.name)), /* @__PURE__ */ import_react57.default.createElement("td", null, /* @__PURE__ */ import_react57.default.createElement("div", { style: { maxHeight: "200px", overflowY: "auto" } }, summaries[project.name] ? Object.keys(summaries[project.name]).map((testName2) => {
32198
- const testData = summaries[project.name][testName2];
32199
- const runTime = configs[project.name].tests.find((t) => t[0] === testName2)[1];
32200
- const hasRuntimeErrors = testData.runTimeErrors > 0;
32201
- const hasStaticErrors = testData.typeErrors > 0 || testData.staticErrors > 0;
32202
- return /* @__PURE__ */ import_react57.default.createElement("div", { key: testName2 }, /* @__PURE__ */ import_react57.default.createElement(
32203
- "a",
32204
- {
32205
- href: `#/projects/${project.name}/tests/${encodeURIComponent(testName2)}/${runTime}`
32206
- },
32207
- hasRuntimeErrors ? "\u274C " : hasStaticErrors ? "\u26A0\uFE0F " : "",
32208
- testName2.split("/").pop()
32209
- ));
32210
- }) : /* @__PURE__ */ import_react57.default.createElement("div", null, "Loading tests..."))), /* @__PURE__ */ import_react57.default.createElement("td", null, /* @__PURE__ */ import_react57.default.createElement(
32211
- "a",
32212
- {
32213
- href: `#/projects/${project.name}#node`
32214
- },
32215
- getStatusIcon(project.nodeStatus),
32216
- " Node build logs"
32217
- )), /* @__PURE__ */ import_react57.default.createElement("td", null, /* @__PURE__ */ import_react57.default.createElement(
32218
- "a",
32219
- {
32220
- href: `#/projects/${project.name}#web`
32221
- },
32222
- getStatusIcon(project.webStatus),
32223
- " Web build logs"
32224
- )), /* @__PURE__ */ import_react57.default.createElement("td", null, /* @__PURE__ */ import_react57.default.createElement(
32225
- "a",
32226
- {
32227
- href: `#/projects/${project.name}#pure`
32228
- },
32229
- getStatusIcon(project.pureStatus),
32230
- " Pure build logs"
32231
- )))))));
32232
- };
32233
-
32234
- // src/ProjectPage.tsx
32235
- var import_react59 = __toESM(require_react(), 1);
32236
-
32237
32127
  // src/components/TestStatusBadge.tsx
32238
- var import_react58 = __toESM(require_react(), 1);
32128
+ var import_react57 = __toESM(require_react(), 1);
32239
32129
  var TestStatusBadge = (props) => {
32240
32130
  console.groupCollapsed(`[TestStatusBadge] Rendering for ${props.testName}`);
32241
32131
  console.log("Raw props:", JSON.parse(JSON.stringify(props)));
@@ -32266,7 +32156,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32266
32156
  if (props.variant === "compact") {
32267
32157
  console.log("Rendering compact badge:", bddStatus);
32268
32158
  console.groupEnd();
32269
- return /* @__PURE__ */ import_react58.default.createElement(Badge_default, { bg: bddStatus.variant }, bddStatus.text);
32159
+ return /* @__PURE__ */ import_react57.default.createElement(Badge_default, { bg: bddStatus.variant }, bddStatus.text);
32270
32160
  }
32271
32161
  console.log("Rendering full badge set with:", {
32272
32162
  bddStatus,
@@ -32274,186 +32164,149 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32274
32164
  staticErrors: props.staticErrors
32275
32165
  });
32276
32166
  console.groupEnd();
32277
- return /* @__PURE__ */ import_react58.default.createElement("div", { className: "d-flex gap-2" }, /* @__PURE__ */ import_react58.default.createElement(Badge_default, { bg: bddStatus.variant }, bddStatus.text));
32167
+ return /* @__PURE__ */ import_react57.default.createElement("div", { className: "d-flex gap-2" }, /* @__PURE__ */ import_react57.default.createElement(Badge_default, { bg: bddStatus.variant }, bddStatus.text));
32278
32168
  };
32279
32169
 
32280
- // src/ProjectPage.tsx
32281
- var BuildLogViewer = ({ logs, runtime }) => {
32282
- if (!logs)
32283
- return /* @__PURE__ */ import_react59.default.createElement(Alert_default, { variant: "info" }, "Loading ", runtime.toLowerCase(), " build logs...");
32284
- const hasErrors = logs.errors?.length > 0;
32285
- const hasWarnings = logs.warnings?.length > 0;
32286
- const [activeTab, setActiveTab] = (0, import_react59.useState)("summary");
32287
- return /* @__PURE__ */ import_react59.default.createElement("div", null, /* @__PURE__ */ import_react59.default.createElement(Tab_default.Container, { activeKey: activeTab, onSelect: (k) => setActiveTab(k || "summary") }, /* @__PURE__ */ import_react59.default.createElement(Nav_default2, { variant: "tabs", className: "mb-3" }, /* @__PURE__ */ import_react59.default.createElement(Nav_default2.Item, null, /* @__PURE__ */ import_react59.default.createElement(Nav_default2.Link, { eventKey: "summary" }, "Build Summary")), /* @__PURE__ */ import_react59.default.createElement(Nav_default2.Item, null, /* @__PURE__ */ import_react59.default.createElement(Nav_default2.Link, { eventKey: "warnings" }, hasWarnings ? `\u26A0\uFE0F Warnings (${logs.warnings.length})` : "Warnings")), /* @__PURE__ */ import_react59.default.createElement(Nav_default2.Item, null, /* @__PURE__ */ import_react59.default.createElement(Nav_default2.Link, { eventKey: "errors" }, hasErrors ? `\u274C Errors (${logs.errors.length})` : "Errors"))), /* @__PURE__ */ import_react59.default.createElement(Tab_default.Content, null, /* @__PURE__ */ import_react59.default.createElement(Tab_default.Pane, { eventKey: "summary" }, /* @__PURE__ */ import_react59.default.createElement(Card_default, null, /* @__PURE__ */ import_react59.default.createElement(Card_default.Header, { className: "d-flex justify-content-between align-items-center" }, /* @__PURE__ */ import_react59.default.createElement("h5", null, "Build Summary"), /* @__PURE__ */ import_react59.default.createElement("div", null, hasErrors && /* @__PURE__ */ import_react59.default.createElement(Badge_default, { bg: "danger", className: "me-2" }, logs.errors.length, " Error", logs.errors.length !== 1 ? "s" : ""), hasWarnings && /* @__PURE__ */ import_react59.default.createElement(Badge_default, { bg: "warning", text: "dark" }, logs.warnings.length, " Warning", logs.warnings.length !== 1 ? "s" : ""), !hasErrors && !hasWarnings && /* @__PURE__ */ import_react59.default.createElement("div", { className: "d-flex align-items-center gap-2" }, /* @__PURE__ */ import_react59.default.createElement(Badge_default, { bg: "success" }, "Build Successful"), logs.testsExist && /* @__PURE__ */ import_react59.default.createElement(Badge_default, { bg: "info" }, "tests.json \u2713")))), /* @__PURE__ */ import_react59.default.createElement(Card_default.Body, null, /* @__PURE__ */ import_react59.default.createElement("div", { className: "mb-3" }, /* @__PURE__ */ import_react59.default.createElement("h6", null, "Input Files (", Object.keys(logs.metafile?.inputs || {}).length, ")"), /* @__PURE__ */ import_react59.default.createElement(ListGroup_default, { className: "max-h-200 overflow-auto" }, Object.keys(logs.metafile?.inputs || {}).map((file) => /* @__PURE__ */ import_react59.default.createElement(ListGroup_default.Item, { key: file, className: "py-2" }, /* @__PURE__ */ import_react59.default.createElement("code", null, file), /* @__PURE__ */ import_react59.default.createElement("div", { className: "text-muted small" }, logs.metafile.inputs[file].bytes, " bytes"))))), /* @__PURE__ */ import_react59.default.createElement("div", null, /* @__PURE__ */ import_react59.default.createElement("h6", null, "Output Files (", Object.keys(logs.metafile?.outputs || {}).length, ")"), /* @__PURE__ */ import_react59.default.createElement(ListGroup_default, { className: "max-h-200 overflow-auto" }, Object.keys(logs.metafile?.outputs || {}).map((file) => /* @__PURE__ */ import_react59.default.createElement(ListGroup_default.Item, { key: file, className: "py-2" }, /* @__PURE__ */ import_react59.default.createElement("code", null, file), /* @__PURE__ */ import_react59.default.createElement("div", { className: "text-muted small" }, logs.metafile.outputs[file].bytes, " bytes", logs.metafile.outputs[file].entryPoint && /* @__PURE__ */ import_react59.default.createElement("span", { className: "ms-2 badge bg-info" }, "Entry Point"))))))))), /* @__PURE__ */ import_react59.default.createElement(Tab_default.Pane, { eventKey: "warnings" }, hasWarnings ? /* @__PURE__ */ import_react59.default.createElement(Card_default, { className: "border-warning" }, /* @__PURE__ */ import_react59.default.createElement(Card_default.Header, { className: "bg-warning text-white d-flex justify-content-between align-items-center" }, /* @__PURE__ */ import_react59.default.createElement("span", null, "Build Warnings (", logs.warnings.length, ")"), /* @__PURE__ */ import_react59.default.createElement(Badge_default, { bg: "light", text: "dark" }, (/* @__PURE__ */ new Date()).toLocaleString())), /* @__PURE__ */ import_react59.default.createElement(Card_default.Body, { className: "p-0" }, /* @__PURE__ */ import_react59.default.createElement(ListGroup_default, { variant: "flush" }, logs.warnings.map((warn, i) => /* @__PURE__ */ import_react59.default.createElement(ListGroup_default.Item, { key: i, className: "text-warning" }, /* @__PURE__ */ import_react59.default.createElement("div", { className: "d-flex justify-content-between" }, /* @__PURE__ */ import_react59.default.createElement("strong", null, warn.location?.file || "Unknown file", warn.location?.line && `:${warn.location.line}`), /* @__PURE__ */ import_react59.default.createElement("small", { className: "text-muted" }, warn.pluginName ? `[${warn.pluginName}]` : "")), /* @__PURE__ */ import_react59.default.createElement("div", { className: "mt-1" }, /* @__PURE__ */ import_react59.default.createElement("pre", { className: "mb-0 p-2 bg-light rounded" }, warn.text || warn.message || JSON.stringify(warn))), warn.detail && /* @__PURE__ */ import_react59.default.createElement("div", { className: "mt-1 small text-muted" }, /* @__PURE__ */ import_react59.default.createElement("pre", { className: "mb-0 p-2 bg-light rounded" }, warn.detail))))))) : /* @__PURE__ */ import_react59.default.createElement(Alert_default, { variant: "info" }, "No warnings found")), /* @__PURE__ */ import_react59.default.createElement(Tab_default.Pane, { eventKey: "errors" }, hasErrors ? /* @__PURE__ */ import_react59.default.createElement(Card_default, { className: "border-danger" }, /* @__PURE__ */ import_react59.default.createElement(Card_default.Header, { className: "bg-danger text-white d-flex justify-content-between align-items-center" }, /* @__PURE__ */ import_react59.default.createElement("span", null, "Build Errors (", logs.errors.length, ")"), /* @__PURE__ */ import_react59.default.createElement(Badge_default, { bg: "light", text: "dark" }, (/* @__PURE__ */ new Date()).toLocaleString())), /* @__PURE__ */ import_react59.default.createElement(Card_default.Body, { className: "p-0" }, /* @__PURE__ */ import_react59.default.createElement(ListGroup_default, { variant: "flush" }, logs.errors.map((err, i) => /* @__PURE__ */ import_react59.default.createElement(ListGroup_default.Item, { key: i, className: "text-danger" }, /* @__PURE__ */ import_react59.default.createElement("div", { className: "d-flex justify-content-between" }, /* @__PURE__ */ import_react59.default.createElement("strong", null, err.location?.file || "Unknown file", err.location?.line && `:${err.location.line}`), /* @__PURE__ */ import_react59.default.createElement("small", { className: "text-muted" }, err.pluginName ? `[${err.pluginName}]` : "")), /* @__PURE__ */ import_react59.default.createElement("div", { className: "mt-1" }, /* @__PURE__ */ import_react59.default.createElement("pre", { className: "mb-0 p-2 bg-light rounded" }, err.text || err.message || JSON.stringify(err))), err.detail && /* @__PURE__ */ import_react59.default.createElement("div", { className: "mt-1 small text-muted" }, /* @__PURE__ */ import_react59.default.createElement("pre", { className: "mb-0 p-2 bg-light rounded" }, err.detail))))))) : /* @__PURE__ */ import_react59.default.createElement(Alert_default, { variant: "success" }, /* @__PURE__ */ import_react59.default.createElement("h5", null, "No Errors Found"), /* @__PURE__ */ import_react59.default.createElement("p", { className: "mb-0" }, "The build completed without any errors."))))));
32288
- };
32289
- var ProjectPage = () => {
32290
- const [summary, setSummary] = (0, import_react59.useState)(null);
32291
- const [nodeLogs, setNodeLogs] = (0, import_react59.useState)(null);
32292
- const [webLogs, setWebLogs] = (0, import_react59.useState)(null);
32293
- const [pureLogs, setPureLogs] = (0, import_react59.useState)(null);
32294
- const [config, setConfig] = (0, import_react59.useState)({});
32295
- const [loading, setLoading] = (0, import_react59.useState)(true);
32296
- const [error, setError] = (0, import_react59.useState)(null);
32297
- const [projectName, setProjectName] = (0, import_react59.useState)("");
32298
- const navigate = useNavigate();
32299
- const location = useLocation();
32300
- const [route, setRoute] = (0, import_react59.useState)("tests");
32301
- (0, import_react59.useEffect)(() => {
32302
- const hash = location.hash.replace("#", "");
32303
- if (hash && ["tests", "node", "web", "pure"].includes(hash)) {
32304
- setRoute(hash);
32305
- } else {
32306
- setRoute("tests");
32307
- }
32308
- }, [location.hash]);
32309
- const { projectName: name } = useParams();
32310
- (0, import_react59.useEffect)(() => {
32311
- if (!name)
32312
- return;
32313
- setProjectName(name);
32314
- const hash = window.location.hash.replace("#", "");
32315
- if (hash && ["tests", "node", "web", "pure"].includes(hash)) {
32316
- setRoute(hash);
32317
- }
32318
- const fetchData = async () => {
32319
- try {
32320
- const [summaryRes, nodeRes, webRes, pureRes, configRes] = await Promise.all([
32321
- fetch(`reports/${name}/summary.json`),
32322
- fetch(`bundles/node/${name}/metafile.json`),
32323
- fetch(`bundles/web/${name}/metafile.json`),
32324
- fetch(`bundles/pure/${name}/metafile.json`),
32325
- fetch(`reports/${name}/config.json`)
32326
- ]);
32327
- if (!summaryRes.ok)
32328
- throw new Error("Failed to fetch summary");
32329
- const [summaryData, nodeData, webData, pureData, configData] = await Promise.all([
32330
- summaryRes.json(),
32331
- nodeRes.ok ? nodeRes.json() : { errors: ["Failed to load node build logs"] },
32332
- webRes.ok ? webRes.json() : { errors: ["Failed to load web build logs"] },
32333
- pureRes.ok ? pureRes.json() : { errors: ["Failed to load pure build logs"] },
32334
- configRes.ok ? configRes.json() : { tests: [] }
32335
- ]);
32336
- setSummary(summaryData);
32337
- setNodeLogs(nodeData);
32338
- setWebLogs(webData);
32339
- setPureLogs(pureData);
32340
- setConfig(configData);
32341
- } catch (err) {
32342
- setError(err instanceof Error ? err.message : "Unknown error");
32343
- } finally {
32344
- setLoading(false);
32345
- }
32346
- };
32347
- fetchData();
32348
- }, []);
32349
- if (loading)
32350
- return /* @__PURE__ */ import_react59.default.createElement("div", null, "Loading project data...");
32351
- if (error)
32352
- return /* @__PURE__ */ import_react59.default.createElement(Alert_default, { variant: "danger" }, "Error: ", error);
32353
- if (!summary)
32354
- return /* @__PURE__ */ import_react59.default.createElement(Alert_default, { variant: "warning" }, "No data found for project");
32355
- const testStatuses = Object.entries(summary).map(([testName2, testData]) => {
32356
- console.groupCollapsed(`[ProjectPage] Processing test: ${testName2}`);
32357
- console.log("Raw test data from summary.json:", testData);
32358
- const checkTestsJson = async () => {
32359
- try {
32360
- let runtimeType = "node";
32361
- const testConfig = config.tests?.find((t) => t[0] === testName2);
32362
- if (testConfig) {
32363
- runtimeType = testConfig[1] || runtimeType;
32364
- } else if (testName2.includes(".web.")) {
32365
- runtimeType = "web";
32366
- } else if (testName2.includes(".pure.")) {
32367
- runtimeType = "pure";
32368
- }
32369
- const jsonPath = `reports/${projectName}/${testName2.split(".").slice(0, -1).join(".")}/${runtimeType}/tests.json`;
32370
- const res = await fetch(jsonPath, {
32371
- method: "HEAD"
32372
- });
32373
- return res.ok;
32374
- } catch {
32375
- return false;
32376
- }
32377
- };
32378
- const testsJsonExists = checkTestsJson();
32379
- const status = {
32380
- testName: testName2,
32381
- testsExist: testsJsonExists && testData.testsExist !== false,
32382
- // Ensure boolean
32383
- runTimeErrors: Number(testData.runTimeErrors) || 0,
32384
- // Ensure number
32385
- typeErrors: Number(testData.typeErrors) || 0,
32386
- staticErrors: Number(testData.staticErrors) || 0
32387
- };
32388
- console.log("Normalized status:", status);
32389
- console.log("tests.json exists:", testsJsonExists);
32390
- if (status.runTimeErrors === -1 && status.testsExist) {
32391
- console.warn("Inconsistent state: runTimeErrors=-1 but testsExist=true");
32392
- }
32393
- if (!status.testsExist && status.runTimeErrors > 0) {
32394
- console.warn("Inconsistent state: testsExist=false but runTimeErrors>0");
32395
- }
32396
- console.groupEnd();
32397
- return status;
32398
- });
32399
- return /* @__PURE__ */ import_react59.default.createElement(Container_default, { fluid: true }, /* @__PURE__ */ import_react59.default.createElement(
32170
+ // src/components/pure/TestPageView.tsx
32171
+ var TestPageView = ({
32172
+ route,
32173
+ setRoute,
32174
+ navigate,
32175
+ projectName,
32176
+ testName: testName2,
32177
+ decodedTestPath,
32178
+ runtime,
32179
+ testData,
32180
+ logs,
32181
+ typeErrors,
32182
+ lintErrors,
32183
+ testsExist,
32184
+ errorCounts
32185
+ }) => {
32186
+ return /* @__PURE__ */ import_react58.default.createElement(Container_default, { fluid: true }, /* @__PURE__ */ import_react58.default.createElement(
32400
32187
  NavBar,
32401
32188
  {
32402
- title: projectName,
32403
- backLink: "/",
32189
+ title: decodedTestPath,
32190
+ backLink: `/projects/${projectName}`,
32404
32191
  navItems: [
32405
32192
  {
32406
- to: `#tests`,
32407
- label: testStatuses.some((t) => t.runTimeErrors > 0) ? "\u274C Tests" : testStatuses.some((t) => t.typeErrors > 0 || t.staticErrors > 0) ? "\u26A0\uFE0F Tests" : "\u2705 Tests",
32408
- active: route === "tests",
32409
- className: testStatuses.some((t) => t.runTimeErrors > 0) ? "text-danger fw-bold" : testStatuses.some((t) => t.typeErrors > 0 || t.staticErrors > 0) ? "text-warning fw-bold" : ""
32193
+ label: "",
32194
+ badge: {
32195
+ variant: runtime === "node" ? "primary" : runtime === "web" ? "success" : "info",
32196
+ text: runtime
32197
+ },
32198
+ className: "pe-none d-flex align-items-center gap-2"
32410
32199
  },
32411
32200
  {
32412
- to: `#node`,
32413
- label: nodeLogs?.errors?.length ? "\u274C Node Build" : nodeLogs?.warnings?.length ? "\u26A0\uFE0F Node Build" : "Node Build",
32414
- active: route === "node",
32415
- className: nodeLogs?.errors?.length ? "text-danger fw-bold" : nodeLogs?.warnings?.length ? "text-warning fw-bold" : ""
32201
+ to: `#results`,
32202
+ label: /* @__PURE__ */ import_react58.default.createElement(
32203
+ TestStatusBadge,
32204
+ {
32205
+ testName: decodedTestPath,
32206
+ testsExist,
32207
+ runTimeErrors: errorCounts.runTimeErrors,
32208
+ variant: "compact"
32209
+ }
32210
+ ),
32211
+ className: !testsExist || errorCounts.runTimeErrors > 0 ? "text-danger fw-bold" : "",
32212
+ active: route === "results"
32416
32213
  },
32417
32214
  {
32418
- to: `#web`,
32419
- label: webLogs?.errors?.length ? "\u274C Web Build" : webLogs?.warnings?.length ? "\u26A0\uFE0F Web Build" : "Web Build",
32420
- active: route === "web",
32421
- className: webLogs?.errors?.length ? "text-danger fw-bold" : webLogs?.warnings?.length ? "text-warning fw-bold" : ""
32215
+ to: `#logs`,
32216
+ label: `Runtime logs`,
32217
+ active: route === "logs"
32422
32218
  },
32423
32219
  {
32424
- to: `#pure`,
32425
- label: pureLogs?.errors?.length ? "\u274C Pure Build" : pureLogs?.warnings?.length ? "\u26A0\uFE0F Pure Build" : "Pure Build",
32426
- active: route === "pure",
32427
- className: pureLogs?.errors?.length ? "text-danger fw-bold" : pureLogs?.warnings?.length ? "text-warning fw-bold" : ""
32220
+ to: `#types`,
32221
+ label: errorCounts.typeErrors > 0 ? `tsc (\u274C * ${errorCounts.typeErrors})` : "tsc \u2705 ",
32222
+ active: route === "types"
32223
+ },
32224
+ {
32225
+ to: `#lint`,
32226
+ label: errorCounts.staticErrors > 0 ? `eslint (\u274C *${errorCounts.staticErrors}) ` : "eslint \u2705",
32227
+ active: route === "lint"
32428
32228
  }
32429
- ]
32229
+ ],
32230
+ rightContent: /* @__PURE__ */ import_react58.default.createElement(
32231
+ Button_default2,
32232
+ {
32233
+ variant: "info",
32234
+ onClick: async () => {
32235
+ try {
32236
+ const promptPath = `testeranto/reports/${projectName}/${testName2.split(".").slice(0, -1).join(".")}/${runtime}/prompt.txt`;
32237
+ const messagePath = `testeranto/reports/${projectName}/${testName2.split(".").slice(0, -1).join(".")}/${runtime}/message.txt`;
32238
+ const command = `aider --load ${promptPath} --message-file ${messagePath}`;
32239
+ await navigator.clipboard.writeText(command);
32240
+ alert("Copied aider command to clipboard!");
32241
+ } catch (err) {
32242
+ alert("Failed to copy command to clipboard");
32243
+ console.error("Copy failed:", err);
32244
+ }
32245
+ },
32246
+ className: "ms-2"
32247
+ },
32248
+ "\u{1F916}"
32249
+ )
32430
32250
  }
32431
- ), /* @__PURE__ */ import_react59.default.createElement(Tab_default.Container, { activeKey: route, onSelect: (k) => {
32251
+ ), /* @__PURE__ */ import_react58.default.createElement(Tab_default.Container, { activeKey: route, onSelect: (k) => {
32432
32252
  if (k) {
32433
32253
  setRoute(k);
32434
32254
  navigate(`#${k}`, { replace: true });
32435
32255
  }
32436
- } }, /* @__PURE__ */ import_react59.default.createElement(Tab_default.Content, null, /* @__PURE__ */ import_react59.default.createElement(Tab_default.Pane, { eventKey: "tests" }, /* @__PURE__ */ import_react59.default.createElement(Table_default, { striped: true, bordered: true, hover: true }, /* @__PURE__ */ import_react59.default.createElement("thead", null, /* @__PURE__ */ import_react59.default.createElement("tr", null, /* @__PURE__ */ import_react59.default.createElement("th", null, "Test"), /* @__PURE__ */ import_react59.default.createElement("th", null, "Runtime"), /* @__PURE__ */ import_react59.default.createElement("th", null, "BDD Errors"), /* @__PURE__ */ import_react59.default.createElement("th", null, "Type Errors"), /* @__PURE__ */ import_react59.default.createElement("th", null, "Lint Errors"))), /* @__PURE__ */ import_react59.default.createElement("tbody", null, testStatuses.map((test) => {
32437
- const testConfig = config.tests?.find((t) => t[0] === test.testName);
32438
- const runTime = testConfig?.[1] || "node";
32439
- const hasRuntimeErrors = test.runTimeErrors > 0;
32440
- const hasTypeErrors = test.typeErrors > 0;
32441
- const hasLintErrors = test.staticErrors > 0;
32442
- return /* @__PURE__ */ import_react59.default.createElement("tr", { key: test.testName }, /* @__PURE__ */ import_react59.default.createElement("td", null, /* @__PURE__ */ import_react59.default.createElement("a", { href: `#/projects/${projectName}/tests/${encodeURIComponent(test.testName)}/${runTime}` }, test.testName)), /* @__PURE__ */ import_react59.default.createElement("td", null, /* @__PURE__ */ import_react59.default.createElement(Badge_default, { bg: "secondary", className: "ms-2" }, runTime)), /* @__PURE__ */ import_react59.default.createElement("td", null, /* @__PURE__ */ import_react59.default.createElement(
32443
- TestStatusBadge,
32444
- {
32445
- testName: test.testName,
32446
- testsExist: test.testsExist,
32447
- runTimeErrors: test.runTimeErrors,
32448
- typeErrors: test.typeErrors,
32449
- staticErrors: test.staticErrors
32450
- }
32451
- )), /* @__PURE__ */ import_react59.default.createElement("td", null, /* @__PURE__ */ import_react59.default.createElement("a", { href: `#/projects/${projectName}/tests/${encodeURIComponent(test.testName)}/${runTime}#types` }, test.typeErrors > 0 ? `tsc (\u274C * ${test.typeErrors})` : "tsc \u2705")), /* @__PURE__ */ import_react59.default.createElement("td", null, /* @__PURE__ */ import_react59.default.createElement("a", { href: `#/projects/${projectName}/tests/${encodeURIComponent(test.testName)}/${runTime}#lint` }, test.staticErrors > 0 ? `eslint (\u274C *${test.staticErrors})` : "eslint \u2705")));
32452
- })))), /* @__PURE__ */ import_react59.default.createElement(Tab_default.Pane, { eventKey: "node" }, /* @__PURE__ */ import_react59.default.createElement(BuildLogViewer, { logs: nodeLogs, runtime: "Node" })), /* @__PURE__ */ import_react59.default.createElement(Tab_default.Pane, { eventKey: "web" }, /* @__PURE__ */ import_react59.default.createElement(BuildLogViewer, { logs: webLogs, runtime: "Web" })), /* @__PURE__ */ import_react59.default.createElement(Tab_default.Pane, { eventKey: "pure" }, /* @__PURE__ */ import_react59.default.createElement(BuildLogViewer, { logs: pureLogs, runtime: "Pure" })))));
32453
- };
32454
-
32455
- // src/TestPage.tsx
32456
- var import_react60 = __toESM(require_react(), 1);
32256
+ } }, /* @__PURE__ */ import_react58.default.createElement(Tab_default.Content, { className: "mt-3" }, /* @__PURE__ */ import_react58.default.createElement(Tab_default.Pane, { eventKey: "results" }, !testsExist ? /* @__PURE__ */ import_react58.default.createElement(Alert_default, { variant: "danger", className: "mt-3" }, /* @__PURE__ */ import_react58.default.createElement("h4", null, "Tests did not run to completion"), /* @__PURE__ */ import_react58.default.createElement("p", null, "The test results file (tests.json) was not found or could not be loaded."), /* @__PURE__ */ import_react58.default.createElement("div", { className: "mt-3" }, /* @__PURE__ */ import_react58.default.createElement(
32257
+ Button_default2,
32258
+ {
32259
+ variant: "outline-light",
32260
+ onClick: () => setRoute("logs"),
32261
+ className: "me-2"
32262
+ },
32263
+ "View Runtime Logs"
32264
+ ), /* @__PURE__ */ import_react58.default.createElement(
32265
+ Button_default2,
32266
+ {
32267
+ variant: "outline-light",
32268
+ onClick: () => navigate(`/projects/${projectName}#${runtime}`)
32269
+ },
32270
+ "View Build Logs"
32271
+ ))) : testData ? /* @__PURE__ */ import_react58.default.createElement("div", { className: "test-results" }, testData.givens.map((given, i) => /* @__PURE__ */ import_react58.default.createElement("div", { key: i, className: "mb-4 card" }, /* @__PURE__ */ import_react58.default.createElement("div", { className: "card-header bg-primary text-white" }, /* @__PURE__ */ import_react58.default.createElement("div", { className: "d-flex justify-content-between align-items-center" }, /* @__PURE__ */ import_react58.default.createElement("h4", null, "Given: ", given.name), given.artifacts?.length > 0 && /* @__PURE__ */ import_react58.default.createElement("div", { className: "dropdown" }, /* @__PURE__ */ import_react58.default.createElement(
32272
+ "button",
32273
+ {
32274
+ className: "btn btn-sm btn-light dropdown-toggle",
32275
+ type: "button",
32276
+ "data-bs-toggle": "dropdown"
32277
+ },
32278
+ "Artifacts (",
32279
+ given.artifacts.length,
32280
+ ")"
32281
+ ), /* @__PURE__ */ import_react58.default.createElement("ul", { className: "dropdown-menu dropdown-menu-end" }, given.artifacts.map((artifact, ai) => /* @__PURE__ */ import_react58.default.createElement("li", { key: ai }, /* @__PURE__ */ import_react58.default.createElement(
32282
+ "a",
32283
+ {
32284
+ className: "dropdown-item",
32285
+ href: `/testeranto/reports/${projectName}/${testName2.split(".").slice(0, -1).join(".")}/${runtime}/${artifact}`,
32286
+ target: "_blank",
32287
+ rel: "noopener noreferrer"
32288
+ },
32289
+ artifact.split("/").pop()
32290
+ ))))))), /* @__PURE__ */ import_react58.default.createElement("div", { className: "card-body" }, given.whens.map((when, j) => /* @__PURE__ */ import_react58.default.createElement("div", { key: `w-${j}`, className: `p-3 mb-2 ${when.error ? "bg-danger text-white" : "bg-success text-white"}` }, /* @__PURE__ */ import_react58.default.createElement("div", { className: "d-flex justify-content-between align-items-start" }, /* @__PURE__ */ import_react58.default.createElement("div", null, /* @__PURE__ */ import_react58.default.createElement("strong", null, "When:"), " ", when.name, when.error && /* @__PURE__ */ import_react58.default.createElement("pre", { className: "mt-2" }, when.error)), when.artifacts?.length > 0 && /* @__PURE__ */ import_react58.default.createElement("div", { className: "ms-3" }, /* @__PURE__ */ import_react58.default.createElement("strong", null, "Artifacts:"), /* @__PURE__ */ import_react58.default.createElement("ul", { className: "list-unstyled" }, when.artifacts.map((artifact, ai) => /* @__PURE__ */ import_react58.default.createElement("li", { key: ai }, /* @__PURE__ */ import_react58.default.createElement(
32291
+ "a",
32292
+ {
32293
+ href: `/testeranto/reports/${projectName}/${testName2.split(".").slice(0, -1).join(".")}/${runtime}/${artifact}`,
32294
+ target: "_blank",
32295
+ className: "text-white",
32296
+ rel: "noopener noreferrer"
32297
+ },
32298
+ artifact.split("/").pop()
32299
+ )))))))), given.thens.map((then, k) => /* @__PURE__ */ import_react58.default.createElement("div", { key: `t-${k}`, className: `p-3 mb-2 ${then.error ? "bg-danger text-white" : "bg-success text-white"}` }, /* @__PURE__ */ import_react58.default.createElement("div", { className: "d-flex justify-content-between align-items-start" }, /* @__PURE__ */ import_react58.default.createElement("div", null, /* @__PURE__ */ import_react58.default.createElement("strong", null, "Then:"), " ", then.name, then.error && /* @__PURE__ */ import_react58.default.createElement("pre", { className: "mt-2" }, then.error)), then.artifacts?.length > 0 && /* @__PURE__ */ import_react58.default.createElement("div", { className: "ms-3" }, /* @__PURE__ */ import_react58.default.createElement("strong", null, "Artifacts:"), /* @__PURE__ */ import_react58.default.createElement("ul", { className: "list-unstyled" }, then.artifacts.map((artifact, ai) => /* @__PURE__ */ import_react58.default.createElement("li", { key: ai }, /* @__PURE__ */ import_react58.default.createElement(
32300
+ "a",
32301
+ {
32302
+ href: `/testeranto/reports/${projectName}/${testName2.split(".").slice(0, -1).join(".")}/${runtime}/${artifact}`,
32303
+ target: "_blank",
32304
+ className: "text-white",
32305
+ rel: "noopener noreferrer"
32306
+ },
32307
+ artifact.split("/").pop()
32308
+ )))))))))))) : /* @__PURE__ */ import_react58.default.createElement(Alert_default, { variant: "warning" }, "No test results found")), /* @__PURE__ */ import_react58.default.createElement(Tab_default.Pane, { eventKey: "logs" }, logs === void 0 ? /* @__PURE__ */ import_react58.default.createElement(Alert_default, { variant: "danger" }, /* @__PURE__ */ import_react58.default.createElement("h4", null, "Logs file missing"), /* @__PURE__ */ import_react58.default.createElement("p", null, "The runtime logs file (logs.txt) was not found."), /* @__PURE__ */ import_react58.default.createElement("p", null, "This suggests the test may not have executed properly.")) : logs === "" ? /* @__PURE__ */ import_react58.default.createElement(Alert_default, { variant: "success" }, /* @__PURE__ */ import_react58.default.createElement("h4", null, "No runtime logs"), /* @__PURE__ */ import_react58.default.createElement("p", null, "The test executed successfully with no log output.")) : /* @__PURE__ */ import_react58.default.createElement("pre", { className: "bg-dark text-white p-3" }, logs)), /* @__PURE__ */ import_react58.default.createElement(Tab_default.Pane, { eventKey: "types" }, typeErrors ? /* @__PURE__ */ import_react58.default.createElement("pre", { className: "bg-dark text-white p-3" }, typeErrors) : /* @__PURE__ */ import_react58.default.createElement(Alert_default, { variant: "warning" }, "No type errors found")), /* @__PURE__ */ import_react58.default.createElement(Tab_default.Pane, { eventKey: "lint" }, lintErrors ? /* @__PURE__ */ import_react58.default.createElement("pre", { className: "bg-dark text-white p-3" }, lintErrors) : /* @__PURE__ */ import_react58.default.createElement(Alert_default, { variant: "warning" }, "No lint errors found")), /* @__PURE__ */ import_react58.default.createElement(Tab_default.Pane, { eventKey: "coverage" }, /* @__PURE__ */ import_react58.default.createElement("div", { className: "coverage-report" }, /* @__PURE__ */ import_react58.default.createElement(Alert_default, { variant: "info" }, "Coverage reports coming soon!"), /* @__PURE__ */ import_react58.default.createElement("div", { className: "coverage-stats" }, /* @__PURE__ */ import_react58.default.createElement("div", { className: "stat-card bg-success text-white" }, /* @__PURE__ */ import_react58.default.createElement("h4", null, "85%"), /* @__PURE__ */ import_react58.default.createElement("p", null, "Lines Covered")), /* @__PURE__ */ import_react58.default.createElement("div", { className: "stat-card bg-warning text-dark" }, /* @__PURE__ */ import_react58.default.createElement("h4", null, "72%"), /* @__PURE__ */ import_react58.default.createElement("p", null, "Branches Covered")), /* @__PURE__ */ import_react58.default.createElement("div", { className: "stat-card bg-info text-white" }, /* @__PURE__ */ import_react58.default.createElement("h4", null, "91%"), /* @__PURE__ */ import_react58.default.createElement("p", null, "Functions Covered"))))))));
32309
+ };
32457
32310
 
32458
32311
  // src/utils/api.ts
32459
32312
  var fetchTestData = async (projectName, filepath, runTime) => {
@@ -32492,12 +32345,12 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32492
32345
  }
32493
32346
  };
32494
32347
 
32495
- // src/TestPage.tsx
32348
+ // src/components/stateful/TestPage.tsx
32496
32349
  var TestPage = () => {
32497
32350
  const navigate = useNavigate();
32498
32351
  const location = useLocation();
32499
- const [route, setRoute] = (0, import_react60.useState)("results");
32500
- (0, import_react60.useEffect)(() => {
32352
+ const [route, setRoute] = (0, import_react59.useState)("results");
32353
+ (0, import_react59.useEffect)(() => {
32501
32354
  const hash = location.hash.replace("#", "");
32502
32355
  if (hash && ["results", "logs", "types", "lint", "coverage"].includes(hash)) {
32503
32356
  setRoute(hash);
@@ -32505,26 +32358,26 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32505
32358
  setRoute("results");
32506
32359
  }
32507
32360
  }, [location.hash]);
32508
- const [testName2, setTestName] = (0, import_react60.useState)("");
32509
- const [testData, setTestData] = (0, import_react60.useState)(null);
32510
- const [logs, setLogs] = (0, import_react60.useState)("");
32511
- const [typeErrors, setTypeErrors] = (0, import_react60.useState)("");
32512
- const [lintErrors, setLintErrors] = (0, import_react60.useState)("");
32513
- const [loading, setLoading] = (0, import_react60.useState)(true);
32514
- const [error, setError] = (0, import_react60.useState)(null);
32515
- const [testsExist, setTestsExist] = (0, import_react60.useState)(true);
32516
- const [errorCounts, setErrorCounts] = (0, import_react60.useState)({
32361
+ const [testName2, setTestName] = (0, import_react59.useState)("");
32362
+ const [testData, setTestData] = (0, import_react59.useState)(null);
32363
+ const [logs, setLogs] = (0, import_react59.useState)("");
32364
+ const [typeErrors, setTypeErrors] = (0, import_react59.useState)("");
32365
+ const [lintErrors, setLintErrors] = (0, import_react59.useState)("");
32366
+ const [loading, setLoading] = (0, import_react59.useState)(true);
32367
+ const [error, setError] = (0, import_react59.useState)(null);
32368
+ const [testsExist, setTestsExist] = (0, import_react59.useState)(true);
32369
+ const [errorCounts, setErrorCounts] = (0, import_react59.useState)({
32517
32370
  typeErrors: 0,
32518
32371
  staticErrors: 0,
32519
32372
  runTimeErrors: 0
32520
32373
  });
32521
- const [summary, setSummary] = (0, import_react60.useState)(null);
32374
+ const [summary, setSummary] = (0, import_react59.useState)(null);
32522
32375
  const { projectName, "*": splat } = useParams();
32523
32376
  const pathParts = splat ? splat.split("/") : [];
32524
32377
  const runtime = pathParts.pop() || "";
32525
32378
  const testPath = pathParts.join("/");
32526
32379
  const decodedTestPath = testPath ? decodeURIComponent(testPath) : "";
32527
- (0, import_react60.useEffect)(() => {
32380
+ (0, import_react59.useEffect)(() => {
32528
32381
  if (!projectName || !testPath || !runtime)
32529
32382
  return;
32530
32383
  setTestName(testPath);
@@ -32542,26 +32395,15 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32542
32395
  throw new Error("Failed to fetch summary");
32543
32396
  const allSummaries = await summaryResponse.json();
32544
32397
  const testSummary = allSummaries[testPath];
32545
- console.log("testSummary", testSummary);
32546
32398
  if (testSummary) {
32547
- console.groupCollapsed(`[TestPage] Processing test summary for ${testPath}`);
32548
- console.log("Raw test summary:", testSummary);
32549
32399
  const counts = {
32550
32400
  typeErrors: Number(testSummary.typeErrors) || 0,
32551
32401
  staticErrors: Number(testSummary.staticErrors) || 0,
32552
32402
  runTimeErrors: Number(testSummary.runTimeErrors) || 0
32553
32403
  };
32554
- console.log("Normalized counts:", counts);
32555
- if (counts.runTimeErrors === -1 && testSummary.testsExist) {
32556
- console.warn("Inconsistent state: runTimeErrors=-1 but testsExist=true");
32557
- }
32558
- if (!testSummary.testsExist && counts.runTimeErrors > 0) {
32559
- console.warn("Inconsistent state: testsExist=false but runTimeErrors>0");
32560
- }
32561
32404
  setSummary(testSummary);
32562
32405
  setErrorCounts(counts);
32563
32406
  setTestsExist(testSummary.testsExist !== false);
32564
- console.groupEnd();
32565
32407
  }
32566
32408
  } catch (err) {
32567
32409
  console.error("Failed to load summary:", err);
@@ -32575,123 +32417,39 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32575
32417
  };
32576
32418
  fetchData();
32577
32419
  }, []);
32578
- if (loading)
32579
- return /* @__PURE__ */ import_react60.default.createElement("div", null, "Loading test data...");
32580
- if (error)
32581
- return /* @__PURE__ */ import_react60.default.createElement(Alert_default, { variant: "danger" }, "Error: ", error);
32582
- console.log("Test status debug:", {
32583
- testName: testName2,
32584
- testsExist,
32585
- testData,
32586
- fails: testData?.fails,
32587
- runTimeErrors: errorCounts.runTimeErrors,
32588
- typeErrors: errorCounts.typeErrors,
32589
- staticErrors: errorCounts.staticErrors
32590
- });
32591
- console.log("Test data:", {
32592
- testData,
32593
- testsExist,
32594
- errorCounts,
32595
- summary
32596
- });
32597
- return /* @__PURE__ */ import_react60.default.createElement(Container_default, { fluid: true }, /* @__PURE__ */ import_react60.default.createElement(
32598
- NavBar,
32420
+ return /* @__PURE__ */ import_react59.default.createElement(
32421
+ TestPageView,
32599
32422
  {
32600
- title: decodedTestPath,
32601
- backLink: `/projects/${projectName}`,
32602
- navItems: [
32603
- {
32604
- label: "",
32605
- badge: {
32606
- variant: runtime === "node" ? "primary" : runtime === "web" ? "success" : "info",
32607
- text: runtime
32608
- },
32609
- className: "pe-none d-flex align-items-center gap-2"
32610
- },
32611
- {
32612
- to: `#results`,
32613
- label: /* @__PURE__ */ import_react60.default.createElement(
32614
- TestStatusBadge,
32615
- {
32616
- testName: decodedTestPath,
32617
- testsExist,
32618
- runTimeErrors: errorCounts.runTimeErrors,
32619
- variant: "compact"
32620
- }
32621
- ),
32622
- className: !testsExist || errorCounts.runTimeErrors > 0 ? "text-danger fw-bold" : "",
32623
- active: route === "results"
32624
- },
32625
- {
32626
- to: `#logs`,
32627
- label: `Runtime logs`,
32628
- active: route === "logs"
32629
- },
32630
- {
32631
- to: `#types`,
32632
- label: errorCounts.typeErrors > 0 ? `tsc (\u274C * ${errorCounts.typeErrors})` : "tsc \u2705 ",
32633
- active: route === "types"
32634
- },
32635
- {
32636
- to: `#lint`,
32637
- label: errorCounts.staticErrors > 0 ? `eslint (\u274C *${errorCounts.staticErrors}) ` : "eslint \u2705",
32638
- active: route === "lint"
32639
- }
32640
- ],
32641
- rightContent: /* @__PURE__ */ import_react60.default.createElement(
32642
- Button_default2,
32643
- {
32644
- variant: "info",
32645
- onClick: async () => {
32646
- try {
32647
- const promptPath = `testeranto/reports/${projectName}/${testPath.split(".").slice(0, -1).join(".")}/${runtime}/prompt.txt`;
32648
- const messagePath = `testeranto/reports/${projectName}/${testPath.split(".").slice(0, -1).join(".")}/${runtime}/message.txt`;
32649
- const command = `aider --load ${promptPath} --message-file ${messagePath}`;
32650
- await navigator.clipboard.writeText(command);
32651
- alert("Copied aider command to clipboard!");
32652
- } catch (err) {
32653
- alert("Failed to copy command to clipboard");
32654
- console.error("Copy failed:", err);
32655
- }
32656
- },
32657
- className: "ms-2"
32658
- },
32659
- "\u{1F916}"
32660
- )
32661
- }
32662
- ), /* @__PURE__ */ import_react60.default.createElement(Tab_default.Container, { activeKey: route, onSelect: (k) => {
32663
- if (k) {
32664
- setRoute(k);
32665
- navigate(`#${k}`, { replace: true });
32423
+ route,
32424
+ setRoute,
32425
+ navigate,
32426
+ projectName,
32427
+ testName: testName2,
32428
+ decodedTestPath,
32429
+ runtime,
32430
+ testData,
32431
+ logs,
32432
+ typeErrors,
32433
+ lintErrors,
32434
+ loading,
32435
+ error,
32436
+ testsExist,
32437
+ errorCounts,
32438
+ summary
32666
32439
  }
32667
- } }, /* @__PURE__ */ import_react60.default.createElement(Tab_default.Content, { className: "mt-3" }, /* @__PURE__ */ import_react60.default.createElement(Tab_default.Pane, { eventKey: "results" }, !testsExist ? /* @__PURE__ */ import_react60.default.createElement(Alert_default, { variant: "danger", className: "mt-3" }, /* @__PURE__ */ import_react60.default.createElement("h4", null, "Tests did not run to completion"), /* @__PURE__ */ import_react60.default.createElement("p", null, "The test results file (tests.json) was not found or could not be loaded."), /* @__PURE__ */ import_react60.default.createElement("div", { className: "mt-3" }, /* @__PURE__ */ import_react60.default.createElement(
32668
- Button_default2,
32669
- {
32670
- variant: "outline-light",
32671
- onClick: () => setRoute("logs"),
32672
- className: "me-2"
32673
- },
32674
- "View Runtime Logs"
32675
- ), /* @__PURE__ */ import_react60.default.createElement(
32676
- Button_default2,
32677
- {
32678
- variant: "outline-light",
32679
- onClick: () => navigate(`/projects/${projectName}#${runtime}`)
32680
- },
32681
- "View Build Logs"
32682
- ))) : testData ? /* @__PURE__ */ import_react60.default.createElement("div", { className: "test-results" }, /* @__PURE__ */ import_react60.default.createElement("div", { className: "mb-3" }), testData.givens.map((given, i) => /* @__PURE__ */ import_react60.default.createElement("div", { key: i, className: "mb-4 card" }, /* @__PURE__ */ import_react60.default.createElement("div", { className: "card-header bg-primary text-white" }, /* @__PURE__ */ import_react60.default.createElement("h4", null, "Given: ", given.name)), /* @__PURE__ */ import_react60.default.createElement("div", { className: "card-body" }, given.whens.map((when, j) => /* @__PURE__ */ import_react60.default.createElement("div", { key: `w-${j}`, className: `p-3 mb-2 ${when.error ? "bg-danger text-white" : "bg-success text-white"}` }, /* @__PURE__ */ import_react60.default.createElement("strong", null, "When:"), " ", when.name, when.error && /* @__PURE__ */ import_react60.default.createElement("pre", { className: "mt-2" }, when.error))), given.thens.map((then, k) => /* @__PURE__ */ import_react60.default.createElement("div", { key: `t-${k}`, className: `p-3 mb-2 ${then.error ? "bg-danger text-white" : "bg-success text-white"}` }, /* @__PURE__ */ import_react60.default.createElement("strong", null, "Then:"), " ", then.name, then.error && /* @__PURE__ */ import_react60.default.createElement("pre", { className: "mt-2" }, then.error))))))) : /* @__PURE__ */ import_react60.default.createElement(Alert_default, { variant: "warning" }, "No test results found")), /* @__PURE__ */ import_react60.default.createElement(Tab_default.Pane, { eventKey: "logs" }, logs === void 0 ? /* @__PURE__ */ import_react60.default.createElement(Alert_default, { variant: "danger" }, /* @__PURE__ */ import_react60.default.createElement("h4", null, "Logs file missing"), /* @__PURE__ */ import_react60.default.createElement("p", null, "The runtime logs file (logs.txt) was not found."), /* @__PURE__ */ import_react60.default.createElement("p", null, "This suggests the test may not have executed properly.")) : logs === "" ? /* @__PURE__ */ import_react60.default.createElement(Alert_default, { variant: "success" }, /* @__PURE__ */ import_react60.default.createElement("h4", null, "No runtime logs"), /* @__PURE__ */ import_react60.default.createElement("p", null, "The test executed successfully with no log output.")) : /* @__PURE__ */ import_react60.default.createElement("pre", { className: "bg-dark text-white p-3" }, logs)), /* @__PURE__ */ import_react60.default.createElement(Tab_default.Pane, { eventKey: "types" }, typeErrors ? /* @__PURE__ */ import_react60.default.createElement("pre", { className: "bg-dark text-white p-3" }, typeErrors) : /* @__PURE__ */ import_react60.default.createElement(Alert_default, { variant: "warning" }, "No type errors found")), /* @__PURE__ */ import_react60.default.createElement(Tab_default.Pane, { eventKey: "lint" }, lintErrors ? /* @__PURE__ */ import_react60.default.createElement("pre", { className: "bg-dark text-white p-3" }, lintErrors) : /* @__PURE__ */ import_react60.default.createElement(Alert_default, { variant: "warning" }, "No lint errors found")), /* @__PURE__ */ import_react60.default.createElement(Tab_default.Pane, { eventKey: "coverage" }, /* @__PURE__ */ import_react60.default.createElement("div", { className: "coverage-report" }, /* @__PURE__ */ import_react60.default.createElement(Alert_default, { variant: "info" }, "Coverage reports coming soon!"), /* @__PURE__ */ import_react60.default.createElement("div", { className: "coverage-stats" }, /* @__PURE__ */ import_react60.default.createElement("div", { className: "stat-card bg-success text-white" }, /* @__PURE__ */ import_react60.default.createElement("h4", null, "85%"), /* @__PURE__ */ import_react60.default.createElement("p", null, "Lines Covered")), /* @__PURE__ */ import_react60.default.createElement("div", { className: "stat-card bg-warning text-dark" }, /* @__PURE__ */ import_react60.default.createElement("h4", null, "72%"), /* @__PURE__ */ import_react60.default.createElement("p", null, "Branches Covered")), /* @__PURE__ */ import_react60.default.createElement("div", { className: "stat-card bg-info text-white" }, /* @__PURE__ */ import_react60.default.createElement("h4", null, "91%"), /* @__PURE__ */ import_react60.default.createElement("p", null, "Functions Covered"))))))));
32440
+ );
32683
32441
  };
32684
32442
 
32685
32443
  // src/SettingsButton.tsx
32686
- var import_react62 = __toESM(require_react(), 1);
32444
+ var import_react61 = __toESM(require_react(), 1);
32687
32445
 
32688
32446
  // src/components/SunriseAnimation.tsx
32689
- var import_react61 = __toESM(require_react(), 1);
32447
+ var import_react60 = __toESM(require_react(), 1);
32690
32448
  var SunriseAnimation = ({ active }) => {
32691
- const [position, setPosition] = (0, import_react61.useState)(0);
32692
- const [dimensions, setDimensions] = (0, import_react61.useState)({ width: 0, height: 0 });
32693
- const animationIdRef = (0, import_react61.useRef)(null);
32694
- (0, import_react61.useEffect)(() => {
32449
+ const [position, setPosition] = (0, import_react60.useState)(0);
32450
+ const [dimensions, setDimensions] = (0, import_react60.useState)({ width: 0, height: 0 });
32451
+ const animationIdRef = (0, import_react60.useRef)(null);
32452
+ (0, import_react60.useEffect)(() => {
32695
32453
  setDimensions({
32696
32454
  width: window.innerWidth,
32697
32455
  height: window.innerHeight
@@ -32709,7 +32467,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32709
32467
  }, []);
32710
32468
  const ANIMATION_DURATION = 1e4;
32711
32469
  const UPDATE_INTERVAL = 50;
32712
- (0, import_react61.useEffect)(() => {
32470
+ (0, import_react60.useEffect)(() => {
32713
32471
  if (!active) {
32714
32472
  if (animationIdRef.current) {
32715
32473
  cancelAnimationFrame(animationIdRef.current);
@@ -32744,7 +32502,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32744
32502
  const normalizedPos = (position + 1) / 2;
32745
32503
  if (!active)
32746
32504
  return null;
32747
- return /* @__PURE__ */ import_react61.default.createElement("div", { id: "sunrise", style: {
32505
+ return /* @__PURE__ */ import_react60.default.createElement("div", { id: "sunrise", style: {
32748
32506
  width: "100vw",
32749
32507
  height: "100vh",
32750
32508
  position: "fixed",
@@ -32753,7 +32511,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32753
32511
  backgroundColor: "transparent",
32754
32512
  overflow: "hidden",
32755
32513
  pointerEvents: "none"
32756
- } }, /* @__PURE__ */ import_react61.default.createElement("div", { id: "daily-bg", style: {
32514
+ } }, /* @__PURE__ */ import_react60.default.createElement("div", { id: "daily-bg", style: {
32757
32515
  position: "absolute",
32758
32516
  top: 0,
32759
32517
  left: 0,
@@ -32761,7 +32519,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32761
32519
  height: "100%",
32762
32520
  backgroundColor: "rgba(0,0,0,0.3)",
32763
32521
  zIndex: -1001
32764
- } }), "Stars Container", /* @__PURE__ */ import_react61.default.createElement(
32522
+ } }), "Stars Container", /* @__PURE__ */ import_react60.default.createElement(
32765
32523
  "div",
32766
32524
  {
32767
32525
  id: "starsContainer",
@@ -32778,7 +32536,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32778
32536
  opacity: Math.max(0, 0.5 - normalizedPos * 0.5)
32779
32537
  }
32780
32538
  },
32781
- /* @__PURE__ */ import_react61.default.createElement(
32539
+ /* @__PURE__ */ import_react60.default.createElement(
32782
32540
  "div",
32783
32541
  {
32784
32542
  id: "stars",
@@ -32794,7 +32552,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32794
32552
  }
32795
32553
  }
32796
32554
  )
32797
- ), /* @__PURE__ */ import_react61.default.createElement(
32555
+ ), /* @__PURE__ */ import_react60.default.createElement(
32798
32556
  "div",
32799
32557
  {
32800
32558
  id: "sun",
@@ -32810,7 +32568,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32810
32568
  opacity: 0.5
32811
32569
  }
32812
32570
  }
32813
- ), /* @__PURE__ */ import_react61.default.createElement(
32571
+ ), /* @__PURE__ */ import_react60.default.createElement(
32814
32572
  "div",
32815
32573
  {
32816
32574
  id: "sunDay",
@@ -32825,7 +32583,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32825
32583
  opacity: Math.max(0, 1 - yPos / dimensions.height)
32826
32584
  }
32827
32585
  }
32828
- ), /* @__PURE__ */ import_react61.default.createElement(
32586
+ ), /* @__PURE__ */ import_react60.default.createElement(
32829
32587
  "div",
32830
32588
  {
32831
32589
  id: "sunSet",
@@ -32840,7 +32598,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32840
32598
  opacity: Math.max(0, yPos / dimensions.height - 0.2)
32841
32599
  }
32842
32600
  }
32843
- ), /* @__PURE__ */ import_react61.default.createElement(
32601
+ ), /* @__PURE__ */ import_react60.default.createElement(
32844
32602
  "div",
32845
32603
  {
32846
32604
  id: "sky",
@@ -32855,7 +32613,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32855
32613
  opacity: Math.max(0, 1 - yPos / dimensions.height)
32856
32614
  }
32857
32615
  }
32858
- ), /* @__PURE__ */ import_react61.default.createElement(
32616
+ ), /* @__PURE__ */ import_react60.default.createElement(
32859
32617
  "div",
32860
32618
  {
32861
32619
  id: "horizon",
@@ -32870,7 +32628,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32870
32628
  opacity: Math.max(0, yPos > dimensions.height / 2 ? (dimensions.height - yPos) / (dimensions.height / 2) + 0.2 : yPos / (dimensions.height / 2))
32871
32629
  }
32872
32630
  }
32873
- ), /* @__PURE__ */ import_react61.default.createElement(
32631
+ ), /* @__PURE__ */ import_react60.default.createElement(
32874
32632
  "div",
32875
32633
  {
32876
32634
  id: "horizonNight",
@@ -32885,7 +32643,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32885
32643
  opacity: Math.max(0, (yPos - dimensions.height * 4 / 5) / (dimensions.height - dimensions.height * 4 / 5))
32886
32644
  }
32887
32645
  }
32888
- ), /* @__PURE__ */ import_react61.default.createElement(
32646
+ ), /* @__PURE__ */ import_react60.default.createElement(
32889
32647
  "div",
32890
32648
  {
32891
32649
  id: "moon",
@@ -32900,7 +32658,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32900
32658
  opacity: Math.max(0, (yPos - dimensions.height * 9 / 10) / (dimensions.height - dimensions.height * 9 / 10))
32901
32659
  }
32902
32660
  }
32903
- ), /* @__PURE__ */ import_react61.default.createElement(
32661
+ ), /* @__PURE__ */ import_react60.default.createElement(
32904
32662
  "div",
32905
32663
  {
32906
32664
  id: "water",
@@ -32915,7 +32673,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32915
32673
  zIndex: -400
32916
32674
  }
32917
32675
  }
32918
- ), /* @__PURE__ */ import_react61.default.createElement(
32676
+ ), /* @__PURE__ */ import_react60.default.createElement(
32919
32677
  "div",
32920
32678
  {
32921
32679
  id: "waterReflectionContainer",
@@ -32932,7 +32690,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32932
32690
  transform: `translateY(${dimensions.height - yPos}px)`
32933
32691
  }
32934
32692
  },
32935
- /* @__PURE__ */ import_react61.default.createElement(
32693
+ /* @__PURE__ */ import_react60.default.createElement(
32936
32694
  "div",
32937
32695
  {
32938
32696
  id: "waterReflectionMiddle",
@@ -32949,7 +32707,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32949
32707
  }
32950
32708
  }
32951
32709
  )
32952
- ), /* @__PURE__ */ import_react61.default.createElement(
32710
+ ), /* @__PURE__ */ import_react60.default.createElement(
32953
32711
  "div",
32954
32712
  {
32955
32713
  id: "waterDistance",
@@ -32964,7 +32722,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32964
32722
  opacity: Math.max(0, yPos / dimensions.height + 0.6)
32965
32723
  }
32966
32724
  }
32967
- ), /* @__PURE__ */ import_react61.default.createElement(
32725
+ ), /* @__PURE__ */ import_react60.default.createElement(
32968
32726
  "div",
32969
32727
  {
32970
32728
  id: "darknessOverlaySky",
@@ -32979,7 +32737,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32979
32737
  zIndex: -50
32980
32738
  }
32981
32739
  }
32982
- ), /* @__PURE__ */ import_react61.default.createElement(
32740
+ ), /* @__PURE__ */ import_react60.default.createElement(
32983
32741
  "div",
32984
32742
  {
32985
32743
  id: "darknessOverlay",
@@ -32994,7 +32752,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
32994
32752
  zIndex: -5
32995
32753
  }
32996
32754
  }
32997
- ), /* @__PURE__ */ import_react61.default.createElement(
32755
+ ), /* @__PURE__ */ import_react60.default.createElement(
32998
32756
  "div",
32999
32757
  {
33000
32758
  id: "oceanRipple",
@@ -33015,12 +32773,12 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
33015
32773
 
33016
32774
  // src/SettingsButton.tsx
33017
32775
  var SettingsButton = ({ className }) => {
33018
- (0, import_react62.useEffect)(() => {
32776
+ (0, import_react61.useEffect)(() => {
33019
32777
  return () => {
33020
32778
  };
33021
32779
  }, []);
33022
- const [showModal, setShowModal] = (0, import_react62.useState)(false);
33023
- const [theme, setTheme] = (0, import_react62.useState)(localStorage.getItem("theme") || "system");
32780
+ const [showModal, setShowModal] = (0, import_react61.useState)(false);
32781
+ const [theme, setTheme] = (0, import_react61.useState)(localStorage.getItem("theme") || "system");
33024
32782
  const handleThemeChange = (e) => {
33025
32783
  const newTheme = e.target.value;
33026
32784
  setTheme(newTheme);
@@ -33031,14 +32789,14 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
33031
32789
  }
33032
32790
  document.documentElement.setAttribute("data-bs-theme", themeToApply);
33033
32791
  };
33034
- return /* @__PURE__ */ import_react62.default.createElement(import_react62.default.Fragment, null, /* @__PURE__ */ import_react62.default.createElement("div", { id: "settings-button" }, /* @__PURE__ */ import_react62.default.createElement(
32792
+ return /* @__PURE__ */ import_react61.default.createElement(import_react61.default.Fragment, null, /* @__PURE__ */ import_react61.default.createElement("div", { id: "settings-button" }, /* @__PURE__ */ import_react61.default.createElement(
33035
32793
  "button",
33036
32794
  {
33037
32795
  className: `btn btn-sm btn-outline-secondary ${className}`,
33038
32796
  onClick: () => setShowModal(true)
33039
32797
  },
33040
- /* @__PURE__ */ import_react62.default.createElement("div", { id: "gear-icon-settings" }, "\u2699\uFE0F")
33041
- )), /* @__PURE__ */ import_react62.default.createElement(SunriseAnimation_default, { active: theme === "daily" }), /* @__PURE__ */ import_react62.default.createElement(Modal_default2, { show: showModal, onHide: () => setShowModal(false), size: "lg" }, /* @__PURE__ */ import_react62.default.createElement(Modal_default2.Header, { closeButton: true, className: "border-0" }, /* @__PURE__ */ import_react62.default.createElement(Modal_default2.Title, { className: "d-flex align-items-center" }, /* @__PURE__ */ import_react62.default.createElement("i", { className: "bi bi-palette-fill me-2" }), /* @__PURE__ */ import_react62.default.createElement("span", null, "Settings"))), /* @__PURE__ */ import_react62.default.createElement("div", { className: "alert alert-warning mx-3 mt-2 mb-0" }, /* @__PURE__ */ import_react62.default.createElement("i", { className: "bi bi-exclamation-triangle-fill me-2" }), /* @__PURE__ */ import_react62.default.createElement("strong", null, "Warning:"), ' Themes are an experimental feature. Only "Business casual" is fully supported at this time.'), /* @__PURE__ */ import_react62.default.createElement(Modal_default2.Body, { className: "p-0" }, /* @__PURE__ */ import_react62.default.createElement("div", { className: "p-3" }, /* @__PURE__ */ import_react62.default.createElement("div", { className: "row g-3" }, /* @__PURE__ */ import_react62.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react62.default.createElement(
32798
+ /* @__PURE__ */ import_react61.default.createElement("div", { id: "gear-icon-settings" }, "\u2699\uFE0F")
32799
+ )), /* @__PURE__ */ import_react61.default.createElement(SunriseAnimation_default, { active: theme === "daily" }), /* @__PURE__ */ import_react61.default.createElement(Modal_default2, { show: showModal, onHide: () => setShowModal(false), size: "lg" }, /* @__PURE__ */ import_react61.default.createElement(Modal_default2.Header, { closeButton: true, className: "border-0" }, /* @__PURE__ */ import_react61.default.createElement(Modal_default2.Title, { className: "d-flex align-items-center" }, /* @__PURE__ */ import_react61.default.createElement("i", { className: "bi bi-palette-fill me-2" }), /* @__PURE__ */ import_react61.default.createElement("span", null, "Settings"))), /* @__PURE__ */ import_react61.default.createElement("div", { className: "alert alert-warning mx-3 mt-2 mb-0" }, /* @__PURE__ */ import_react61.default.createElement("i", { className: "bi bi-exclamation-triangle-fill me-2" }), /* @__PURE__ */ import_react61.default.createElement("strong", null, "Warning:"), ' Themes are an experimental feature. Only "Business casual" is fully supported at this time.'), /* @__PURE__ */ import_react61.default.createElement(Modal_default2.Body, { className: "p-0" }, /* @__PURE__ */ import_react61.default.createElement("div", { className: "p-3" }, /* @__PURE__ */ import_react61.default.createElement("div", { className: "row g-3" }, /* @__PURE__ */ import_react61.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react61.default.createElement(
33042
32800
  "div",
33043
32801
  {
33044
32802
  className: `card theme-card ${theme === "system" ? "border-primary" : ""}`,
@@ -33048,8 +32806,8 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
33048
32806
  borderColor: "#adb5bd"
33049
32807
  }
33050
32808
  },
33051
- /* @__PURE__ */ import_react62.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react62.default.createElement("h5", { className: "card-title mb-0" }, "9 to 5"), /* @__PURE__ */ import_react62.default.createElement("p", { className: "small text-muted mb-0" }, "Follows your OS theme"))
33052
- )), /* @__PURE__ */ import_react62.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react62.default.createElement(
32809
+ /* @__PURE__ */ import_react61.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react61.default.createElement("h5", { className: "card-title mb-0" }, "9 to 5"), /* @__PURE__ */ import_react61.default.createElement("p", { className: "small text-muted mb-0" }, "Follows your OS theme"))
32810
+ )), /* @__PURE__ */ import_react61.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react61.default.createElement(
33053
32811
  "div",
33054
32812
  {
33055
32813
  className: `card theme-card ${theme === "light" ? "border-primary" : ""}`,
@@ -33061,8 +32819,8 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
33061
32819
  borderWidth: "2px"
33062
32820
  }
33063
32821
  },
33064
- /* @__PURE__ */ import_react62.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react62.default.createElement("h5", { className: "card-title mb-1" }, "Business casual"), /* @__PURE__ */ import_react62.default.createElement("p", { className: "small text-muted mb-0" }, "Clean & professional"))
33065
- )), /* @__PURE__ */ import_react62.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react62.default.createElement(
32822
+ /* @__PURE__ */ import_react61.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react61.default.createElement("h5", { className: "card-title mb-1" }, "Business casual"), /* @__PURE__ */ import_react61.default.createElement("p", { className: "small text-muted mb-0" }, "Clean & professional"))
32823
+ )), /* @__PURE__ */ import_react61.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react61.default.createElement(
33066
32824
  "div",
33067
32825
  {
33068
32826
  className: `card theme-card ${theme === "dark" ? "border-primary" : ""}`,
@@ -33074,8 +32832,8 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
33074
32832
  borderWidth: "2px"
33075
32833
  }
33076
32834
  },
33077
- /* @__PURE__ */ import_react62.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react62.default.createElement("h5", { className: "card-title mb-1" }, "Business formal"), /* @__PURE__ */ import_react62.default.createElement("p", { className: "small text-muted mb-0" }, "Premium & focused"))
33078
- )), /* @__PURE__ */ import_react62.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react62.default.createElement(
32835
+ /* @__PURE__ */ import_react61.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react61.default.createElement("h5", { className: "card-title mb-1" }, "Business formal"), /* @__PURE__ */ import_react61.default.createElement("p", { className: "small text-muted mb-0" }, "Premium & focused"))
32836
+ )), /* @__PURE__ */ import_react61.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react61.default.createElement(
33079
32837
  "div",
33080
32838
  {
33081
32839
  className: `card theme-card ${theme === "light-vibrant" ? "border-primary" : ""}`,
@@ -33086,8 +32844,8 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
33086
32844
  color: "#fff"
33087
32845
  }
33088
32846
  },
33089
- /* @__PURE__ */ import_react62.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react62.default.createElement("h5", { className: "card-title mb-1" }, "Office Party"), /* @__PURE__ */ import_react62.default.createElement("p", { className: "small text-muted mb-0" }, "Colorful & fun"))
33090
- )), /* @__PURE__ */ import_react62.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react62.default.createElement(
32847
+ /* @__PURE__ */ import_react61.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react61.default.createElement("h5", { className: "card-title mb-1" }, "Office Party"), /* @__PURE__ */ import_react61.default.createElement("p", { className: "small text-muted mb-0" }, "Colorful & fun"))
32848
+ )), /* @__PURE__ */ import_react61.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react61.default.createElement(
33091
32849
  "div",
33092
32850
  {
33093
32851
  className: `card theme-card ${theme === "dark-vibrant" ? "border-primary" : ""}`,
@@ -33098,8 +32856,8 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
33098
32856
  color: "#fff"
33099
32857
  }
33100
32858
  },
33101
- /* @__PURE__ */ import_react62.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react62.default.createElement("h5", { className: "card-title mb-1" }, "After Party"), /* @__PURE__ */ import_react62.default.createElement("p", { className: "small text-muted mb-0" }, "Neon nightlife"))
33102
- )), /* @__PURE__ */ import_react62.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react62.default.createElement(
32859
+ /* @__PURE__ */ import_react61.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react61.default.createElement("h5", { className: "card-title mb-1" }, "After Party"), /* @__PURE__ */ import_react61.default.createElement("p", { className: "small text-muted mb-0" }, "Neon nightlife"))
32860
+ )), /* @__PURE__ */ import_react61.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react61.default.createElement(
33103
32861
  "div",
33104
32862
  {
33105
32863
  className: `card theme-card ${theme === "sepia" ? "border-primary" : ""}`,
@@ -33110,8 +32868,8 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
33110
32868
  color: "#3a3226"
33111
32869
  }
33112
32870
  },
33113
- /* @__PURE__ */ import_react62.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react62.default.createElement("h5", { className: "card-title mb-1" }, "WFH"), /* @__PURE__ */ import_react62.default.createElement("p", { className: "small text-muted mb-0" }, "Vintage warmth"))
33114
- )), /* @__PURE__ */ import_react62.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react62.default.createElement(
32871
+ /* @__PURE__ */ import_react61.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react61.default.createElement("h5", { className: "card-title mb-1" }, "WFH"), /* @__PURE__ */ import_react61.default.createElement("p", { className: "small text-muted mb-0" }, "Vintage warmth"))
32872
+ )), /* @__PURE__ */ import_react61.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react61.default.createElement(
33115
32873
  "div",
33116
32874
  {
33117
32875
  className: `card theme-card ${theme === "light-grayscale" ? "border-primary" : ""}`,
@@ -33123,8 +32881,8 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
33123
32881
  borderWidth: "2px"
33124
32882
  }
33125
32883
  },
33126
- /* @__PURE__ */ import_react62.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react62.default.createElement("h5", { className: "card-title mb-1" }, "Serious Business"), /* @__PURE__ */ import_react62.default.createElement("p", { className: "small text-muted mb-0" }, "Simple & distraction-free"))
33127
- )), /* @__PURE__ */ import_react62.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react62.default.createElement(
32884
+ /* @__PURE__ */ import_react61.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react61.default.createElement("h5", { className: "card-title mb-1" }, "Serious Business"), /* @__PURE__ */ import_react61.default.createElement("p", { className: "small text-muted mb-0" }, "Simple & distraction-free"))
32885
+ )), /* @__PURE__ */ import_react61.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react61.default.createElement(
33128
32886
  "div",
33129
32887
  {
33130
32888
  className: `card theme-card ${theme === "dark-grayscale" ? "border-primary" : ""}`,
@@ -33136,8 +32894,8 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
33136
32894
  borderWidth: "2px"
33137
32895
  }
33138
32896
  },
33139
- /* @__PURE__ */ import_react62.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react62.default.createElement("h5", { className: "card-title mb-1" }, "Very Serious business"), /* @__PURE__ */ import_react62.default.createElement("p", { className: "small text-muted mb-0" }, "Maximum readability"))
33140
- )), /* @__PURE__ */ import_react62.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react62.default.createElement(
32897
+ /* @__PURE__ */ import_react61.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react61.default.createElement("h5", { className: "card-title mb-1" }, "Very Serious business"), /* @__PURE__ */ import_react61.default.createElement("p", { className: "small text-muted mb-0" }, "Maximum readability"))
32898
+ )), /* @__PURE__ */ import_react61.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react61.default.createElement(
33141
32899
  "div",
33142
32900
  {
33143
32901
  className: `card theme-card ${theme === "daily" ? "border-primary" : ""}`,
@@ -33148,8 +32906,8 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
33148
32906
  color: "#00192d"
33149
32907
  }
33150
32908
  },
33151
- /* @__PURE__ */ import_react62.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react62.default.createElement("h5", { className: "card-title mb-1" }, "Dreaming of PTO"), /* @__PURE__ */ import_react62.default.createElement("p", { className: "small text-muted mb-0" }, "Sunrise, sunset"))
33152
- )), /* @__PURE__ */ import_react62.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react62.default.createElement(
32909
+ /* @__PURE__ */ import_react61.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react61.default.createElement("h5", { className: "card-title mb-1" }, "Dreaming of PTO"), /* @__PURE__ */ import_react61.default.createElement("p", { className: "small text-muted mb-0" }, "Sunrise, sunset"))
32910
+ )), /* @__PURE__ */ import_react61.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react61.default.createElement(
33153
32911
  "div",
33154
32912
  {
33155
32913
  className: `card theme-card ${theme === "protanopia" ? "border-primary" : ""}`,
@@ -33160,8 +32918,8 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
33160
32918
  color: "#333"
33161
32919
  }
33162
32920
  },
33163
- /* @__PURE__ */ import_react62.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react62.default.createElement("h5", { className: "card-title mb-0" }, "Protanopia"), /* @__PURE__ */ import_react62.default.createElement("p", { className: "small text-muted mb-0" }, "Red-blind mode"))
33164
- )), /* @__PURE__ */ import_react62.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react62.default.createElement(
32921
+ /* @__PURE__ */ import_react61.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react61.default.createElement("h5", { className: "card-title mb-0" }, "Protanopia"), /* @__PURE__ */ import_react61.default.createElement("p", { className: "small text-muted mb-0" }, "Red-blind mode"))
32922
+ )), /* @__PURE__ */ import_react61.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react61.default.createElement(
33165
32923
  "div",
33166
32924
  {
33167
32925
  className: `card theme-card ${theme === "deuteranopia" ? "border-primary" : ""}`,
@@ -33172,8 +32930,8 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
33172
32930
  color: "#333"
33173
32931
  }
33174
32932
  },
33175
- /* @__PURE__ */ import_react62.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react62.default.createElement("h5", { className: "card-title mb-0" }, "Deuteranopia"), /* @__PURE__ */ import_react62.default.createElement("p", { className: "small text-muted mb-0" }, "Green-blind mode"))
33176
- )), /* @__PURE__ */ import_react62.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react62.default.createElement(
32933
+ /* @__PURE__ */ import_react61.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react61.default.createElement("h5", { className: "card-title mb-0" }, "Deuteranopia"), /* @__PURE__ */ import_react61.default.createElement("p", { className: "small text-muted mb-0" }, "Green-blind mode"))
32934
+ )), /* @__PURE__ */ import_react61.default.createElement("div", { className: "col-md-4" }, /* @__PURE__ */ import_react61.default.createElement(
33177
32935
  "div",
33178
32936
  {
33179
32937
  className: `card theme-card ${theme === "tritanopia" ? "border-primary" : ""}`,
@@ -33184,23 +32942,311 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
33184
32942
  color: "#333"
33185
32943
  }
33186
32944
  },
33187
- /* @__PURE__ */ import_react62.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react62.default.createElement("h5", { className: "card-title mb-0" }, "Tritanopia"), /* @__PURE__ */ import_react62.default.createElement("p", { className: "small text-muted mb-0" }, "Blue-blind mode"))
33188
- ))))), /* @__PURE__ */ import_react62.default.createElement(Modal_default2.Footer, { className: "border-0" }, /* @__PURE__ */ import_react62.default.createElement(Button_default2, { variant: "btn-primary", onClick: () => setShowModal(false) }, "Done"))));
32945
+ /* @__PURE__ */ import_react61.default.createElement("div", { className: "card-body text-center p-3" }, /* @__PURE__ */ import_react61.default.createElement("h5", { className: "card-title mb-0" }, "Tritanopia"), /* @__PURE__ */ import_react61.default.createElement("p", { className: "small text-muted mb-0" }, "Blue-blind mode"))
32946
+ ))))), /* @__PURE__ */ import_react61.default.createElement(Modal_default2.Footer, { className: "border-0" }, /* @__PURE__ */ import_react61.default.createElement(Button_default2, { variant: "btn-primary", onClick: () => setShowModal(false) }, "Done"))));
33189
32947
  };
33190
32948
 
33191
- // src/App.tsx
33192
- var App = () => {
33193
- return /* @__PURE__ */ import_react63.default.createElement(HashRouter, null, /* @__PURE__ */ import_react63.default.createElement("div", { className: "d-flex flex-column min-vh-100", key: window.location.pathname }, /* @__PURE__ */ import_react63.default.createElement("main", { className: "flex-grow-1 p-3" }, /* @__PURE__ */ import_react63.default.createElement(Container_default, { fluid: true }, /* @__PURE__ */ import_react63.default.createElement(Routes, null, /* @__PURE__ */ import_react63.default.createElement(Route, { path: "/", element: /* @__PURE__ */ import_react63.default.createElement(ProjectsPage, null) }), /* @__PURE__ */ import_react63.default.createElement(Route, { path: "/projects/:projectName", element: /* @__PURE__ */ import_react63.default.createElement(ProjectPage, null) }), /* @__PURE__ */ import_react63.default.createElement(
33194
- Route,
32949
+ // src/components/stateful/ProjectPage.tsx
32950
+ var import_react63 = __toESM(require_react(), 1);
32951
+
32952
+ // src/components/pure/ProjectPageView.tsx
32953
+ var import_react62 = __toESM(require_react(), 1);
32954
+ var BuildLogViewer = ({ logs, runtime }) => {
32955
+ if (!logs)
32956
+ return /* @__PURE__ */ import_react62.default.createElement(Alert_default, { variant: "info" }, "Loading ", runtime.toLowerCase(), " build logs...");
32957
+ const hasErrors = logs.errors?.length > 0;
32958
+ const hasWarnings = logs.warnings?.length > 0;
32959
+ const [activeTab, setActiveTab] = import_react62.default.useState("summary");
32960
+ return /* @__PURE__ */ import_react62.default.createElement("div", null, /* @__PURE__ */ import_react62.default.createElement(Tab_default.Container, { activeKey: activeTab, onSelect: (k) => setActiveTab(k || "summary") }, /* @__PURE__ */ import_react62.default.createElement(Nav_default2, { variant: "tabs", className: "mb-3" }, /* @__PURE__ */ import_react62.default.createElement(Nav_default2.Item, null, /* @__PURE__ */ import_react62.default.createElement(Nav_default2.Link, { eventKey: "summary" }, "Build Summary")), /* @__PURE__ */ import_react62.default.createElement(Nav_default2.Item, null, /* @__PURE__ */ import_react62.default.createElement(Nav_default2.Link, { eventKey: "warnings" }, hasWarnings ? `\u26A0\uFE0F Warnings (${logs.warnings.length})` : "Warnings")), /* @__PURE__ */ import_react62.default.createElement(Nav_default2.Item, null, /* @__PURE__ */ import_react62.default.createElement(Nav_default2.Link, { eventKey: "errors" }, hasErrors ? `\u274C Errors (${logs.errors.length})` : "Errors"))), /* @__PURE__ */ import_react62.default.createElement(Tab_default.Content, null, /* @__PURE__ */ import_react62.default.createElement(Tab_default.Pane, { eventKey: "summary" }, /* @__PURE__ */ import_react62.default.createElement(Card_default, null, /* @__PURE__ */ import_react62.default.createElement(Card_default.Header, { className: "d-flex justify-content-between align-items-center" }, /* @__PURE__ */ import_react62.default.createElement("h5", null, "Build Summary"), /* @__PURE__ */ import_react62.default.createElement("div", null, hasErrors && /* @__PURE__ */ import_react62.default.createElement(Badge_default, { bg: "danger", className: "me-2" }, logs.errors.length, " Error", logs.errors.length !== 1 ? "s" : ""), hasWarnings && /* @__PURE__ */ import_react62.default.createElement(Badge_default, { bg: "warning", text: "dark" }, logs.warnings.length, " Warning", logs.warnings.length !== 1 ? "s" : ""), !hasErrors && !hasWarnings && /* @__PURE__ */ import_react62.default.createElement(Badge_default, { bg: "success" }, "Build Successful"))), /* @__PURE__ */ import_react62.default.createElement(Card_default.Body, null, /* @__PURE__ */ import_react62.default.createElement("div", { className: "mb-3" }, /* @__PURE__ */ import_react62.default.createElement("h6", null, "Input Files (", Object.keys(logs.metafile?.inputs || {}).length, ")"), /* @__PURE__ */ import_react62.default.createElement(ListGroup_default, { className: "max-h-200 overflow-auto" }, Object.keys(logs.metafile?.inputs || {}).map((file) => /* @__PURE__ */ import_react62.default.createElement(ListGroup_default.Item, { key: file, className: "py-2" }, /* @__PURE__ */ import_react62.default.createElement("code", null, file), /* @__PURE__ */ import_react62.default.createElement("div", { className: "text-muted small" }, logs.metafile.inputs[file].bytes, " bytes"))))), /* @__PURE__ */ import_react62.default.createElement("div", null, /* @__PURE__ */ import_react62.default.createElement("h6", null, "Output Files (", Object.keys(logs.metafile?.outputs || {}).length, ")"), /* @__PURE__ */ import_react62.default.createElement(ListGroup_default, { className: "max-h-200 overflow-auto" }, Object.keys(logs.metafile?.outputs || {}).map((file) => /* @__PURE__ */ import_react62.default.createElement(ListGroup_default.Item, { key: file, className: "py-2" }, /* @__PURE__ */ import_react62.default.createElement("code", null, file), /* @__PURE__ */ import_react62.default.createElement("div", { className: "text-muted small" }, logs.metafile.outputs[file].bytes, " bytes", logs.metafile.outputs[file].entryPoint && /* @__PURE__ */ import_react62.default.createElement("span", { className: "ms-2 badge bg-info" }, "Entry Point"))))))))), /* @__PURE__ */ import_react62.default.createElement(Tab_default.Pane, { eventKey: "warnings" }, hasWarnings ? /* @__PURE__ */ import_react62.default.createElement(Card_default, { className: "border-warning" }, /* @__PURE__ */ import_react62.default.createElement(Card_default.Header, { className: "bg-warning text-white d-flex justify-content-between align-items-center" }, /* @__PURE__ */ import_react62.default.createElement("span", null, "Build Warnings (", logs.warnings.length, ")"), /* @__PURE__ */ import_react62.default.createElement(Badge_default, { bg: "light", text: "dark" }, (/* @__PURE__ */ new Date()).toLocaleString())), /* @__PURE__ */ import_react62.default.createElement(Card_default.Body, { className: "p-0" }, /* @__PURE__ */ import_react62.default.createElement(ListGroup_default, { variant: "flush" }, logs.warnings.map((warn, i) => /* @__PURE__ */ import_react62.default.createElement(ListGroup_default.Item, { key: i, className: "text-warning" }, /* @__PURE__ */ import_react62.default.createElement("div", { className: "d-flex justify-content-between" }, /* @__PURE__ */ import_react62.default.createElement("strong", null, warn.location?.file || "Unknown file", warn.location?.line && `:${warn.location.line}`), /* @__PURE__ */ import_react62.default.createElement("small", { className: "text-muted" }, warn.pluginName ? `[${warn.pluginName}]` : "")), /* @__PURE__ */ import_react62.default.createElement("div", { className: "mt-1" }, /* @__PURE__ */ import_react62.default.createElement("pre", { className: "mb-0 p-2 bg-light rounded" }, warn.text || warn.message || JSON.stringify(warn))), warn.detail && /* @__PURE__ */ import_react62.default.createElement("div", { className: "mt-1 small text-muted" }, /* @__PURE__ */ import_react62.default.createElement("pre", { className: "mb-0 p-2 bg-light rounded" }, warn.detail))))))) : /* @__PURE__ */ import_react62.default.createElement(Alert_default, { variant: "info" }, "No warnings found")), /* @__PURE__ */ import_react62.default.createElement(Tab_default.Pane, { eventKey: "errors" }, hasErrors ? /* @__PURE__ */ import_react62.default.createElement(Card_default, { className: "border-danger" }, /* @__PURE__ */ import_react62.default.createElement(Card_default.Header, { className: "bg-danger text-white d-flex justify-content-between align-items-center" }, /* @__PURE__ */ import_react62.default.createElement("span", null, "Build Errors (", logs.errors.length, ")"), /* @__PURE__ */ import_react62.default.createElement(Badge_default, { bg: "light", text: "dark" }, (/* @__PURE__ */ new Date()).toLocaleString())), /* @__PURE__ */ import_react62.default.createElement(Card_default.Body, { className: "p-0" }, /* @__PURE__ */ import_react62.default.createElement(ListGroup_default, { variant: "flush" }, logs.errors.map((err, i) => /* @__PURE__ */ import_react62.default.createElement(ListGroup_default.Item, { key: i, className: "text-danger" }, /* @__PURE__ */ import_react62.default.createElement("div", { className: "d-flex justify-content-between" }, /* @__PURE__ */ import_react62.default.createElement("strong", null, err.location?.file || "Unknown file", err.location?.line && `:${err.location.line}`), /* @__PURE__ */ import_react62.default.createElement("small", { className: "text-muted" }, err.pluginName ? `[${err.pluginName}]` : "")), /* @__PURE__ */ import_react62.default.createElement("div", { className: "mt-1" }, /* @__PURE__ */ import_react62.default.createElement("pre", { className: "mb-0 p-2 bg-light rounded" }, err.text || err.message || JSON.stringify(err))), err.detail && /* @__PURE__ */ import_react62.default.createElement("div", { className: "mt-1 small text-muted" }, /* @__PURE__ */ import_react62.default.createElement("pre", { className: "mb-0 p-2 bg-light rounded" }, err.detail))))))) : /* @__PURE__ */ import_react62.default.createElement(Alert_default, { variant: "success" }, /* @__PURE__ */ import_react62.default.createElement("h5", null, "No Errors Found"), /* @__PURE__ */ import_react62.default.createElement("p", { className: "mb-0" }, "The build completed without any errors."))))));
32961
+ };
32962
+ var ProjectPageView = ({
32963
+ summary,
32964
+ nodeLogs,
32965
+ webLogs,
32966
+ pureLogs,
32967
+ config,
32968
+ loading,
32969
+ error,
32970
+ projectName,
32971
+ route,
32972
+ setRoute,
32973
+ navigate
32974
+ }) => {
32975
+ if (loading)
32976
+ return /* @__PURE__ */ import_react62.default.createElement("div", null, "Loading project data...");
32977
+ if (error)
32978
+ return /* @__PURE__ */ import_react62.default.createElement(Alert_default, { variant: "danger" }, "Error: ", error);
32979
+ if (!summary)
32980
+ return /* @__PURE__ */ import_react62.default.createElement(Alert_default, { variant: "warning" }, "No data found for project");
32981
+ const testStatuses = Object.entries(summary).map(([testName2, testData]) => {
32982
+ const runTime = config.tests?.find((t) => t[0] === testName2)?.[1] || "node";
32983
+ return {
32984
+ testName: testName2,
32985
+ testsExist: testData.testsExist !== false,
32986
+ runTimeErrors: Number(testData.runTimeErrors) || 0,
32987
+ typeErrors: Number(testData.typeErrors) || 0,
32988
+ staticErrors: Number(testData.staticErrors) || 0,
32989
+ runTime
32990
+ };
32991
+ });
32992
+ return /* @__PURE__ */ import_react62.default.createElement(Container_default, { fluid: true }, /* @__PURE__ */ import_react62.default.createElement(
32993
+ NavBar,
33195
32994
  {
33196
- path: "/projects/:projectName/tests/*",
33197
- element: /* @__PURE__ */ import_react63.default.createElement(TestPage, null)
32995
+ title: projectName,
32996
+ backLink: "/",
32997
+ navItems: [
32998
+ {
32999
+ to: `#tests`,
33000
+ label: testStatuses.some((t) => t.runTimeErrors > 0) ? "\u274C Tests" : testStatuses.some((t) => t.typeErrors > 0 || t.staticErrors > 0) ? "\u26A0\uFE0F Tests" : "\u2705 Tests",
33001
+ active: route === "tests",
33002
+ className: testStatuses.some((t) => t.runTimeErrors > 0) ? "text-danger fw-bold" : testStatuses.some((t) => t.typeErrors > 0 || t.staticErrors > 0) ? "text-warning fw-bold" : ""
33003
+ },
33004
+ {
33005
+ to: `#node`,
33006
+ label: nodeLogs?.errors?.length ? "\u274C Node Build" : nodeLogs?.warnings?.length ? "\u26A0\uFE0F Node Build" : "Node Build",
33007
+ active: route === "node",
33008
+ className: nodeLogs?.errors?.length ? "text-danger fw-bold" : nodeLogs?.warnings?.length ? "text-warning fw-bold" : ""
33009
+ },
33010
+ {
33011
+ to: `#web`,
33012
+ label: webLogs?.errors?.length ? "\u274C Web Build" : webLogs?.warnings?.length ? "\u26A0\uFE0F Web Build" : "Web Build",
33013
+ active: route === "web",
33014
+ className: webLogs?.errors?.length ? "text-danger fw-bold" : webLogs?.warnings?.length ? "text-warning fw-bold" : ""
33015
+ },
33016
+ {
33017
+ to: `#pure`,
33018
+ label: pureLogs?.errors?.length ? "\u274C Pure Build" : pureLogs?.warnings?.length ? "\u26A0\uFE0F Pure Build" : "Pure Build",
33019
+ active: route === "pure",
33020
+ className: pureLogs?.errors?.length ? "text-danger fw-bold" : pureLogs?.warnings?.length ? "text-warning fw-bold" : ""
33021
+ }
33022
+ ]
33023
+ }
33024
+ ), /* @__PURE__ */ import_react62.default.createElement(Tab_default.Container, { activeKey: route, onSelect: (k) => {
33025
+ if (k) {
33026
+ setRoute(k);
33027
+ navigate(`#${k}`, { replace: true });
33028
+ }
33029
+ } }, /* @__PURE__ */ import_react62.default.createElement(Tab_default.Content, null, /* @__PURE__ */ import_react62.default.createElement(Tab_default.Pane, { eventKey: "tests" }, /* @__PURE__ */ import_react62.default.createElement(Table_default, { striped: true, bordered: true, hover: true }, /* @__PURE__ */ import_react62.default.createElement("thead", null, /* @__PURE__ */ import_react62.default.createElement("tr", null, /* @__PURE__ */ import_react62.default.createElement("th", null, "Test"), /* @__PURE__ */ import_react62.default.createElement("th", null, "Runtime"), /* @__PURE__ */ import_react62.default.createElement("th", null, "Status"), /* @__PURE__ */ import_react62.default.createElement("th", null, "Type Errors"), /* @__PURE__ */ import_react62.default.createElement("th", null, "Lint Errors"))), /* @__PURE__ */ import_react62.default.createElement("tbody", null, testStatuses.map((test) => /* @__PURE__ */ import_react62.default.createElement("tr", { key: test.testName }, /* @__PURE__ */ import_react62.default.createElement("td", null, /* @__PURE__ */ import_react62.default.createElement("a", { href: `#/projects/${projectName}/tests/${encodeURIComponent(test.testName)}/${test.runTime}` }, test.testName)), /* @__PURE__ */ import_react62.default.createElement("td", null, /* @__PURE__ */ import_react62.default.createElement(Badge_default, { bg: "secondary", className: "ms-2" }, test.runTime)), /* @__PURE__ */ import_react62.default.createElement("td", null, /* @__PURE__ */ import_react62.default.createElement(
33030
+ TestStatusBadge,
33031
+ {
33032
+ testName: test.testName,
33033
+ testsExist: test.testsExist,
33034
+ runTimeErrors: test.runTimeErrors
33035
+ }
33036
+ )), /* @__PURE__ */ import_react62.default.createElement("td", null, /* @__PURE__ */ import_react62.default.createElement("a", { href: `#/projects/${projectName}/tests/${encodeURIComponent(test.testName)}/${test.runTime}#types` }, test.typeErrors > 0 ? `\u274C ${test.typeErrors}` : "\u2705")), /* @__PURE__ */ import_react62.default.createElement("td", null, /* @__PURE__ */ import_react62.default.createElement("a", { href: `#/projects/${projectName}/tests/${encodeURIComponent(test.testName)}/${test.runTime}#lint` }, test.staticErrors > 0 ? `\u274C ${test.staticErrors}` : "\u2705"))))))), /* @__PURE__ */ import_react62.default.createElement(Tab_default.Pane, { eventKey: "node" }, /* @__PURE__ */ import_react62.default.createElement(BuildLogViewer, { logs: nodeLogs, runtime: "Node" })), /* @__PURE__ */ import_react62.default.createElement(Tab_default.Pane, { eventKey: "web" }, /* @__PURE__ */ import_react62.default.createElement(BuildLogViewer, { logs: webLogs, runtime: "Web" })), /* @__PURE__ */ import_react62.default.createElement(Tab_default.Pane, { eventKey: "pure" }, /* @__PURE__ */ import_react62.default.createElement(BuildLogViewer, { logs: pureLogs, runtime: "Pure" })))));
33037
+ };
33038
+
33039
+ // src/components/stateful/ProjectPage.tsx
33040
+ var ProjectPage = () => {
33041
+ const [summary, setSummary] = (0, import_react63.useState)(null);
33042
+ const [nodeLogs, setNodeLogs] = (0, import_react63.useState)(null);
33043
+ const [webLogs, setWebLogs] = (0, import_react63.useState)(null);
33044
+ const [pureLogs, setPureLogs] = (0, import_react63.useState)(null);
33045
+ const [config, setConfig] = (0, import_react63.useState)({});
33046
+ const [loading, setLoading] = (0, import_react63.useState)(true);
33047
+ const [error, setError] = (0, import_react63.useState)(null);
33048
+ const [projectName, setProjectName] = (0, import_react63.useState)("");
33049
+ const navigate = useNavigate();
33050
+ const location = useLocation();
33051
+ const [route, setRoute] = (0, import_react63.useState)("tests");
33052
+ (0, import_react63.useEffect)(() => {
33053
+ const hash = location.hash.replace("#", "");
33054
+ if (hash && ["tests", "node", "web", "pure"].includes(hash)) {
33055
+ setRoute(hash);
33056
+ } else {
33057
+ setRoute("tests");
33058
+ }
33059
+ }, [location.hash]);
33060
+ const { projectName: name } = useParams();
33061
+ (0, import_react63.useEffect)(() => {
33062
+ if (!name)
33063
+ return;
33064
+ setProjectName(name);
33065
+ const fetchData = async () => {
33066
+ try {
33067
+ const [summaryRes, nodeRes, webRes, pureRes, configRes] = await Promise.all([
33068
+ fetch(`reports/${name}/summary.json`),
33069
+ fetch(`bundles/node/${name}/metafile.json`),
33070
+ fetch(`bundles/web/${name}/metafile.json`),
33071
+ fetch(`bundles/pure/${name}/metafile.json`),
33072
+ fetch(`reports/${name}/config.json`)
33073
+ ]);
33074
+ const [summaryData, nodeData, webData, pureData, configData] = await Promise.all([
33075
+ summaryRes.ok ? summaryRes.json() : {},
33076
+ nodeRes.ok ? nodeRes.json() : { errors: ["Failed to load node build logs"] },
33077
+ webRes.ok ? webRes.json() : { errors: ["Failed to load web build logs"] },
33078
+ pureRes.ok ? pureRes.json() : { errors: ["Failed to load pure build logs"] },
33079
+ configRes.ok ? configRes.json() : { tests: [] }
33080
+ ]);
33081
+ setSummary(summaryData);
33082
+ setNodeLogs(nodeData);
33083
+ setWebLogs(webData);
33084
+ setPureLogs(pureData);
33085
+ setConfig(configData);
33086
+ } catch (err) {
33087
+ setError(err instanceof Error ? err.message : "Unknown error");
33088
+ } finally {
33089
+ setLoading(false);
33090
+ }
33091
+ };
33092
+ fetchData();
33093
+ }, [name]);
33094
+ return /* @__PURE__ */ import_react63.default.createElement(
33095
+ ProjectPageView,
33096
+ {
33097
+ summary,
33098
+ nodeLogs,
33099
+ webLogs,
33100
+ pureLogs,
33101
+ config,
33102
+ loading,
33103
+ error,
33104
+ projectName,
33105
+ route,
33106
+ setRoute,
33107
+ navigate
33108
+ }
33109
+ );
33110
+ };
33111
+
33112
+ // src/components/stateful/ProjectsPage.tsx
33113
+ var import_react65 = __toESM(require_react(), 1);
33114
+
33115
+ // src/components/pure/ProjectsPageView.tsx
33116
+ var import_react64 = __toESM(require_react(), 1);
33117
+ var ProjectsPageView = ({
33118
+ projects,
33119
+ summaries,
33120
+ configs,
33121
+ loading,
33122
+ error,
33123
+ navigate
33124
+ }) => {
33125
+ const getStatusIcon = (status) => {
33126
+ switch (status) {
33127
+ case "success":
33128
+ return "\u2705";
33129
+ case "failed":
33130
+ return "\u274C";
33131
+ case "warning":
33132
+ return "\u26A0\uFE0F";
33133
+ default:
33134
+ return "\u2753";
33198
33135
  }
33199
- ), /* @__PURE__ */ import_react63.default.createElement(Route, { path: "/projects/:projectName#:tab", element: /* @__PURE__ */ import_react63.default.createElement(ProjectPage, null) })))), /* @__PURE__ */ import_react63.default.createElement("footer", { className: "bg-light py-3 d-flex justify-content-between align-items-center" }, /* @__PURE__ */ import_react63.default.createElement("div", { className: "ms-3" }, /* @__PURE__ */ import_react63.default.createElement(SettingsButton, null)), /* @__PURE__ */ import_react63.default.createElement(Container_default, { className: "text-end", fluid: true }, "made with \u2764\uFE0F and ", /* @__PURE__ */ import_react63.default.createElement("a", { href: "https://www.npmjs.com/package/testeranto" }, "testeranto")))));
33136
+ };
33137
+ if (loading)
33138
+ return /* @__PURE__ */ import_react64.default.createElement("div", null, "Loading projects...");
33139
+ if (error)
33140
+ return /* @__PURE__ */ import_react64.default.createElement(Alert_default, { variant: "danger" }, "Error: ", error);
33141
+ return /* @__PURE__ */ import_react64.default.createElement("div", { className: "p-3" }, /* @__PURE__ */ import_react64.default.createElement(NavBar, { title: "Testeranto", backLink: null }), /* @__PURE__ */ import_react64.default.createElement(Table_default, { striped: true, bordered: true, hover: true, responsive: true }, /* @__PURE__ */ import_react64.default.createElement("thead", null, /* @__PURE__ */ import_react64.default.createElement("tr", null, /* @__PURE__ */ import_react64.default.createElement("th", null, "Project"), /* @__PURE__ */ import_react64.default.createElement("th", null, "Tests"), /* @__PURE__ */ import_react64.default.createElement("th", null, "Node"), /* @__PURE__ */ import_react64.default.createElement("th", null, "Web"), /* @__PURE__ */ import_react64.default.createElement("th", null, "Pure"))), /* @__PURE__ */ import_react64.default.createElement("tbody", null, projects.map((project) => /* @__PURE__ */ import_react64.default.createElement("tr", { key: project.name }, /* @__PURE__ */ import_react64.default.createElement("td", null, /* @__PURE__ */ import_react64.default.createElement("a", { href: "#", onClick: (e) => {
33142
+ e.preventDefault();
33143
+ navigate(`/projects/${project.name}`);
33144
+ } }, project.name)), /* @__PURE__ */ import_react64.default.createElement("td", null, /* @__PURE__ */ import_react64.default.createElement("div", { style: { maxHeight: "200px", overflowY: "auto" } }, summaries[project.name] ? Object.keys(summaries[project.name]).map((testName2) => {
33145
+ const testData = summaries[project.name][testName2];
33146
+ const runTime = configs[project.name].tests.find((t) => t[0] === testName2)[1];
33147
+ const hasRuntimeErrors = testData.runTimeErrors > 0;
33148
+ const hasStaticErrors = testData.typeErrors > 0 || testData.staticErrors > 0;
33149
+ return /* @__PURE__ */ import_react64.default.createElement("div", { key: testName2 }, /* @__PURE__ */ import_react64.default.createElement(
33150
+ "a",
33151
+ {
33152
+ href: `#/projects/${project.name}/tests/${encodeURIComponent(testName2)}/${runTime}`
33153
+ },
33154
+ hasRuntimeErrors ? "\u274C " : hasStaticErrors ? "\u26A0\uFE0F " : "",
33155
+ testName2.split("/").pop()
33156
+ ));
33157
+ }) : /* @__PURE__ */ import_react64.default.createElement("div", null, "Loading tests..."))), /* @__PURE__ */ import_react64.default.createElement("td", null, /* @__PURE__ */ import_react64.default.createElement(
33158
+ "a",
33159
+ {
33160
+ href: `#/projects/${project.name}#node`
33161
+ },
33162
+ getStatusIcon(project.nodeStatus),
33163
+ " Node build logs"
33164
+ )), /* @__PURE__ */ import_react64.default.createElement("td", null, /* @__PURE__ */ import_react64.default.createElement(
33165
+ "a",
33166
+ {
33167
+ href: `#/projects/${project.name}#web`
33168
+ },
33169
+ getStatusIcon(project.webStatus),
33170
+ " Web build logs"
33171
+ )), /* @__PURE__ */ import_react64.default.createElement("td", null, /* @__PURE__ */ import_react64.default.createElement(
33172
+ "a",
33173
+ {
33174
+ href: `#/projects/${project.name}#pure`
33175
+ },
33176
+ getStatusIcon(project.pureStatus),
33177
+ " Pure build logs"
33178
+ )))))));
33179
+ };
33180
+
33181
+ // src/components/stateful/ProjectsPage.tsx
33182
+ var ProjectsPage = () => {
33183
+ const [projects, setProjects] = (0, import_react65.useState)([]);
33184
+ const [summaries, setSummaries] = (0, import_react65.useState)({});
33185
+ const [loading, setLoading] = (0, import_react65.useState)(true);
33186
+ const [error, setError] = (0, import_react65.useState)(null);
33187
+ const [configs, setConfigs] = (0, import_react65.useState)({});
33188
+ const navigate = useNavigate();
33189
+ (0, import_react65.useEffect)(() => {
33190
+ const fetchProjects = async () => {
33191
+ try {
33192
+ const projectsRes = await fetch(`projects.json`);
33193
+ const projectNames = await projectsRes.json();
33194
+ const projectsData = await Promise.all(
33195
+ projectNames.map(async (name) => {
33196
+ const [summaryRes, nodeRes, webRes, pureRes, configRes] = await Promise.all([
33197
+ fetch(`reports/${name}/summary.json`),
33198
+ fetch(`bundles/node/${name}/metafile.json`),
33199
+ fetch(`bundles/web/${name}/metafile.json`),
33200
+ fetch(`bundles/pure/${name}/metafile.json`),
33201
+ fetch(`reports/${name}/config.json`)
33202
+ ]);
33203
+ const [summary, nodeData, webData, pureData, configData] = await Promise.all([
33204
+ summaryRes.json(),
33205
+ nodeRes.ok ? nodeRes.json() : { errors: ["Failed to load node build logs"] },
33206
+ webRes.ok ? webRes.json() : { errors: ["Failed to load web build logs"] },
33207
+ pureRes.ok ? pureRes.json() : { errors: ["Failed to load pure build logs"] },
33208
+ configRes.json()
33209
+ ]);
33210
+ setSummaries((prev) => ({ ...prev, [name]: summary }));
33211
+ setConfigs((prev) => ({ ...prev, [name]: configData }));
33212
+ return {
33213
+ name,
33214
+ testCount: Object.keys(summary).length,
33215
+ nodeStatus: nodeData.errors?.length ? "failed" : nodeData.warnings?.length ? "warning" : "success",
33216
+ webStatus: webData.errors?.length ? "failed" : webData.warnings?.length ? "warning" : "success",
33217
+ pureStatus: pureData.errors?.length ? "failed" : pureData.warnings?.length ? "warning" : "success"
33218
+ };
33219
+ })
33220
+ );
33221
+ setProjects(projectsData);
33222
+ } catch (err) {
33223
+ setError(err instanceof Error ? err.message : "Unknown error");
33224
+ } finally {
33225
+ setLoading(false);
33226
+ }
33227
+ };
33228
+ fetchProjects();
33229
+ }, []);
33230
+ return /* @__PURE__ */ import_react65.default.createElement(
33231
+ ProjectsPageView,
33232
+ {
33233
+ projects,
33234
+ summaries,
33235
+ configs,
33236
+ loading,
33237
+ error,
33238
+ navigate
33239
+ }
33240
+ );
33241
+ };
33242
+
33243
+ // src/App.tsx
33244
+ var App = () => {
33245
+ return /* @__PURE__ */ import_react66.default.createElement(HashRouter, null, /* @__PURE__ */ import_react66.default.createElement("div", { className: "d-flex flex-column min-vh-100", key: window.location.pathname }, /* @__PURE__ */ import_react66.default.createElement("main", { className: "flex-grow-1 p-3" }, /* @__PURE__ */ import_react66.default.createElement(Container_default, { fluid: true }, /* @__PURE__ */ import_react66.default.createElement(Routes, null, /* @__PURE__ */ import_react66.default.createElement(Route, { path: "/", element: /* @__PURE__ */ import_react66.default.createElement(ProjectsPage, null) }), /* @__PURE__ */ import_react66.default.createElement(Route, { path: "/projects/:projectName", element: /* @__PURE__ */ import_react66.default.createElement(ProjectPage, null) }), /* @__PURE__ */ import_react66.default.createElement(Route, { path: "/projects/:projectName/tests/*", element: /* @__PURE__ */ import_react66.default.createElement(TestPage, null) }), /* @__PURE__ */ import_react66.default.createElement(Route, { path: "/projects/:projectName#:tab", element: /* @__PURE__ */ import_react66.default.createElement(ProjectPage, null) })))), /* @__PURE__ */ import_react66.default.createElement("footer", { className: "bg-light py-3 d-flex justify-content-between align-items-center" }, /* @__PURE__ */ import_react66.default.createElement("div", { className: "ms-3" }, /* @__PURE__ */ import_react66.default.createElement(SettingsButton, null)), /* @__PURE__ */ import_react66.default.createElement(Container_default, { className: "text-end", fluid: true }, "made with \u2764\uFE0F and ", /* @__PURE__ */ import_react66.default.createElement("a", { href: "https://www.npmjs.com/package/testeranto" }, "testeranto")))));
33200
33246
  };
33201
33247
  if (typeof window !== "undefined") {
33202
33248
  window.App = App;
33203
- window.React = import_react63.default;
33249
+ window.React = import_react66.default;
33204
33250
  window.ReactDOM = import_client.default;
33205
33251
  }
33206
33252
  })();