@noego/wood 0.4.9 → 0.4.10

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 (144) hide show
  1. package/bin/axe.js +313 -98
  2. package/dist/automation/actions.cjs +17 -0
  3. package/dist/automation/actions.cjs.map +1 -0
  4. package/dist/automation/actions.d.cts +57 -0
  5. package/dist/automation/actions.d.ts +57 -0
  6. package/dist/automation/actions.js +1 -0
  7. package/dist/automation/actions.js.map +1 -0
  8. package/dist/automation/actions_executor.cjs +101 -0
  9. package/dist/automation/actions_executor.cjs.map +1 -0
  10. package/dist/automation/actions_executor.d.cts +16 -0
  11. package/dist/automation/actions_executor.d.ts +16 -0
  12. package/dist/automation/actions_executor.js +76 -0
  13. package/dist/automation/actions_executor.js.map +1 -0
  14. package/dist/automation/connection.cjs +86 -0
  15. package/dist/automation/connection.cjs.map +1 -0
  16. package/dist/automation/connection.d.cts +18 -0
  17. package/dist/automation/connection.d.ts +18 -0
  18. package/dist/automation/connection.js +51 -0
  19. package/dist/automation/connection.js.map +1 -0
  20. package/dist/automation/errors.cjs +50 -0
  21. package/dist/automation/errors.cjs.map +1 -0
  22. package/dist/automation/errors.d.cts +31 -0
  23. package/dist/automation/errors.d.ts +31 -0
  24. package/dist/automation/errors.js +24 -0
  25. package/dist/automation/errors.js.map +1 -0
  26. package/dist/automation/index.cjs +49 -0
  27. package/dist/automation/index.cjs.map +1 -0
  28. package/dist/automation/index.d.cts +16 -0
  29. package/dist/automation/index.d.ts +16 -0
  30. package/dist/automation/index.js +15 -0
  31. package/dist/automation/index.js.map +1 -0
  32. package/dist/automation/introspection_reader.cjs +75 -0
  33. package/dist/automation/introspection_reader.cjs.map +1 -0
  34. package/dist/automation/introspection_reader.d.cts +20 -0
  35. package/dist/automation/introspection_reader.d.ts +20 -0
  36. package/dist/automation/introspection_reader.js +48 -0
  37. package/dist/automation/introspection_reader.js.map +1 -0
  38. package/dist/automation/locator.cjs +102 -0
  39. package/dist/automation/locator.cjs.map +1 -0
  40. package/dist/automation/locator.d.cts +51 -0
  41. package/dist/automation/locator.d.ts +51 -0
  42. package/dist/automation/locator.js +75 -0
  43. package/dist/automation/locator.js.map +1 -0
  44. package/dist/automation/observation.cjs +17 -0
  45. package/dist/automation/observation.cjs.map +1 -0
  46. package/dist/automation/observation.d.cts +44 -0
  47. package/dist/automation/observation.d.ts +44 -0
  48. package/dist/automation/observation.js +1 -0
  49. package/dist/automation/observation.js.map +1 -0
  50. package/dist/automation/receipts.cjs +17 -0
  51. package/dist/automation/receipts.cjs.map +1 -0
  52. package/dist/automation/receipts.d.cts +27 -0
  53. package/dist/automation/receipts.d.ts +27 -0
  54. package/dist/automation/receipts.js +1 -0
  55. package/dist/automation/receipts.js.map +1 -0
  56. package/dist/automation/scenario.cjs +696 -0
  57. package/dist/automation/scenario.cjs.map +1 -0
  58. package/dist/automation/scenario.d.cts +89 -0
  59. package/dist/automation/scenario.d.ts +89 -0
  60. package/dist/automation/scenario.js +660 -0
  61. package/dist/automation/scenario.js.map +1 -0
  62. package/dist/automation/scrolling.cjs +17 -0
  63. package/dist/automation/scrolling.cjs.map +1 -0
  64. package/dist/automation/scrolling.d.cts +51 -0
  65. package/dist/automation/scrolling.d.ts +51 -0
  66. package/dist/automation/scrolling.js +1 -0
  67. package/dist/automation/scrolling.js.map +1 -0
  68. package/dist/automation/scrolling_executor.cjs +109 -0
  69. package/dist/automation/scrolling_executor.cjs.map +1 -0
  70. package/dist/automation/scrolling_executor.d.cts +13 -0
  71. package/dist/automation/scrolling_executor.d.ts +13 -0
  72. package/dist/automation/scrolling_executor.js +84 -0
  73. package/dist/automation/scrolling_executor.js.map +1 -0
  74. package/dist/automation/target_identity.cjs +17 -0
  75. package/dist/automation/target_identity.cjs.map +1 -0
  76. package/dist/automation/target_identity.d.cts +28 -0
  77. package/dist/automation/target_identity.d.ts +28 -0
  78. package/dist/automation/target_identity.js +1 -0
  79. package/dist/automation/target_identity.js.map +1 -0
  80. package/dist/automation/target_registry.cjs +148 -0
  81. package/dist/automation/target_registry.cjs.map +1 -0
  82. package/dist/automation/target_registry.d.cts +32 -0
  83. package/dist/automation/target_registry.d.ts +32 -0
  84. package/dist/automation/target_registry.js +122 -0
  85. package/dist/automation/target_registry.js.map +1 -0
  86. package/dist/automation/waits.cjs +17 -0
  87. package/dist/automation/waits.cjs.map +1 -0
  88. package/dist/automation/waits.d.cts +44 -0
  89. package/dist/automation/waits.d.ts +44 -0
  90. package/dist/automation/waits.js +1 -0
  91. package/dist/automation/waits.js.map +1 -0
  92. package/dist/automation/waits_executor.cjs +104 -0
  93. package/dist/automation/waits_executor.cjs.map +1 -0
  94. package/dist/automation/waits_executor.d.cts +14 -0
  95. package/dist/automation/waits_executor.d.ts +14 -0
  96. package/dist/automation/waits_executor.js +79 -0
  97. package/dist/automation/waits_executor.js.map +1 -0
  98. package/dist/client/index.d.cts +1 -0
  99. package/dist/client/index.d.ts +1 -0
  100. package/dist/codegen/renderer_app_generator.cjs +16 -1
  101. package/dist/codegen/renderer_app_generator.cjs.map +1 -1
  102. package/dist/codegen/renderer_app_generator.js +16 -1
  103. package/dist/codegen/renderer_app_generator.js.map +1 -1
  104. package/dist/index.d.cts +1 -0
  105. package/dist/index.d.ts +1 -0
  106. package/dist/navigation/automation_introspection.cjs +110 -0
  107. package/dist/navigation/automation_introspection.cjs.map +1 -0
  108. package/dist/navigation/automation_introspection.d.cts +60 -0
  109. package/dist/navigation/automation_introspection.d.ts +60 -0
  110. package/dist/navigation/automation_introspection.js +85 -0
  111. package/dist/navigation/automation_introspection.js.map +1 -0
  112. package/dist/navigation/index.cjs +7 -2
  113. package/dist/navigation/index.cjs.map +1 -1
  114. package/dist/navigation/index.d.cts +2 -0
  115. package/dist/navigation/index.d.ts +2 -0
  116. package/dist/navigation/index.js +4 -1
  117. package/dist/navigation/index.js.map +1 -1
  118. package/dist/testing/automation_assertions.cjs +417 -0
  119. package/dist/testing/automation_assertions.cjs.map +1 -0
  120. package/dist/testing/automation_assertions.d.cts +44 -0
  121. package/dist/testing/automation_assertions.d.ts +44 -0
  122. package/dist/testing/automation_assertions.js +385 -0
  123. package/dist/testing/automation_assertions.js.map +1 -0
  124. package/dist/testing/browser.cjs +26 -34
  125. package/dist/testing/browser.cjs.map +1 -1
  126. package/dist/testing/browser.d.cts +2 -1
  127. package/dist/testing/browser.d.ts +2 -1
  128. package/dist/testing/browser.js +30 -31
  129. package/dist/testing/browser.js.map +1 -1
  130. package/dist/testing/create_controller_harness.d.cts +1 -0
  131. package/dist/testing/create_controller_harness.d.ts +1 -0
  132. package/dist/testing/geometry.cjs +109 -0
  133. package/dist/testing/geometry.cjs.map +1 -0
  134. package/dist/testing/geometry.d.cts +45 -0
  135. package/dist/testing/geometry.d.ts +45 -0
  136. package/dist/testing/geometry.js +79 -0
  137. package/dist/testing/geometry.js.map +1 -0
  138. package/dist/testing/index.cjs +31 -2
  139. package/dist/testing/index.cjs.map +1 -1
  140. package/dist/testing/index.d.cts +4 -0
  141. package/dist/testing/index.d.ts +4 -0
  142. package/dist/testing/index.js +31 -1
  143. package/dist/testing/index.js.map +1 -1
  144. package/package.json +7 -1
