hazo_ui 3.2.1 → 3.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,9 +23,46 @@ declare function AppSidebar({ pkg, navItems, }: {
23
23
  navItems: NavItem[];
24
24
  }): React__default.JSX.Element;
25
25
 
26
+ interface CaseDoc {
27
+ /** What this test verifies, in plain language. */
28
+ description: string;
29
+ /** The inputs / preconditions the case feeds in (URL, payload, fixture, state). */
30
+ inputs: string;
31
+ /** The outputs / state the case asserts on success. */
32
+ expectedOutputs: string;
33
+ /** Known limitations, assumptions, or gotchas. Use "None" when not applicable. */
34
+ caveats: string;
35
+ }
36
+ interface Case {
37
+ name: string;
38
+ run: () => Promise<void>;
39
+ doc: CaseDoc;
40
+ }
41
+ interface Scenario {
42
+ id: string;
43
+ name: string;
44
+ pkg: string;
45
+ filePath?: string;
46
+ cases: Case[];
47
+ }
48
+ /**
49
+ * Register a scenario with the global registry.
50
+ * Call this at module load time in your scenario files.
51
+ */
52
+ declare function registerScenario(id: string, opts: {
53
+ name: string;
54
+ pkg: string;
55
+ cases: Case[];
56
+ }): void;
57
+ /** Return the entire registry (read-only reference). */
58
+ declare function getRegistry(): Map<string, Scenario>;
59
+ /** Clear the registry — used in tests only. */
60
+ declare function clearRegistry(): void;
61
+
26
62
  type RunStatus = "pending" | "running" | "passed" | "failed";
27
63
  interface CaseResult {
28
64
  name: string;
65
+ doc?: CaseDoc;
29
66
  scenarioId?: string;
30
67
  status: RunStatus;
31
68
  durationMs?: number;
@@ -57,31 +94,6 @@ declare function CopyAllFailuresButton({ failedCases, }: {
57
94
  failedCases: CaseResult[];
58
95
  }): React__default.JSX.Element;
59
96
 
60
- interface Case {
61
- name: string;
62
- run: () => Promise<void>;
63
- }
64
- interface Scenario {
65
- id: string;
66
- name: string;
67
- pkg: string;
68
- filePath?: string;
69
- cases: Case[];
70
- }
71
- /**
72
- * Register a scenario with the global registry.
73
- * Call this at module load time in your scenario files.
74
- */
75
- declare function registerScenario(id: string, opts: {
76
- name: string;
77
- pkg: string;
78
- cases: Case[];
79
- }): void;
80
- /** Return the entire registry (read-only reference). */
81
- declare function getRegistry(): Map<string, Scenario>;
82
- /** Clear the registry — used in tests only. */
83
- declare function clearRegistry(): void;
84
-
85
97
  /**
86
98
  * Assertion error thrown by all helpers in this module.
87
99
  * Carries expected/actual values and the call-site string for prompt generation.
@@ -141,4 +153,4 @@ interface FormatOptions {
141
153
  }
142
154
  declare function formatAsClaudePrompt(fc: FailedCase, opts?: FormatOptions): Promise<string>;
143
155
 
144
- export { AppSidebar, type AutoTestContextValue, AutoTestProvider, AutoTestRunner, type Case, type CaseResult, CopyAllFailuresButton, type FailedCase, type FormatOptions, HazoAssertionError, type NavItem, type RunStatus, type Scenario, type ScenarioResult, SidebarLayout, assertEqual, assertIncludes, assertMatch, assertRejects, assertResolves, assertThrows, clearRegistry, formatAsClaudePrompt, getRegistry, registerScenario, useAutoTest };
156
+ export { AppSidebar, type AutoTestContextValue, AutoTestProvider, AutoTestRunner, type Case, type CaseDoc, type CaseResult, CopyAllFailuresButton, type FailedCase, type FormatOptions, HazoAssertionError, type NavItem, type RunStatus, type Scenario, type ScenarioResult, SidebarLayout, assertEqual, assertIncludes, assertMatch, assertRejects, assertResolves, assertThrows, clearRegistry, formatAsClaudePrompt, getRegistry, registerScenario, useAutoTest };
@@ -23,9 +23,46 @@ declare function AppSidebar({ pkg, navItems, }: {
23
23
  navItems: NavItem[];
24
24
  }): React__default.JSX.Element;
25
25
 
26
+ interface CaseDoc {
27
+ /** What this test verifies, in plain language. */
28
+ description: string;
29
+ /** The inputs / preconditions the case feeds in (URL, payload, fixture, state). */
30
+ inputs: string;
31
+ /** The outputs / state the case asserts on success. */
32
+ expectedOutputs: string;
33
+ /** Known limitations, assumptions, or gotchas. Use "None" when not applicable. */
34
+ caveats: string;
35
+ }
36
+ interface Case {
37
+ name: string;
38
+ run: () => Promise<void>;
39
+ doc: CaseDoc;
40
+ }
41
+ interface Scenario {
42
+ id: string;
43
+ name: string;
44
+ pkg: string;
45
+ filePath?: string;
46
+ cases: Case[];
47
+ }
48
+ /**
49
+ * Register a scenario with the global registry.
50
+ * Call this at module load time in your scenario files.
51
+ */
52
+ declare function registerScenario(id: string, opts: {
53
+ name: string;
54
+ pkg: string;
55
+ cases: Case[];
56
+ }): void;
57
+ /** Return the entire registry (read-only reference). */
58
+ declare function getRegistry(): Map<string, Scenario>;
59
+ /** Clear the registry — used in tests only. */
60
+ declare function clearRegistry(): void;
61
+
26
62
  type RunStatus = "pending" | "running" | "passed" | "failed";