@@ -2,6 +2,7 @@ import { Navigation } from '../navigation/index.cjs';
2
2
  import { TraceRecorder } from '../trace-testing/trace_recorder.cjs';
3
3
  import { RouterBridgeResult } from './create_router_bridge.cjs';
4
4
  import { createTestRouter } from './create_test_router.cjs';
5
+ import '../navigation/automation_introspection.cjs';
5
6
  import '@noego/trace/testing';
6
7
  import '../trace_hub-Cob54qRx.cjs';
7
8
  import 'rxjs';
@@ -2,6 +2,7 @@ import { Navigation } from '../navigation/index.js';
2
2
  import { TraceRecorder } from '../trace-testing/trace_recorder.js';
3
3
  import { RouterBridgeResult } from './create_router_bridge.js';
4
4
  import { createTestRouter } from './create_test_router.js';
5
+ import '../navigation/automation_introspection.js';
5
6
  import '@noego/trace/testing';
6
7
  import '../trace_hub-Cob54qRx.js';
7
8
  import 'rxjs';
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var geometry_exports = {};
20
+ __export(geometry_exports, {
21
+ axisEdges: () => axisEdges,
22
+ axisGap: () => axisGap,
23
+ evenSpacing: () => evenSpacing,
24
+ gaps: () => gaps,
25
+ rectsOverlap: () => rectsOverlap,
26
+ sharedEdges: () => sharedEdges,
27
+ snapshotRectsOverlap: () => snapshotRectsOverlap
28
+ });
29
+ module.exports = __toCommonJS(geometry_exports);
30
+ function axisEdges(rect, axis) {
31
+ return axis === "horizontal" ? { leading: rect.left, trailing: rect.right } : { leading: rect.top, trailing: rect.bottom };
32
+ }
33
+ function axisGap(first, second, axis) {
34
+ const a = axisEdges(first, axis);
35
+ const b = axisEdges(second, axis);
36
+ const [earlier, later] = a.leading <= b.leading ? [a, b] : [b, a];
37
+ return later.leading - earlier.trailing;
38
+ }
39
+ function rectsOverlap(a, b) {
40
+ return Boolean(
41
+ a && b && a.left < b.right && a.right > b.left && a.top < b.bottom && a.bottom > b.top
42
+ );
43
+ }
44
+ function snapshotRectsOverlap(a, b) {
45
+ return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;
46
+ }
47
+ function sharedEdges(rects, edge, options = {}) {
48
+ const tolerance = options.tolerance ?? 1;
49
+ if (rects.length < 2) {
50
+ return {
51
+ pass: false,
52
+ message: "sharedEdges requires at least two rects.",
53
+ details: { count: rects.length, edge, tolerance }
54
+ };
55
+ }
56
+ const expected = rects[0][edge];
57
+ const deltas = rects.slice(1).map((rect) => Math.abs(rect[edge] - expected));
58
+ const maximumDelta = Math.max(...deltas);
59
+ const pass = maximumDelta <= tolerance;
60
+ return {
61
+ pass,
62
+ message: pass ? `All rects share the ${edge} edge within ${tolerance}px.` : `Rects do not share the ${edge} edge within ${tolerance}px (maximum delta ${maximumDelta.toFixed(2)}px).`,
63
+ details: { edge, tolerance, expected, deltas, maximumDelta }
64
+ };
65
+ }
66
+ function gaps(rects, axis) {
67
+ const sorted = [...rects].sort(
68
+ (a, b) => axisEdges(a, axis).leading - axisEdges(b, axis).leading
69
+ );
70
+ return sorted.slice(1).map((rect, index) => axisGap(sorted[index], rect, axis));
71
+ }
72
+ function evenSpacing(rects, axis, options = {}) {
73
+ const tolerance = options.tolerance ?? 1;
74
+ if (rects.length < 3) {
75
+ return {
76
+ pass: false,
77
+ message: `evenSpacing requires at least three rects, got ${rects.length}.`,
78
+ details: { count: rects.length, axis, tolerance }
79
+ };
80
+ }
81
+ const measuredGaps = gaps(rects, axis);
82
+ const widest = Math.max(...measuredGaps);
83
+ const narrowest = Math.min(...measuredGaps);
84
+ const spread = widest - narrowest;
85
+ const pass = spread <= tolerance;
86
+ return {
87
+ pass,
88
+ message: pass ? `Rects are evenly spaced along ${axis} within ${tolerance}px.` : `Rects are not evenly spaced along ${axis}: gap spread ${spread.toFixed(2)}px exceeds ${tolerance}px.`,
89
+ details: {
90
+ axis,
91
+ tolerance,
92
+ gaps: measuredGaps,
93
+ widest,
94
+ narrowest,
95
+ spread
96
+ }
97
+ };
98
+ }
99
+ // Annotate the CommonJS export names for ESM import in node:
100
+ 0 && (module.exports = {
101
+ axisEdges,
102
+ axisGap,
103
+ evenSpacing,
104
+ gaps,
105
+ rectsOverlap,
106
+ sharedEdges,
107
+ snapshotRectsOverlap
108
+ });
109
+ //# sourceMappingURL=geometry.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/testing/geometry.ts"],"sourcesContent":["export type RectAxis = 'horizontal' | 'vertical';\n\nexport interface RectBox {\n top: number;\n left: number;\n right: number;\n bottom: number;\n width: number;\n height: number;\n}\n\nexport interface SnapshotRect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface GeometryVerdict {\n pass: boolean;\n message: string;\n details?: Record<string, unknown>;\n}\n\nexport type RectEdge = 'left' | 'right' | 'top' | 'bottom';\n\nexport function axisEdges(\n rect: RectBox,\n axis: RectAxis,\n): { leading: number; trailing: number } {\n return axis === 'horizontal'\n ? { leading: rect.left, trailing: rect.right }\n : { leading: rect.top, trailing: rect.bottom };\n}\n\n/**\n * Edge-to-edge gap between two border boxes. The box with the smaller leading\n * edge is treated as the earlier box, so negative values mean overlap.\n */\nexport function axisGap(first: RectBox, second: RectBox, axis: RectAxis): number {\n const a = axisEdges(first, axis);\n const b = axisEdges(second, axis);\n const [earlier, later] = a.leading <= b.leading ? [a, b] : [b, a];\n return later.leading - earlier.trailing;\n}\n\nexport function rectsOverlap(\n a: RectBox | null | undefined,\n b: RectBox | null | undefined,\n): boolean {\n return Boolean(\n a && b\n && a.left < b.right && a.right > b.left\n && a.top < b.bottom && a.bottom > b.top,\n );\n}\n\n/** Two CDP snapshot `[x,y,w,h]` rects overlap on both axes. */\nexport function snapshotRectsOverlap(a: SnapshotRect, b: SnapshotRect): boolean {\n return a.x < b.x + b.w\n && a.x + a.w > b.x\n && a.y < b.y + b.h\n && a.y + a.h > b.y;\n}\n\n/** Assert that every rect shares one named edge with the first rect. */\nexport function sharedEdges(\n rects: readonly RectBox[],\n edge: RectEdge,\n options: { tolerance?: number } = {},\n): GeometryVerdict {\n const tolerance = options.tolerance ?? 1;\n if (rects.length < 2) {\n return {\n pass: false,\n message: 'sharedEdges requires at least two rects.',\n details: { count: rects.length, edge, tolerance },\n };\n }\n\n const expected = rects[0][edge];\n const deltas = rects.slice(1).map((rect) => Math.abs(rect[edge] - expected));\n const maximumDelta = Math.max(...deltas);\n const pass = maximumDelta <= tolerance;\n return {\n pass,\n message: pass\n ? `All rects share the ${edge} edge within ${tolerance}px.`\n : `Rects do not share the ${edge} edge within ${tolerance}px (maximum delta ${maximumDelta.toFixed(2)}px).`,\n details: { edge, tolerance, expected, deltas, maximumDelta },\n };\n}\n\n/** Consecutive edge-to-edge gaps, after sorting rects along the requested axis. */\nexport function gaps(rects: readonly RectBox[], axis: RectAxis): number[] {\n const sorted = [...rects].sort(\n (a, b) => axisEdges(a, axis).leading - axisEdges(b, axis).leading,\n );\n return sorted.slice(1).map((rect, index) => axisGap(sorted[index], rect, axis));\n}\n\n/** Assert that consecutive rect gaps have no more than the requested spread. */\nexport function evenSpacing(\n rects: readonly RectBox[],\n axis: RectAxis,\n options: { tolerance?: number } = {},\n): GeometryVerdict {\n const tolerance = options.tolerance ?? 1;\n if (rects.length < 3) {\n return {\n pass: false,\n message: `evenSpacing requires at least three rects, got ${rects.length}.`,\n details: { count: rects.length, axis, tolerance },\n };\n }\n\n const measuredGaps = gaps(rects, axis);\n const widest = Math.max(...measuredGaps);\n const narrowest = Math.min(...measuredGaps);\n const spread = widest - narrowest;\n const pass = spread <= tolerance;\n return {\n pass,\n message: pass\n ? `Rects are evenly spaced along ${axis} within ${tolerance}px.`\n : `Rects are not evenly spaced along ${axis}: gap spread ${spread.toFixed(2)}px exceeds ${tolerance}px.`,\n details: {\n axis,\n tolerance,\n gaps: measuredGaps,\n widest,\n narrowest,\n spread,\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,45 @@
1
+ type RectAxis = 'horizontal' | 'vertical';
2
+ interface RectBox {
3
+ top: number;
4
+ left: number;
5
+ right: number;
6
+ bottom: number;
7
+ width: number;
8
+ height: number;
9
+ }
10
+ interface SnapshotRect {
11
+ x: number;
12
+ y: number;
13
+ w: number;
14
+ h: number;
15
+ }
16
+ interface GeometryVerdict {
17
+ pass: boolean;
18
+ message: string;
19
+ details?: Record<string, unknown>;
20
+ }
21
+ type RectEdge = 'left' | 'right' | 'top' | 'bottom';
22
+ declare function axisEdges(rect: RectBox, axis: RectAxis): {
23
+ leading: number;
24
+ trailing: number;
25
+ };
26
+ /**
27
+ * Edge-to-edge gap between two border boxes. The box with the smaller leading
28
+ * edge is treated as the earlier box, so negative values mean overlap.
29
+ */
30
+ declare function axisGap(first: RectBox, second: RectBox, axis: RectAxis): number;
31
+ declare function rectsOverlap(a: RectBox | null | undefined, b: RectBox | null | undefined): boolean;
32
+ /** Two CDP snapshot `[x,y,w,h]` rects overlap on both axes. */
33
+ declare function snapshotRectsOverlap(a: SnapshotRect, b: SnapshotRect): boolean;
34
+ /** Assert that every rect shares one named edge with the first rect. */
35
+ declare function sharedEdges(rects: readonly RectBox[], edge: RectEdge, options?: {
36
+ tolerance?: number;
37
+ }): GeometryVerdict;
38
+ /** Consecutive edge-to-edge gaps, after sorting rects along the requested axis. */
39
+ declare function gaps(rects: readonly RectBox[], axis: RectAxis): number[];
40
+ /** Assert that consecutive rect gaps have no more than the requested spread. */
41
+ declare function evenSpacing(rects: readonly RectBox[], axis: RectAxis, options?: {
42
+ tolerance?: number;
43
+ }): GeometryVerdict;
44
+
45
+ export { type GeometryVerdict, type RectAxis, type RectBox, type RectEdge, type SnapshotRect, axisEdges, axisGap, evenSpacing, gaps, rectsOverlap, sharedEdges, snapshotRectsOverlap };
@@ -0,0 +1,45 @@
1
+ type RectAxis = 'horizontal' | 'vertical';
2
+ interface RectBox {
3
+ top: number;
4
+ left: number;
5
+ right: number;
6
+ bottom: number;
7
+ width: number;
8
+ height: number;
9
+ }
10
+ interface SnapshotRect {
11
+ x: number;
12
+ y: number;
13
+ w: number;
14
+ h: number;
15
+ }
16
+ interface GeometryVerdict {
17
+ pass: boolean;
18
+ message: string;
19
+ details?: Record<string, unknown>;
20
+ }
21
+ type RectEdge = 'left' | 'right' | 'top' | 'bottom';
22
+ declare function axisEdges(rect: RectBox, axis: RectAxis): {
23
+ leading: number;
24
+ trailing: number;
25
+ };
26
+ /**
27
+ * Edge-to-edge gap between two border boxes. The box with the smaller leading
28
+ * edge is treated as the earlier box, so negative values mean overlap.
29
+ */
30
+ declare function axisGap(first: RectBox, second: RectBox, axis: RectAxis): number;
31
+ declare function rectsOverlap(a: RectBox | null | undefined, b: RectBox | null | undefined): boolean;
32
+ /** Two CDP snapshot `[x,y,w,h]` rects overlap on both axes. */
33
+ declare function snapshotRectsOverlap(a: SnapshotRect, b: SnapshotRect): boolean;
34
+ /** Assert that every rect shares one named edge with the first rect. */
35
+ declare function sharedEdges(rects: readonly RectBox[], edge: RectEdge, options?: {
36
+ tolerance?: number;
37
+ }): GeometryVerdict;
38
+ /** Consecutive edge-to-edge gaps, after sorting rects along the requested axis. */
39
+ declare function gaps(rects: readonly RectBox[], axis: RectAxis): number[];
40
+ /** Assert that consecutive rect gaps have no more than the requested spread. */
41
+ declare function evenSpacing(rects: readonly RectBox[], axis: RectAxis, options?: {
42
+ tolerance?: number;
43
+ }): GeometryVerdict;
44
+
45
+ export { type GeometryVerdict, type RectAxis, type RectBox, type RectEdge, type SnapshotRect, axisEdges, axisGap, evenSpacing, gaps, rectsOverlap, sharedEdges, snapshotRectsOverlap };
@@ -0,0 +1,79 @@
1
+ function axisEdges(rect, axis) {
2
+ return axis === "horizontal" ? { leading: rect.left, trailing: rect.right } : { leading: rect.top, trailing: rect.bottom };
3
+ }
4
+ function axisGap(first, second, axis) {
5
+ const a = axisEdges(first, axis);
6
+ const b = axisEdges(second, axis);
7
+ const [earlier, later] = a.leading <= b.leading ? [a, b] : [b, a];
8
+ return later.leading - earlier.trailing;
9
+ }
10
+ function rectsOverlap(a, b) {
11
+ return Boolean(
12
+ a && b && a.left < b.right && a.right > b.left && a.top < b.bottom && a.bottom > b.top
13
+ );
14
+ }
15
+ function snapshotRectsOverlap(a, b) {
16
+ return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;
17
+ }
18
+ function sharedEdges(rects, edge, options = {}) {
19
+ const tolerance = options.tolerance ?? 1;
20
+ if (rects.length < 2) {
21
+ return {
22
+ pass: false,
23
+ message: "sharedEdges requires at least two rects.",
24
+ details: { count: rects.length, edge, tolerance }
25
+ };
26
+ }
27
+ const expected = rects[0][edge];
28
+ const deltas = rects.slice(1).map((rect) => Math.abs(rect[edge] - expected));
29
+ const maximumDelta = Math.max(...deltas);
30
+ const pass = maximumDelta <= tolerance;
31
+ return {
32
+ pass,
33
+ message: pass ? `All rects share the ${edge} edge within ${tolerance}px.` : `Rects do not share the ${edge} edge within ${tolerance}px (maximum delta ${maximumDelta.toFixed(2)}px).`,
34
+ details: { edge, tolerance, expected, deltas, maximumDelta }
35
+ };
36
+ }
37
+ function gaps(rects, axis) {
38
+ const sorted = [...rects].sort(
39
+ (a, b) => axisEdges(a, axis).leading - axisEdges(b, axis).leading
40
+ );
41
+ return sorted.slice(1).map((rect, index) => axisGap(sorted[index], rect, axis));
42
+ }
43
+ function evenSpacing(rects, axis, options = {}) {
44
+ const tolerance = options.tolerance ?? 1;
45
+ if (rects.length < 3) {
46
+ return {
47
+ pass: false,
48
+ message: `evenSpacing requires at least three rects, got ${rects.length}.`,
49
+ details: { count: rects.length, axis, tolerance }
50
+ };
51
+ }
52
+ const measuredGaps = gaps(rects, axis);
53
+ const widest = Math.max(...measuredGaps);
54
+ const narrowest = Math.min(...measuredGaps);
55
+ const spread = widest - narrowest;
56
+ const pass = spread <= tolerance;
57
+ return {
58
+ pass,
59
+ message: pass ? `Rects are evenly spaced along ${axis} within ${tolerance}px.` : `Rects are not evenly spaced along ${axis}: gap spread ${spread.toFixed(2)}px exceeds ${tolerance}px.`,
60
+ details: {
61
+ axis,
62
+ tolerance,
63
+ gaps: measuredGaps,
64
+ widest,
65
+ narrowest,
66
+ spread
67
+ }
68
+ };
69
+ }
70
+ export {
71
+ axisEdges,
72
+ axisGap,
73
+ evenSpacing,
74
+ gaps,
75
+ rectsOverlap,
76
+ sharedEdges,
77
+ snapshotRectsOverlap
78
+ };
79
+ //# sourceMappingURL=geometry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/testing/geometry.ts"],"sourcesContent":["export type RectAxis = 'horizontal' | 'vertical';\n\nexport interface RectBox {\n top: number;\n left: number;\n right: number;\n bottom: number;\n width: number;\n height: number;\n}\n\nexport interface SnapshotRect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface GeometryVerdict {\n pass: boolean;\n message: string;\n details?: Record<string, unknown>;\n}\n\nexport type RectEdge = 'left' | 'right' | 'top' | 'bottom';\n\nexport function axisEdges(\n rect: RectBox,\n axis: RectAxis,\n): { leading: number; trailing: number } {\n return axis === 'horizontal'\n ? { leading: rect.left, trailing: rect.right }\n : { leading: rect.top, trailing: rect.bottom };\n}\n\n/**\n * Edge-to-edge gap between two border boxes. The box with the smaller leading\n * edge is treated as the earlier box, so negative values mean overlap.\n */\nexport function axisGap(first: RectBox, second: RectBox, axis: RectAxis): number {\n const a = axisEdges(first, axis);\n const b = axisEdges(second, axis);\n const [earlier, later] = a.leading <= b.leading ? [a, b] : [b, a];\n return later.leading - earlier.trailing;\n}\n\nexport function rectsOverlap(\n a: RectBox | null | undefined,\n b: RectBox | null | undefined,\n): boolean {\n return Boolean(\n a && b\n && a.left < b.right && a.right > b.left\n && a.top < b.bottom && a.bottom > b.top,\n );\n}\n\n/** Two CDP snapshot `[x,y,w,h]` rects overlap on both axes. */\nexport function snapshotRectsOverlap(a: SnapshotRect, b: SnapshotRect): boolean {\n return a.x < b.x + b.w\n && a.x + a.w > b.x\n && a.y < b.y + b.h\n && a.y + a.h > b.y;\n}\n\n/** Assert that every rect shares one named edge with the first rect. */\nexport function sharedEdges(\n rects: readonly RectBox[],\n edge: RectEdge,\n options: { tolerance?: number } = {},\n): GeometryVerdict {\n const tolerance = options.tolerance ?? 1;\n if (rects.length < 2) {\n return {\n pass: false,\n message: 'sharedEdges requires at least two rects.',\n details: { count: rects.length, edge, tolerance },\n };\n }\n\n const expected = rects[0][edge];\n const deltas = rects.slice(1).map((rect) => Math.abs(rect[edge] - expected));\n const maximumDelta = Math.max(...deltas);\n const pass = maximumDelta <= tolerance;\n return {\n pass,\n message: pass\n ? `All rects share the ${edge} edge within ${tolerance}px.`\n : `Rects do not share the ${edge} edge within ${tolerance}px (maximum delta ${maximumDelta.toFixed(2)}px).`,\n details: { edge, tolerance, expected, deltas, maximumDelta },\n };\n}\n\n/** Consecutive edge-to-edge gaps, after sorting rects along the requested axis. */\nexport function gaps(rects: readonly RectBox[], axis: RectAxis): number[] {\n const sorted = [...rects].sort(\n (a, b) => axisEdges(a, axis).leading - axisEdges(b, axis).leading,\n );\n return sorted.slice(1).map((rect, index) => axisGap(sorted[index], rect, axis));\n}\n\n/** Assert that consecutive rect gaps have no more than the requested spread. */\nexport function evenSpacing(\n rects: readonly RectBox[],\n axis: RectAxis,\n options: { tolerance?: number } = {},\n): GeometryVerdict {\n const tolerance = options.tolerance ?? 1;\n if (rects.length < 3) {\n return {\n pass: false,\n message: `evenSpacing requires at least three rects, got ${rects.length}.`,\n details: { count: rects.length, axis, tolerance },\n };\n }\n\n const measuredGaps = gaps(rects, axis);\n const widest = Math.max(...measuredGaps);\n const narrowest = Math.min(...measuredGaps);\n const spread = widest - narrowest;\n const pass = spread <= tolerance;\n return {\n pass,\n message: pass\n ? `Rects are evenly spaced along ${axis} within ${tolerance}px.`\n : `Rects are not evenly spaced along ${axis}: gap spread ${spread.toFixed(2)}px exceeds ${tolerance}px.`,\n details: {\n axis,\n tolerance,\n gaps: measuredGaps,\n widest,\n narrowest,\n spread,\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -25,6 +25,7 @@ __export(testing_exports, {
25
25
  RouterBridgeEvents: () => import_create_router_bridge.RouterBridgeEvents,