27
63
  interface CaseResult {
28
64
  name: string;
65
+ doc?: CaseDoc;
29
66
  scenarioId?: string;
30
67
  status: RunStatus;
31
68
  durationMs?: number;
@@ -57,31 +94,6 @@ declare function CopyAllFailuresButton({ failedCases, }: {
57
94
  failedCases: CaseResult[];
58
95
  }): React__default.JSX.Element;
59
96
 
60
- interface Case {
61
- name: string;
62
- run: () => Promise<void>;
63
- }
64
- interface Scenario {
65
- id: string;
66
- name: string;
67
- pkg: string;
68
- filePath?: string;
69
- cases: Case[];
70
- }
71
- /**
72
- * Register a scenario with the global registry.
73
- * Call this at module load time in your scenario files.
74
- */
75
- declare function registerScenario(id: string, opts: {
76
- name: string;
77
- pkg: string;
78
- cases: Case[];
79
- }): void;
80
- /** Return the entire registry (read-only reference). */
81
- declare function getRegistry(): Map<string, Scenario>;
82
- /** Clear the registry — used in tests only. */
83
- declare function clearRegistry(): void;
84
-
85
97
  /**
86
98
  * Assertion error thrown by all helpers in this module.
87
99
  * Carries expected/actual values and the call-site string for prompt generation.
@@ -141,4 +153,4 @@ interface FormatOptions {
141
153
  }
142
154
  declare function formatAsClaudePrompt(fc: FailedCase, opts?: FormatOptions): Promise<string>;
143
155
 
144
- export { AppSidebar, type AutoTestContextValue, AutoTestProvider, AutoTestRunner, type Case, type CaseResult, CopyAllFailuresButton, type FailedCase, type FormatOptions, HazoAssertionError, type NavItem, type RunStatus, type Scenario, type ScenarioResult, SidebarLayout, assertEqual, assertIncludes, assertMatch, assertRejects, assertResolves, assertThrows, clearRegistry, formatAsClaudePrompt, getRegistry, registerScenario, useAutoTest };
156
+ export { AppSidebar, type AutoTestContextValue, AutoTestProvider, AutoTestRunner, type Case, type CaseDoc, type CaseResult, CopyAllFailuresButton, type FailedCase, type FormatOptions, HazoAssertionError, type NavItem, type RunStatus, type Scenario, type ScenarioResult, SidebarLayout, assertEqual, assertIncludes, assertMatch, assertRejects, assertResolves, assertThrows, clearRegistry, formatAsClaudePrompt, getRegistry, registerScenario, useAutoTest };
@@ -2,7 +2,7 @@ import React, { createContext, useState, useRef, useCallback, useContext } from
2
2
  import { clsx } from 'clsx';
3
3
  import { twMerge } from 'tailwind-merge';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
5
- import { optional_import } from 'hazo_core';
5
+ import { optional_import } from 'hazo_core/client';
6
6
 
7
7
  var __defProp = Object.defineProperty;
8
8
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -146,6 +146,7 @@ function build_initial_state() {
146
146
  status: "pending",
147
147
  cases: scenario.cases.map((c) => ({
148
148
  name: c.name,
149
+ doc: c.doc,
149
150
  status: "pending"
150
151
  }))
151
152
  });
@@ -854,6 +855,63 @@ function CopySinglePromptButton({
854
855
  }
855
856
  );
856
857
  }
858
+ function CaseRow({
859
+ c,
860
+ scenario_id,
861
+ pkg
862
+ }) {
863
+ const [expanded, set_expanded] = useState(false);
864
+ return /* @__PURE__ */ jsxs("div", { className: "px-6 py-2", children: [
865
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
866
+ c.doc && /* @__PURE__ */ jsx(
867
+ "button",
868
+ {
869
+ onClick: () => set_expanded((v) => !v),
870
+ className: "text-gray-400 hover:text-gray-600 text-xs font-mono w-3 shrink-0",
871
+ "aria-label": expanded ? "Collapse doc" : "Expand doc",
872
+ children: expanded ? "\u25BE" : "\u25B8"
873
+ }
874
+ ),
875
+ !c.doc && /* @__PURE__ */ jsx("span", { className: "w-3 shrink-0" }),
876
+ /* @__PURE__ */ jsx(StatusIcon, { status: c.status }),
877
+ /* @__PURE__ */ jsx("span", { className: cn(
878
+ "flex-1",
879
+ c.status === "failed" ? "text-red-700" : "text-gray-700"
880
+ ), children: c.name }),
881
+ c.durationMs != null && /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-400", children: [
882
+ c.durationMs,
883
+ "ms"
884
+ ] }),
885
+ c.status === "failed" && c.error && /* @__PURE__ */ jsx(
886
+ CopySinglePromptButton,
887
+ {
888
+ scenario_id,
889
+ case_result: c,
890
+ pkg
891
+ }
892
+ )
893
+ ] }),
894
+ expanded && c.doc && /* @__PURE__ */ jsxs("div", { className: "mt-2 ml-8 text-xs rounded border border-gray-100 bg-gray-50 divide-y divide-gray-100", children: [
895
+ /* @__PURE__ */ jsxs("div", { className: "px-3 py-2", children: [
896
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-600", children: "Description" }),
897
+ /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-gray-700", children: c.doc.description })
898
+ ] }),
899
+ /* @__PURE__ */ jsxs("div", { className: "px-3 py-2", children: [
900
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-600", children: "Inputs" }),
901
+ /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-gray-700", children: c.doc.inputs })
902
+ ] }),
903
+ /* @__PURE__ */ jsxs("div", { className: "px-3 py-2", children: [
904
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-600", children: "Expected outputs" }),
905
+ /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-gray-700", children: c.doc.expectedOutputs })
906
+ ] }),
907
+ /* @__PURE__ */ jsxs("div", { className: "px-3 py-2", children: [
908
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-600", children: "Caveats" }),
909
+ /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-gray-700", children: c.doc.caveats })
910
+ ] })
911
+ ] }),
912
+ c.status === "failed" && c.error && /* @__PURE__ */ jsx("div", { className: "mt-1 ml-8 text-xs text-red-600 bg-red-50 rounded px-2 py-1 font-mono", children: c.error.message })
913
+ ] });
914
+ }
857
915
  function ScenarioRow({
858
916
  scenario,
859
917
  pkg
@@ -895,28 +953,7 @@ function ScenarioRow({
895
953
  }
896
954
  )
897
955
  ] }),