26
26
  TraceRecorder: () => import_trace_testing.TraceRecorder,
27
27
  assertLoopbackSerializable: () => import_transport.assertLoopbackSerializable,
28
+ automationAssertions: () => import_automation_assertions.automationAssertions,
28
29
  browser: () => import_browser.browser,
29
30
  buildTransportBridge: () => import_transport.buildTransportBridge,
30
31
  createBrowserBridgeFixture: () => import_browser.createBrowserBridgeFixture,
@@ -32,8 +33,21 @@ __export(testing_exports, {
32
33
  createRouterBridge: () => import_create_router_bridge.createRouterBridge,
33
34
  createTestContainer: () => import_create_test_container.createTestContainer,
34
35
  createTestRouter: () => import_create_test_router.createTestRouter,
36
+ evenSpacing: () => import_automation_assertions.evenSpacing,
37
+ evenSpacingRects: () => import_automation_assertions.evenSpacingRects,
38
+ gaps: () => import_automation_assertions.gaps,
35
39
  getElectronMockFactory: () => import_mock_electron.getElectronMockFactory,
36
- mockElectron: () => import_mock_electron.mockElectron
40
+ hidden: () => import_automation_assertions.hidden,
41
+ hitTestReachable: () => import_automation_assertions.hitTestReachable,
42
+ insideViewport: () => import_automation_assertions.insideViewport,
43
+ mockElectron: () => import_mock_electron.mockElectron,
44
+ notClipped: () => import_automation_assertions.notClipped,
45
+ notOverlapping: () => import_automation_assertions.notOverlapping,
46
+ rectsOverlap: () => import_automation_assertions.rectsOverlap,
47
+ sharedEdges: () => import_automation_assertions.sharedEdges,
48
+ sharedRectEdges: () => import_automation_assertions.sharedRectEdges,
49
+ stableAfterAnimation: () => import_automation_assertions.stableAfterAnimation,
50
+ visible: () => import_automation_assertions.visible
37
51
  });
38
52
  module.exports = __toCommonJS(testing_exports);
39
53
  var import_create_test_container = require("./create_test_container.js");
@@ -42,6 +56,7 @@ var import_create_test_router = require("./create_test_router.js");
42
56
  var import_mock_electron = require("./mock_electron.js");
43
57
  var import_create_router_bridge = require("./create_router_bridge.js");
44
58
  var import_browser = require("./browser.js");
59
+ var import_automation_assertions = require("./automation_assertions.js");
45
60
  var import_transport = require("../transport/index.js");
46
61
  var import_trace_testing = require("../trace-testing/index.js");
47
62
  // Annotate the CommonJS export names for ESM import in node:
@@ -53,6 +68,7 @@ var import_trace_testing = require("../trace-testing/index.js");
53
68
  RouterBridgeEvents,
54
69
  TraceRecorder,
55
70
  assertLoopbackSerializable,
71
+ automationAssertions,
56
72
  browser,
57
73
  buildTransportBridge,
58
74
  createBrowserBridgeFixture,
@@ -60,7 +76,20 @@ var import_trace_testing = require("../trace-testing/index.js");
60
76
  createRouterBridge,
61
77
  createTestContainer,
62
78
  createTestRouter,
79
+ evenSpacing,
80
+ evenSpacingRects,
81
+ gaps,
63
82
  getElectronMockFactory,