898
- expanded && /* @__PURE__ */ jsx("div", { className: "divide-y divide-gray-100", children: scenario.cases.map((c, i) => /* @__PURE__ */ jsxs("div", { className: "px-6 py-2", children: [
899
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
900
- /* @__PURE__ */ jsx(StatusIcon, { status: c.status }),
901
- /* @__PURE__ */ jsx("span", { className: cn(
902
- "flex-1",
903
- c.status === "failed" ? "text-red-700" : "text-gray-700"
904
- ), children: c.name }),
905
- c.durationMs != null && /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-400", children: [
906
- c.durationMs,
907
- "ms"
908
- ] }),
909
- c.status === "failed" && c.error && /* @__PURE__ */ jsx(
910
- CopySinglePromptButton,
911
- {
912
- scenario_id: scenario.id,
913
- case_result: c,
914
- pkg
915
- }
916
- )
917
- ] }),
918
- c.status === "failed" && c.error && /* @__PURE__ */ jsx("div", { className: "mt-1 ml-5 text-xs text-red-600 bg-red-50 rounded px-2 py-1 font-mono", children: c.error.message })
919
- ] }, i)) })
956
+ expanded && /* @__PURE__ */ jsx("div", { className: "divide-y divide-gray-100", children: scenario.cases.map((c, i) => /* @__PURE__ */ jsx(CaseRow, { c, scenario_id: scenario.id, pkg }, i)) })
920
957
  ] });
921
958
  }
922
959
  function AutoTestRunner() {