64
- mockElectron
83
+ hidden,
84
+ hitTestReachable,
85
+ insideViewport,
86
+ mockElectron,
87
+ notClipped,
88
+ notOverlapping,
89
+ rectsOverlap,
90
+ sharedEdges,
91
+ sharedRectEdges,
92
+ stableAfterAnimation,
93
+ visible
65
94
  });
66
95
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/testing/index.ts"],"sourcesContent":["export { createTestContainer } from './create_test_container.js';\nexport {\n createControllerHarness,\n type ControllerHarnessResult,\n type CreateControllerHarnessOptions,\n} from './create_controller_harness.js';\nexport { createTestRouter, type TestRouterResult } from './create_test_router.js';\nexport { mockElectron, getElectronMockFactory } from './mock_electron.js';\nexport {\n createRouterBridge,\n RouterBridgeEvents,\n type RouterBridgeResult,\n} from './create_router_bridge.js';\nexport {\n browser,\n createBrowserBridgeFixture,\n type MountedWoodBridge,\n type MountedWoodComponent,\n type MountedWoodNavigation,\n type MountedWoodRoute,\n type MountedWoodSurface,\n type MountedWoodTree,\n type MountComponentOptions,\n type MountRouteOptions,\n type MountTreeOptions,\n type WoodBridgeFixtureContext,\n type WoodBridgeFixtureInput,\n type WoodBridgeRecordedCall,\n type WoodBridgeRecordedEvent,\n type WoodRpcManifestEntryInput,\n type WoodBrowserExpect,\n type WoodHitTestResult,\n type WoodRectSnapshot,\n type WoodBrowserHarness,\n type WoodBrowserHarnessConfig,\n type WoodBrowserPageContext,\n type WoodBrowserTraceConfig,\n type WoodViewport,\n} from './browser.js';\nexport {\n InProcessRouterTransport,\n LoopbackRemoteTransport,\n LoopbackRemoteTransportServer,\n assertLoopbackSerializable,\n LoopbackSerializationError,\n buildTransportBridge,\n type WoodRpcTransport,\n type WoodChannelContract,\n type WoodChannelMapLike,\n type WoodChannelInput,\n type WoodChannelOutput,\n type TypedCall,\n type TransportBridgeResult,\n} from '../transport/index.js';\nexport { TraceRecorder } from '../trace-testing/index.js';\nexport type {\n TraceDispatchResult,\n TraceEvent,\n TraceInput,\n TraceWaitOptions,\n} from '../tracing/index.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAAoC;AACpC,uCAIO;AACP,gCAAwD;AACxD,2BAAqD;AACrD,kCAIO;AACP,qBAyBO;AACP,uBAcO;AACP,2BAA8B;","names":[]}
1
+ {"version":3,"sources":["../../src/testing/index.ts"],"sourcesContent":["export { createTestContainer } from './create_test_container.js';\nexport {\n createControllerHarness,\n type ControllerHarnessResult,\n type CreateControllerHarnessOptions,\n} from './create_controller_harness.js';\nexport { createTestRouter, type TestRouterResult } from './create_test_router.js';\nexport { mockElectron, getElectronMockFactory } from './mock_electron.js';\nexport {\n createRouterBridge,\n RouterBridgeEvents,\n type RouterBridgeResult,\n} from './create_router_bridge.js';\nexport {\n browser,\n createBrowserBridgeFixture,\n type MountedWoodBridge,\n type MountedWoodComponent,\n type MountedWoodNavigation,\n type MountedWoodRoute,\n type MountedWoodSurface,\n type MountedWoodTree,\n type MountComponentOptions,\n type MountRouteOptions,\n type MountTreeOptions,\n type WoodBridgeFixtureContext,\n type WoodBridgeFixtureInput,\n type WoodBridgeRecordedCall,\n type WoodBridgeRecordedEvent,\n type WoodRpcManifestEntryInput,\n type WoodBrowserExpect,\n type WoodHitTestResult,\n type WoodRectSnapshot,\n type WoodBrowserHarness,\n type WoodBrowserHarnessConfig,\n type WoodBrowserPageContext,\n type WoodBrowserTraceConfig,\n type WoodViewport,\n} from './browser.js';\nexport {\n automationAssertions,\n visible,\n hidden,\n insideViewport,\n notClipped,\n notOverlapping,\n hitTestReachable,\n sharedEdges,\n evenSpacing,\n stableAfterAnimation,\n rectsOverlap,\n gaps,\n sharedRectEdges,\n evenSpacingRects,\n type AssertionVerdict,\n type AutomationTarget,\n type AutomationRectTarget,\n type GeometryVerdict,\n type RectAxis,\n type RectBox,\n type RectEdge,\n} from './automation_assertions.js';\nexport {\n InProcessRouterTransport,\n LoopbackRemoteTransport,\n LoopbackRemoteTransportServer,\n assertLoopbackSerializable,\n LoopbackSerializationError,\n buildTransportBridge,\n type WoodRpcTransport,\n type WoodChannelContract,\n type WoodChannelMapLike,\n type WoodChannelInput,\n type WoodChannelOutput,\n type TypedCall,\n type TransportBridgeResult,\n} from '../transport/index.js';\nexport { TraceRecorder } from '../trace-testing/index.js';\nexport type {\n TraceDispatchResult,\n TraceEvent,\n TraceInput,\n TraceWaitOptions,\n} from '../tracing/index.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAAoC;AACpC,uCAIO;AACP,gCAAwD;AACxD,2BAAqD;AACrD,kCAIO;AACP,qBAyBO;AACP,mCAsBO;AACP,uBAcO;AACP,2BAA8B;","names":[]}
@@ -4,6 +4,7 @@ export { TestRouterResult, createTestRouter } from './create_test_router.cjs';
4
4
  export { getElectronMockFactory, mockElectron } from './mock_electron.cjs';
5
5
  export { RouterBridgeEvents, RouterBridgeResult, createRouterBridge } from './create_router_bridge.cjs';
6
6
  export { MountComponentOptions, MountRouteOptions, MountTreeOptions, MountedWoodBridge, MountedWoodComponent, MountedWoodNavigation, MountedWoodRoute, MountedWoodSurface, MountedWoodTree, WoodBridgeFixtureContext, WoodBridgeFixtureInput, WoodBridgeRecordedCall, WoodBridgeRecordedEvent, WoodBrowserExpect, WoodBrowserHarness, WoodBrowserHarnessConfig, WoodBrowserPageContext, WoodBrowserTraceConfig, WoodHitTestResult, WoodRectSnapshot, WoodRpcManifestEntryInput, WoodViewport, browser, createBrowserBridgeFixture } from './browser.cjs';
7
+ export { AssertionVerdict, AutomationRectTarget, AutomationTarget, automationAssertions, evenSpacing, hidden, hitTestReachable, insideViewport, notClipped, notOverlapping, sharedEdges, stableAfterAnimation, visible } from './automation_assertions.cjs';
7
8
  export { TypedCall, WoodChannelContract, WoodChannelInput, WoodChannelMapLike, WoodChannelOutput, WoodRpcTransport } from '../transport/wood_rpc_transport.cjs';
8
9
  export { InProcessRouterTransport } from '../transport/in_process_router_transport.cjs';
9
10
  export { LoopbackRemoteTransport, LoopbackRemoteTransportServer } from '../transport/loopback_remote_transport.cjs';
@@ -11,9 +12,12 @@ export { LoopbackSerializationError, assertLoopbackSerializable } from '../trans
11
12
  export { TransportBridgeResult, buildTransportBridge } from '../transport/build_transport_bridge.cjs';
12
13
  export { TraceRecorder } from '../trace-testing/trace_recorder.cjs';
13
14
  export { T as TraceDispatchResult, a as TraceEvent, b as TraceInput, f as TraceWaitOptions } from '../trace_hub-Cob54qRx.cjs';
15
+ export { GeometryVerdict, RectAxis, RectBox, RectEdge, evenSpacing as evenSpacingRects, gaps, rectsOverlap, sharedEdges as sharedRectEdges } from './geometry.cjs';
14
16
  import '../navigation/index.cjs';
17
+ import '../navigation/automation_introspection.cjs';
15
18
  import '../router/wood_router.cjs';
16
19
  import '../types/operations.cjs';
20
+ import 'playwright';
17
21
  import '@noego/trace/testing';
18
22
  import '../tracing/trace_provider.cjs';
19
23
  import '@noego/ioc';
@@ -4,6 +4,7 @@ export { TestRouterResult, createTestRouter } from './create_test_router.js';
4
4
  export { getElectronMockFactory, mockElectron } from './mock_electron.js';
5
5
  export { RouterBridgeEvents, RouterBridgeResult, createRouterBridge } from './create_router_bridge.js';
6
6
  export { MountComponentOptions, MountRouteOptions, MountTreeOptions, MountedWoodBridge, MountedWoodComponent, MountedWoodNavigation, MountedWoodRoute, MountedWoodSurface, MountedWoodTree, WoodBridgeFixtureContext, WoodBridgeFixtureInput, WoodBridgeRecordedCall, WoodBridgeRecordedEvent, WoodBrowserExpect, WoodBrowserHarness, WoodBrowserHarnessConfig, WoodBrowserPageContext, WoodBrowserTraceConfig, WoodHitTestResult, WoodRectSnapshot, WoodRpcManifestEntryInput, WoodViewport, browser, createBrowserBridgeFixture } from './browser.js';
7
+ export { AssertionVerdict, AutomationRectTarget, AutomationTarget, automationAssertions, evenSpacing, hidden, hitTestReachable, insideViewport, notClipped, notOverlapping, sharedEdges, stableAfterAnimation, visible } from './automation_assertions.js';
7
8
  export { TypedCall, WoodChannelContract, WoodChannelInput, WoodChannelMapLike, WoodChannelOutput, WoodRpcTransport } from '../transport/wood_rpc_transport.js';
8
9
  export { InProcessRouterTransport } from '../transport/in_process_router_transport.js';
9
10
  export { LoopbackRemoteTransport, LoopbackRemoteTransportServer } from '../transport/loopback_remote_transport.js';
@@ -11,9 +12,12 @@ export { LoopbackSerializationError, assertLoopbackSerializable } from '../trans
11
12
  export { TransportBridgeResult, buildTransportBridge } from '../transport/build_transport_bridge.js';
12
13
  export { TraceRecorder } from '../trace-testing/trace_recorder.js';
13
14
  export { T as TraceDispatchResult, a as TraceEvent, b as TraceInput, f as TraceWaitOptions } from '../trace_hub-Cob54qRx.js';
15
+ export { GeometryVerdict, RectAxis, RectBox, RectEdge, evenSpacing as evenSpacingRects, gaps, rectsOverlap, sharedEdges as sharedRectEdges } from './geometry.js';
14
16
  import '../navigation/index.js';
17
+ import '../navigation/automation_introspection.js';
15
18
  import '../router/wood_router.js';
16
19
  import '../types/operations.js';
20
+ import 'playwright';
17
21
  import '@noego/trace/testing';
18
22
  import '../tracing/trace_provider.js';
19
23
  import '@noego/ioc';
@@ -12,6 +12,22 @@ import {
12
12
  browser,
13
13
  createBrowserBridgeFixture
14
14
  } from "./browser.js";
15
+ import {
16
+ automationAssertions,
17
+ visible,
18
+ hidden,
19
+ insideViewport,
20
+ notClipped,
21
+ notOverlapping,
22
+ hitTestReachable,
23
+ sharedEdges,
24
+ evenSpacing,
25
+ stableAfterAnimation,
26
+ rectsOverlap,
27
+ gaps,
28
+ sharedRectEdges,
29
+ evenSpacingRects
30
+ } from "./automation_assertions.js";
15
31
  import {
16
32
  InProcessRouterTransport,
17
33
  LoopbackRemoteTransport,
@@ -29,6 +45,7 @@ export {
29
45
  RouterBridgeEvents,
30
46
  TraceRecorder,
31
47
  assertLoopbackSerializable,
48
+ automationAssertions,
32
49
  browser,
33
50
  buildTransportBridge,
34
51
  createBrowserBridgeFixture,
@@ -36,7 +53,20 @@ export {
36
53
  createRouterBridge,
37
54
  createTestContainer,
38
55
  createTestRouter,
56
+ evenSpacing,
57
+ evenSpacingRects,
58
+ gaps,
39
59
  getElectronMockFactory,
40
- mockElectron
60
+ hidden,
61
+ hitTestReachable,
62
+ insideViewport,
63
+ mockElectron,
64
+ notClipped,
65
+ notOverlapping,
66
+ rectsOverlap,
67
+ sharedEdges,
68
+ sharedRectEdges,
69
+ stableAfterAnimation,
70
+ visible
41
71
  };
42
72
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/testing/index.ts"],"sourcesContent":["export { createTestContainer } from './create_test_container.js';\nexport {\n createControllerHarness,\n type ControllerHarnessResult,\n type CreateControllerHarnessOptions,\n} from './create_controller_harness.js';\nexport { createTestRouter, type TestRouterResult } from './create_test_router.js';\nexport { mockElectron, getElectronMockFactory } from './mock_electron.js';\nexport {\n createRouterBridge,\n RouterBridgeEvents,\n type RouterBridgeResult,\n} from './create_router_bridge.js';\nexport {\n browser,\n createBrowserBridgeFixture,\n type MountedWoodBridge,\n type MountedWoodComponent,\n type MountedWoodNavigation,\n type MountedWoodRoute,\n type MountedWoodSurface,\n type MountedWoodTree,\n type MountComponentOptions,\n type MountRouteOptions,\n type MountTreeOptions,\n type WoodBridgeFixtureContext,\n type WoodBridgeFixtureInput,\n type WoodBridgeRecordedCall,\n type WoodBridgeRecordedEvent,\n type WoodRpcManifestEntryInput,\n type WoodBrowserExpect,\n type WoodHitTestResult,\n type WoodRectSnapshot,\n type WoodBrowserHarness,\n type WoodBrowserHarnessConfig,\n type WoodBrowserPageContext,\n type WoodBrowserTraceConfig,\n type WoodViewport,\n} from './browser.js';\nexport {\n InProcessRouterTransport,\n LoopbackRemoteTransport,\n LoopbackRemoteTransportServer,\n assertLoopbackSerializable,\n LoopbackSerializationError,\n buildTransportBridge,\n type WoodRpcTransport,\n type WoodChannelContract,\n type WoodChannelMapLike,\n type WoodChannelInput,\n type WoodChannelOutput,\n type TypedCall,\n type TransportBridgeResult,\n} from '../transport/index.js';\nexport { TraceRecorder } from '../trace-testing/index.js';\nexport type {\n TraceDispatchResult,\n TraceEvent,\n TraceInput,\n TraceWaitOptions,\n} from '../tracing/index.js';\n"],"mappings":"AAAA,SAAS,2BAA2B;AACpC;AAAA,EACE;AAAA,OAGK;AACP,SAAS,wBAA+C;AACxD,SAAS,cAAc,8BAA8B;AACrD;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAuBK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAQK;AACP,SAAS,qBAAqB;","names":[]}
1
+ {"version":3,"sources":["../../src/testing/index.ts"],"sourcesContent":["export { createTestContainer } from './create_test_container.js';\nexport {\n createControllerHarness,\n type ControllerHarnessResult,\n type CreateControllerHarnessOptions,\n} from './create_controller_harness.js';\nexport { createTestRouter, type TestRouterResult } from './create_test_router.js';\nexport { mockElectron, getElectronMockFactory } from './mock_electron.js';\nexport {\n createRouterBridge,\n RouterBridgeEvents,\n type RouterBridgeResult,\n} from './create_router_bridge.js';\nexport {\n browser,\n createBrowserBridgeFixture,\n type MountedWoodBridge,\n type MountedWoodComponent,\n type MountedWoodNavigation,\n type MountedWoodRoute,\n type MountedWoodSurface,\n type MountedWoodTree,\n type MountComponentOptions,\n type MountRouteOptions,\n type MountTreeOptions,\n type WoodBridgeFixtureContext,\n type WoodBridgeFixtureInput,\n type WoodBridgeRecordedCall,\n type WoodBridgeRecordedEvent,\n type WoodRpcManifestEntryInput,\n type WoodBrowserExpect,\n type WoodHitTestResult,\n type WoodRectSnapshot,\n type WoodBrowserHarness,\n type WoodBrowserHarnessConfig,\n type WoodBrowserPageContext,\n type WoodBrowserTraceConfig,\n type WoodViewport,\n} from './browser.js';\nexport {\n automationAssertions,\n visible,\n hidden,\n insideViewport,\n notClipped,\n notOverlapping,\n hitTestReachable,\n sharedEdges,\n evenSpacing,\n stableAfterAnimation,\n rectsOverlap,\n gaps,\n sharedRectEdges,\n evenSpacingRects,\n type AssertionVerdict,\n type AutomationTarget,\n type AutomationRectTarget,\n type GeometryVerdict,\n type RectAxis,\n type RectBox,\n type RectEdge,\n} from './automation_assertions.js';\nexport {\n InProcessRouterTransport,\n LoopbackRemoteTransport,\n LoopbackRemoteTransportServer,\n assertLoopbackSerializable,\n LoopbackSerializationError,\n buildTransportBridge,\n type WoodRpcTransport,\n type WoodChannelContract,\n type WoodChannelMapLike,\n type WoodChannelInput,\n type WoodChannelOutput,\n type TypedCall,\n type TransportBridgeResult,\n} from '../transport/index.js';\nexport { TraceRecorder } from '../trace-testing/index.js';\nexport type {\n TraceDispatchResult,\n TraceEvent,\n TraceInput,\n TraceWaitOptions,\n} from '../tracing/index.js';\n"],"mappings":"AAAA,SAAS,2BAA2B;AACpC;AAAA,EACE;AAAA,OAGK;AACP,SAAS,wBAA+C;AACxD,SAAS,cAAc,8BAA8B;AACrD;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAuBK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAQK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAQK;AACP,SAAS,qBAAqB;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noego/wood",
3
- "version": "0.4.9",
3
+ "version": "0.4.10",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -99,6 +99,12 @@
99
99
  "import": "./dist/stick/index.js",
100
100
  "default": "./dist/stick/index.js"
101
101
  },
102
+ "./automation": {
103
+ "types": "./dist/automation/index.d.ts",
104
+ "require": "./dist/automation/index.cjs",
105
+ "import": "./dist/automation/index.js",
106
+ "default": "./dist/automation/index.js"
107
+ },
102
108
  "./dev": {
103
109
  "types": "./dist/dev/index.d.ts",
104
110
  "require": "./dist/dev/index.cjs",