@hubspot/ui-extensions 0.11.2 → 0.11.4

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 (215) hide show
  1. package/dist/__tests__/crm/hooks/useAssociations.spec.js +4 -4
  2. package/dist/__tests__/crm/hooks/useCrmProperties.spec.js +2 -2
  3. package/dist/__tests__/crm/utils/fetchAssociations.spec.js +5 -5
  4. package/dist/__tests__/crm/utils/fetchCrmProperties.spec.js +4 -4
  5. package/dist/clientTypes.d.ts +1 -0
  6. package/dist/clientTypes.js +1 -1
  7. package/dist/crm/hooks/useAssociations.d.ts +5 -3
  8. package/dist/crm/hooks/useAssociations.js +4 -2
  9. package/dist/crm/hooks/useCrmProperties.d.ts +4 -2
  10. package/dist/crm/hooks/useCrmProperties.js +4 -2
  11. package/dist/crm/index.d.ts +4 -4
  12. package/dist/crm/index.js +3 -3
  13. package/dist/crm/utils/fetchAssociations.d.ts +1 -1
  14. package/dist/experimental/index.d.ts +4 -4
  15. package/dist/experimental/index.js +3 -3
  16. package/dist/experimental/testing/__tests__/createRenderer.spec.js +23 -0
  17. package/dist/experimental/testing/__tests__/debug.spec.js +21 -7
  18. package/dist/experimental/testing/__tests__/find.spec.js +23 -8
  19. package/dist/experimental/testing/__tests__/findAll.spec.js +4 -3
  20. package/dist/experimental/testing/__tests__/findAllChildren.spec.js +14 -8
  21. package/dist/experimental/testing/__tests__/findByTestId.spec.js +126 -0
  22. package/dist/experimental/testing/__tests__/findChild.spec.js +11 -7
  23. package/dist/experimental/testing/__tests__/fragments.spec.js +17 -10
  24. package/dist/experimental/testing/__tests__/invalid-components.spec.js +16 -8
  25. package/dist/experimental/testing/__tests__/isMatch.spec.js +106 -53
  26. package/dist/experimental/testing/__tests__/logger.spec.js +10 -0
  27. package/dist/experimental/testing/__tests__/maybeFind.spec.js +20 -11
  28. package/dist/experimental/testing/__tests__/maybeFindByTestId.spec.js +65 -0
  29. package/dist/experimental/testing/__tests__/maybeFindChild.spec.js +22 -12
  30. package/dist/experimental/testing/__tests__/mocks.actions.spec.js +19 -0
  31. package/dist/experimental/testing/__tests__/mocks.context.spec.js +24 -0
  32. package/dist/experimental/testing/__tests__/mocks.runServerlessFunction.spec.js +35 -0
  33. package/dist/experimental/testing/__tests__/mocks.useAssociations.spec.js +47 -0
  34. package/dist/experimental/testing/__tests__/mocks.useCrmProperties.spec.js +58 -0
  35. package/dist/experimental/testing/__tests__/props.spec.js +13 -0
  36. package/dist/experimental/testing/__tests__/testId.spec.js +18 -0
  37. package/dist/experimental/testing/__tests__/trigger.spec.js +9 -6
  38. package/dist/experimental/testing/__tests__/type-utils.spec.js +12 -10
  39. package/dist/experimental/testing/__tests__/waitFor.spec.js +7 -5
  40. package/dist/experimental/testing/index.d.ts +4 -3
  41. package/dist/experimental/testing/index.js +4 -3
  42. package/dist/experimental/testing/internal/constants.d.ts +2 -2
  43. package/dist/experimental/testing/internal/constants.js +1 -1
  44. package/dist/experimental/testing/internal/convert.d.ts +2 -2
  45. package/dist/experimental/testing/internal/convert.js +42 -24
  46. package/dist/experimental/testing/internal/debug.d.ts +3 -3
  47. package/dist/experimental/testing/internal/debug.js +4 -5
  48. package/dist/experimental/testing/internal/document.d.ts +1 -1
  49. package/dist/experimental/testing/internal/document.js +4 -1
  50. package/dist/experimental/testing/internal/element.d.ts +4 -3
  51. package/dist/experimental/testing/internal/element.js +15 -10
  52. package/dist/experimental/testing/internal/errors.d.ts +45 -2
  53. package/dist/experimental/testing/internal/errors.js +44 -2
  54. package/dist/experimental/testing/internal/fragment.d.ts +3 -2
  55. package/dist/experimental/testing/internal/fragment.js +13 -9
  56. package/dist/experimental/testing/internal/match.d.ts +3 -12
  57. package/dist/experimental/testing/internal/match.js +0 -23
  58. package/dist/experimental/testing/internal/mocks/index.d.ts +17 -0
  59. package/dist/experimental/testing/internal/mocks/index.js +46 -0
  60. package/dist/experimental/testing/internal/mocks/mock-extension-point-api.d.ts +2 -0
  61. package/dist/experimental/testing/internal/mocks/mock-extension-point-api.js +166 -0
  62. package/dist/experimental/testing/internal/mocks/mock-hooks.d.ts +2 -0
  63. package/dist/experimental/testing/internal/mocks/mock-hooks.js +59 -0
  64. package/dist/experimental/testing/internal/print.d.ts +2 -2
  65. package/dist/experimental/testing/internal/print.js +17 -11
  66. package/dist/experimental/testing/internal/query.d.ts +19 -9
  67. package/dist/experimental/testing/internal/query.js +91 -28
  68. package/dist/experimental/testing/internal/root.d.ts +1 -1
  69. package/dist/experimental/testing/internal/root.js +12 -8
  70. package/dist/experimental/testing/internal/text.d.ts +3 -2
  71. package/dist/experimental/testing/internal/text.js +12 -3
  72. package/dist/experimental/testing/internal/type-utils-internal.d.ts +44 -0
  73. package/dist/experimental/testing/internal/type-utils-internal.js +54 -0
  74. package/dist/experimental/testing/internal/types-internal.d.ts +20 -2
  75. package/dist/experimental/testing/render.d.ts +32 -6
  76. package/dist/experimental/testing/render.js +96 -32
  77. package/dist/experimental/testing/type-utils.d.ts +2 -2
  78. package/dist/experimental/testing/type-utils.js +1 -1
  79. package/dist/experimental/testing/types.d.ts +127 -10
  80. package/dist/experimental/testing/utils.d.ts +11 -0
  81. package/dist/experimental/testing/utils.js +24 -0
  82. package/dist/hubspot.d.ts +2 -4
  83. package/dist/hubspot.js +3 -3
  84. package/dist/index.d.ts +5 -5
  85. package/dist/index.js +5 -5
  86. package/dist/internal/global-utils.d.ts +6 -0
  87. package/dist/internal/global-utils.js +37 -0
  88. package/dist/internal/hook-utils.d.ts +19 -0
  89. package/dist/internal/hook-utils.js +34 -0
  90. package/dist/logger.d.ts +1 -8
  91. package/dist/logger.js +3 -2
  92. package/dist/pages/home/index.d.ts +1 -1
  93. package/dist/pages/home/index.js +1 -1
  94. package/dist/{__synced__/remoteComponents.synced.d.ts → shared/remoteComponents.d.ts} +103 -103
  95. package/dist/{__synced__/remoteComponents.synced.js → shared/remoteComponents.js} +1 -1
  96. package/dist/{__synced__/types/components/accordion.synced.d.ts → shared/types/components/accordion.d.ts} +2 -2
  97. package/dist/{__synced__/types/components/alert.synced.d.ts → shared/types/components/alert.d.ts} +2 -1
  98. package/dist/{__synced__/types/components/app-home-header-actions.synced.d.ts → shared/types/components/app-home-header-actions.d.ts} +4 -4
  99. package/dist/{__synced__/types/components/button-row.synced.d.ts → shared/types/components/button-row.d.ts} +2 -2
  100. package/dist/{__synced__/types/components/button.synced.d.ts → shared/types/components/button.d.ts} +3 -3
  101. package/dist/{__synced__/types/components/card.synced.d.ts → shared/types/components/card.d.ts} +2 -1
  102. package/dist/{__synced__/types/components/chart.synced.d.ts → shared/types/components/chart.d.ts} +2 -1
  103. package/dist/{__synced__/types/components/description-list.synced.d.ts → shared/types/components/description-list.d.ts} +3 -2
  104. package/dist/{__synced__/types/components/divider.synced.d.ts → shared/types/components/divider.d.ts} +2 -2
  105. package/dist/{__synced__/types/components/dropdown.synced.d.ts → shared/types/components/dropdown.d.ts} +5 -5
  106. package/dist/{__synced__/types/components/empty-state.synced.d.ts → shared/types/components/empty-state.d.ts} +2 -1
  107. package/dist/{__synced__/types/components/error-state.synced.d.ts → shared/types/components/error-state.d.ts} +2 -1
  108. package/dist/{__synced__/types/components/form.synced.d.ts → shared/types/components/form.d.ts} +3 -3
  109. package/dist/{__synced__/types/components/heading.synced.d.ts → shared/types/components/heading.d.ts} +2 -1
  110. package/dist/{__synced__/types/components/icon.synced.d.ts → shared/types/components/icon.d.ts} +2 -2
  111. package/dist/{__synced__/types/components/iframe.synced.d.ts → shared/types/components/iframe.d.ts} +2 -2
  112. package/dist/{__synced__/types/components/illustration.synced.d.ts → shared/types/components/illustration.d.ts} +2 -1
  113. package/dist/{__synced__/types/components/image.synced.d.ts → shared/types/components/image.d.ts} +3 -3
  114. package/dist/shared/types/components/index.d.ts +38 -0
  115. package/dist/{__synced__/types/components/inputs.synced.d.ts → shared/types/components/inputs.d.ts} +2 -1
  116. package/dist/{__synced__/types/components/layouts.synced.d.ts → shared/types/components/layouts.d.ts} +6 -6
  117. package/dist/{__synced__/types/components/link.synced.d.ts → shared/types/components/link.d.ts} +3 -3
  118. package/dist/{__synced__/types/components/list.synced.d.ts → shared/types/components/list.d.ts} +2 -1
  119. package/dist/{__synced__/types/components/loading-spinner.synced.d.ts → shared/types/components/loading-spinner.d.ts} +2 -2
  120. package/dist/{__synced__/types/components/modal.synced.d.ts → shared/types/components/modal.d.ts} +4 -4
  121. package/dist/{__synced__/types/components/panel.synced.d.ts → shared/types/components/panel.d.ts} +5 -5
  122. package/dist/{__synced__/types/components/progress-bar.synced.d.ts → shared/types/components/progress-bar.d.ts} +2 -1
  123. package/dist/{__synced__/types/components/selects.synced.d.ts → shared/types/components/selects.d.ts} +2 -1
  124. package/dist/{__synced__/types/components/statistics.synced.d.ts → shared/types/components/statistics.d.ts} +4 -3
  125. package/dist/{__synced__/types/components/status-tag.synced.d.ts → shared/types/components/status-tag.d.ts} +2 -1
  126. package/dist/{__synced__/types/components/step-indicator.synced.d.ts → shared/types/components/step-indicator.d.ts} +2 -2
  127. package/dist/{__synced__/types/components/table.synced.d.ts → shared/types/components/table.d.ts} +5 -4
  128. package/dist/shared/types/components/table.js +1 -0
  129. package/dist/{__synced__/types/components/tabs.synced.d.ts → shared/types/components/tabs.d.ts} +3 -2
  130. package/dist/shared/types/components/tabs.js +1 -0
  131. package/dist/{__synced__/types/components/tag.synced.d.ts → shared/types/components/tag.d.ts} +3 -3
  132. package/dist/shared/types/components/tag.js +1 -0
  133. package/dist/{__synced__/types/components/text.synced.d.ts → shared/types/components/text.d.ts} +2 -1
  134. package/dist/shared/types/components/text.js +1 -0
  135. package/dist/{__synced__/types/components/tile.synced.d.ts → shared/types/components/tile.d.ts} +2 -1
  136. package/dist/shared/types/components/tile.js +1 -0
  137. package/dist/{__synced__/types/components/toggle.synced.d.ts → shared/types/components/toggle.d.ts} +2 -2
  138. package/dist/shared/types/components/toggle.js +1 -0
  139. package/dist/{__synced__/types/components/toggleInputs.synced.d.ts → shared/types/components/toggleInputs.d.ts} +4 -4
  140. package/dist/shared/types/components/toggleInputs.js +1 -0
  141. package/dist/{__synced__/types/components/tooltip.synced.d.ts → shared/types/components/tooltip.d.ts} +2 -1
  142. package/dist/shared/types/components/tooltip.js +1 -0
  143. package/dist/{__synced__/types/context.synced.d.ts → shared/types/context.d.ts} +1 -1
  144. package/dist/shared/types/context.js +1 -0
  145. package/dist/{__synced__/types/crm.synced.d.ts → shared/types/crm.d.ts} +13 -13
  146. package/dist/shared/types/crm.js +1 -0
  147. package/dist/{__synced__/experimental/types.synced.d.ts → shared/types/experimental.d.ts} +10 -14
  148. package/dist/shared/types/experimental.js +1 -0
  149. package/dist/shared/types/extend.d.ts +4 -0
  150. package/dist/shared/types/extend.js +1 -0
  151. package/dist/{__synced__/types/extension-points.synced.d.ts → shared/types/extension-points.d.ts} +18 -10
  152. package/dist/{__synced__/types/http-requests.synced.d.ts → shared/types/http-requests.d.ts} +1 -1
  153. package/dist/shared/types/index.d.ts +8 -0
  154. package/dist/shared/types/index.js +1 -0
  155. package/dist/shared/types/logger.d.ts +7 -0
  156. package/dist/shared/types/logger.js +1 -0
  157. package/dist/shared/types/reactions.js +1 -0
  158. package/dist/{__synced__/types/shared.synced.d.ts → shared/types/shared.d.ts} +3 -0
  159. package/dist/shared/types/worker-globals.d.ts +17 -0
  160. package/dist/shared/types/worker-globals.js +1 -0
  161. package/dist/{__synced__/utils/remote-component-registry.synced.d.ts → shared/utils/remote-component-registry.d.ts} +1 -1
  162. package/dist/{__synced__/utils/remote-component-registry.synced.js → shared/utils/remote-component-registry.js} +0 -1
  163. package/package.json +6 -4
  164. package/dist/__synced__/experimental/types.synced.js +0 -5
  165. package/dist/__synced__/types/components/index.synced.d.ts +0 -38
  166. package/dist/__synced__/types/index.synced.d.ts +0 -8
  167. package/dist/__synced__/types/index.synced.js +0 -1
  168. /package/dist/{__synced__/types/actions.synced.js → experimental/testing/__tests__/createRenderer.spec.d.ts} +0 -0
  169. /package/dist/{__synced__/types/components/accordion.synced.js → experimental/testing/__tests__/findByTestId.spec.d.ts} +0 -0
  170. /package/dist/{__synced__/types/components/alert.synced.js → experimental/testing/__tests__/logger.spec.d.ts} +0 -0
  171. /package/dist/{__synced__/types/components/app-home-header-actions.synced.js → experimental/testing/__tests__/maybeFindByTestId.spec.d.ts} +0 -0
  172. /package/dist/{__synced__/types/components/button-row.synced.js → experimental/testing/__tests__/mocks.actions.spec.d.ts} +0 -0
  173. /package/dist/{__synced__/types/components/button.synced.js → experimental/testing/__tests__/mocks.context.spec.d.ts} +0 -0
  174. /package/dist/{__synced__/types/components/card.synced.js → experimental/testing/__tests__/mocks.runServerlessFunction.spec.d.ts} +0 -0
  175. /package/dist/{__synced__/types/components/description-list.synced.js → experimental/testing/__tests__/mocks.useAssociations.spec.d.ts} +0 -0
  176. /package/dist/{__synced__/types/components/divider.synced.js → experimental/testing/__tests__/mocks.useCrmProperties.spec.d.ts} +0 -0
  177. /package/dist/{__synced__/types/components/dropdown.synced.js → experimental/testing/__tests__/props.spec.d.ts} +0 -0
  178. /package/dist/{__synced__/types/components/empty-state.synced.js → experimental/testing/__tests__/testId.spec.d.ts} +0 -0
  179. /package/dist/{__synced__/types/actions.synced.d.ts → shared/types/actions.d.ts} +0 -0
  180. /package/dist/{__synced__/types/components/error-state.synced.js → shared/types/actions.js} +0 -0
  181. /package/dist/{__synced__/types/components/form.synced.js → shared/types/components/accordion.js} +0 -0
  182. /package/dist/{__synced__/types/components/heading.synced.js → shared/types/components/alert.js} +0 -0
  183. /package/dist/{__synced__/types/components/icon.synced.js → shared/types/components/app-home-header-actions.js} +0 -0
  184. /package/dist/{__synced__/types/components/iframe.synced.js → shared/types/components/button-row.js} +0 -0
  185. /package/dist/{__synced__/types/components/image.synced.js → shared/types/components/button.js} +0 -0
  186. /package/dist/{__synced__/types/components/index.synced.js → shared/types/components/card.js} +0 -0
  187. /package/dist/{__synced__/types/components/chart.synced.js → shared/types/components/chart.js} +0 -0
  188. /package/dist/{__synced__/types/components/inputs.synced.js → shared/types/components/description-list.js} +0 -0
  189. /package/dist/{__synced__/types/components/layouts.synced.js → shared/types/components/divider.js} +0 -0
  190. /package/dist/{__synced__/types/components/link.synced.js → shared/types/components/dropdown.js} +0 -0
  191. /package/dist/{__synced__/types/components/list.synced.js → shared/types/components/empty-state.js} +0 -0
  192. /package/dist/{__synced__/types/components/loading-spinner.synced.js → shared/types/components/error-state.js} +0 -0
  193. /package/dist/{__synced__/types/components/modal.synced.js → shared/types/components/form.js} +0 -0
  194. /package/dist/{__synced__/types/components/panel.synced.js → shared/types/components/heading.js} +0 -0
  195. /package/dist/{__synced__/types/components/progress-bar.synced.js → shared/types/components/icon.js} +0 -0
  196. /package/dist/{__synced__/types/components/selects.synced.js → shared/types/components/iframe.js} +0 -0
  197. /package/dist/{__synced__/types/components/illustration.synced.js → shared/types/components/illustration.js} +0 -0
  198. /package/dist/{__synced__/types/components/statistics.synced.js → shared/types/components/image.js} +0 -0
  199. /package/dist/{__synced__/types/components/status-tag.synced.js → shared/types/components/index.js} +0 -0
  200. /package/dist/{__synced__/types/components/step-indicator.synced.js → shared/types/components/inputs.js} +0 -0
  201. /package/dist/{__synced__/types/components/table.synced.js → shared/types/components/layouts.js} +0 -0
  202. /package/dist/{__synced__/types/components/tabs.synced.js → shared/types/components/link.js} +0 -0
  203. /package/dist/{__synced__/types/components/tag.synced.js → shared/types/components/list.js} +0 -0
  204. /package/dist/{__synced__/types/components/text.synced.js → shared/types/components/loading-spinner.js} +0 -0
  205. /package/dist/{__synced__/types/components/tile.synced.js → shared/types/components/modal.js} +0 -0
  206. /package/dist/{__synced__/types/components/toggle.synced.js → shared/types/components/panel.js} +0 -0
  207. /package/dist/{__synced__/types/components/toggleInputs.synced.js → shared/types/components/progress-bar.js} +0 -0
  208. /package/dist/{__synced__/types/components/tooltip.synced.js → shared/types/components/selects.js} +0 -0
  209. /package/dist/{__synced__/types/context.synced.js → shared/types/components/statistics.js} +0 -0
  210. /package/dist/{__synced__/types/crm.synced.js → shared/types/components/status-tag.js} +0 -0
  211. /package/dist/{__synced__/types/reactions.synced.js → shared/types/components/step-indicator.js} +0 -0
  212. /package/dist/{__synced__/types/extension-points.synced.js → shared/types/extension-points.js} +0 -0
  213. /package/dist/{__synced__/types/http-requests.synced.js → shared/types/http-requests.js} +0 -0
  214. /package/dist/{__synced__/types/reactions.synced.d.ts → shared/types/reactions.d.ts} +0 -0
  215. /package/dist/{__synced__/types/shared.synced.js → shared/types/shared.js} +0 -0
@@ -1,9 +1,11 @@
1
- import { RenderedNodeType } from '../types';
2
- import { EMPTY_CHILDREN } from './constants';
3
- import { debugLog } from './debug';
4
- import { InvalidEventFunctionError, MissingEventFunctionError } from './errors';
5
- import { printNode } from './print';
6
- import { find, findAll, findAllChildren, findChild, maybeFind, maybeFindChild, } from './query';
1
+ import { RenderedNodeType } from "../types.js";
2
+ import { isMatch } from "../utils.js";
3
+ import { EMPTY_RENDERED_CHILD_NODES } from "./constants.js";
4
+ import { debugLog } from "./debug.js";
5
+ import { InvalidEventFunctionError, MissingEventFunctionError, } from "./errors.js";
6
+ import { printNode } from "./print.js";
7
+ import { find, findAll, findAllChildren, findChild, maybeFind, maybeFindChild, } from "./query.js";
8
+ import { asRenderedElementNode, asRenderedNode, } from "./type-utils-internal.js";
7
9
  /**
8
10
  * Creates a rendered element node.
9
11
  *
@@ -18,10 +20,10 @@ export const createElementNode = (document, name, props) => {
18
20
  name,
19
21
  props,
20
22
  text: null,
21
- children: EMPTY_CHILDREN,
23
+ childNodes: EMPTY_RENDERED_CHILD_NODES,
22
24
  document,
23
25
  debugLog: (label) => {
24
- debugLog(elementNode, label);
26
+ debugLog(asRenderedNode(elementNode), label);
25
27
  },
26
28
  find: (targetComponent, matcher) => {
27
29
  return find(elementNode, targetComponent, matcher);
@@ -42,7 +44,7 @@ export const createElementNode = (document, name, props) => {
42
44
  return maybeFindChild(elementNode, targetComponent, matcher);
43
45
  },
44
46
  toString: () => {
45
- return printNode(elementNode);
47
+ return printNode(asRenderedNode(elementNode));
46
48
  },
47
49
  trigger: (eventPropName, eventArg) => {
48
50
  const eventFunction = elementNode.props[eventPropName];
@@ -62,6 +64,9 @@ export const createElementNode = (document, name, props) => {
62
64
  eventFunction(eventArg);
63
65
  });
64
66
  },
67
+ isMatch(__component, __matcher) {
68
+ return isMatch(asRenderedNode(elementNode), __component, __matcher);
69
+ },
65
70
  };
66
- return elementNode;
71
+ return asRenderedElementNode(elementNode);
67
72
  };
@@ -1,5 +1,5 @@
1
- import { RenderedParentNode } from '../types';
2
- import { RenderedRootNodeInternal } from './types-internal';
1
+ import { RenderedElementNode, RenderedParentNode } from '../types.ts';
2
+ import { RenderedRootNodeInternal } from './types-internal.ts';
3
3
  /**
4
4
  * Thrown when trying to trigger an event that has a handler prop that is not a function.
5
5
  */
@@ -54,3 +54,46 @@ export declare class InvalidFragmentPropArrayError extends Error {
54
54
  export declare class WaitForTimeoutError extends Error {
55
55
  constructor(timeout: number);
56
56
  }
57
+ /**
58
+ * Thrown when an invalid extension point location is provided.
59
+ */
60
+ export declare class InvalidExtensionPointLocationError extends Error {
61
+ constructor(extensionPointLocation: string);
62
+ }
63
+ /**
64
+ * Thrown when a component is not found in the rendered output when queryingby test ID.
65
+ */
66
+ export declare class ComponentNotFoundByTestIdError extends Error {
67
+ constructor({ findMethodName, componentName, testId, rootNode, }: {
68
+ findMethodName: string;
69
+ componentName: string;
70
+ testId: string;
71
+ rootNode: RenderedRootNodeInternal;
72
+ });
73
+ }
74
+ /**
75
+ * Thrown when a component is found in the rendered output when querying by test ID, but does not match the expected component.
76
+ */
77
+ export declare class ComponentMismatchedByTestIdError extends Error {
78
+ constructor({ findMethodName, actualComponentName, expectedComponentName, testId, rootNode, }: {
79
+ findMethodName: string;
80
+ actualComponentName: string;
81
+ expectedComponentName: string;
82
+ testId: string;
83
+ rootNode: RenderedRootNodeInternal;
84
+ });
85
+ }
86
+ /**
87
+ * Thrown when a test ID is already in use.
88
+ *
89
+ * @param testId The test ID that is already in use.
90
+ * @param previousElement The element that was already using the test ID.
91
+ * @param newElement The element that is trying to use the same test ID.
92
+ */
93
+ export declare class DuplicateTestIdError extends Error {
94
+ constructor({ testId, previousElement, newElement, }: {
95
+ testId: string;
96
+ previousElement: RenderedElementNode;
97
+ newElement: RenderedElementNode;
98
+ });
99
+ }
@@ -1,4 +1,6 @@
1
- import { printNode } from './print';
1
+ import { EXTENSION_POINT_LOCATIONS } from "../../../shared/types/extension-points.js";
2
+ import { printNode } from "./print.js";
3
+ import { asRenderedNode } from "./type-utils-internal.js";
2
4
  /**
3
5
  * Thrown when trying to trigger an event that has a handler prop that is not a function.
4
6
  */
@@ -34,7 +36,7 @@ export class InvalidComponentsError extends Error {
34
36
  super(`Invalid rendered output. Found invalid components (${rootNode.document
35
37
  .getInvalidComponentNames()
36
38
  .map((name) => `"${name}"`)
37
- .join(', ')}) in rendered output: ${printNode(rootNode, {
39
+ .join(', ')}) in rendered output: ${printNode(asRenderedNode(rootNode), {
38
40
  markInvalidComponents: true,
39
41
  listInvalidComponents: true,
40
42
  })}`);
@@ -68,3 +70,43 @@ export class WaitForTimeoutError extends Error {
68
70
  this.name = 'WaitForTimeoutError';
69
71
  }
70
72
  }
73
+ /**
74
+ * Thrown when an invalid extension point location is provided.
75
+ */
76
+ export class InvalidExtensionPointLocationError extends Error {
77
+ constructor(extensionPointLocation) {
78
+ super(`Invalid extension point location of "${extensionPointLocation}". Allowed locations are: ${EXTENSION_POINT_LOCATIONS.map((location) => `"${location}"`).join(', ')}`);
79
+ this.name = 'InvalidExtensionPointLocationError';
80
+ }
81
+ }
82
+ /**
83
+ * Thrown when a component is not found in the rendered output when queryingby test ID.
84
+ */
85
+ export class ComponentNotFoundByTestIdError extends Error {
86
+ constructor({ findMethodName, componentName, testId, rootNode, }) {
87
+ super(`${findMethodName}() failed. <${componentName}> with test ID "${testId}" not found in rendered output: ${rootNode.toString()}`);
88
+ this.name = 'ComponentNotFoundByTestIdError';
89
+ }
90
+ }
91
+ /**
92
+ * Thrown when a component is found in the rendered output when querying by test ID, but does not match the expected component.
93
+ */
94
+ export class ComponentMismatchedByTestIdError extends Error {
95
+ constructor({ findMethodName, actualComponentName, expectedComponentName, testId, rootNode, }) {
96
+ super(`${findMethodName}() failed. <${actualComponentName}> with test ID "${testId}" does not match expected component <${expectedComponentName}> in rendered output: ${rootNode.toString()}`);
97
+ this.name = 'ComponentMismatchedByTestIdError';
98
+ }
99
+ }
100
+ /**
101
+ * Thrown when a test ID is already in use.
102
+ *
103
+ * @param testId The test ID that is already in use.
104
+ * @param previousElement The element that was already using the test ID.
105
+ * @param newElement The element that is trying to use the same test ID.
106
+ */
107
+ export class DuplicateTestIdError extends Error {
108
+ constructor({ testId, previousElement, newElement, }) {
109
+ super(`Test ID "${testId}" is already in use.\n\nPrevious component: ${previousElement.toString()}\n\nNew component: ${newElement.toString()}`);
110
+ this.name = 'DuplicateTestIdError';
111
+ }
112
+ }
@@ -1,8 +1,9 @@
1
- import type { RenderedDocumentInternal, RenderedFragmentNodeInternal } from './types-internal';
1
+ import { RenderedFragmentNode } from '../types.ts';
2
+ import type { RenderedDocumentInternal } from './types-internal.ts';
2
3
  /**
3
4
  * Creates a rendered fragment node.
4
5
  *
5
6
  * @param document The document that the fragment belongs to.
6
7
  * @returns A rendered fragment node.
7
8
  */
8
- export declare const createFragmentNode: (document: RenderedDocumentInternal) => RenderedFragmentNodeInternal;
9
+ export declare const createFragmentNode: (document: RenderedDocumentInternal) => RenderedFragmentNode;
@@ -1,8 +1,9 @@
1
- import { RenderedNodeType } from '../types';
2
- import { EMPTY_CHILDREN } from './constants';
3
- import { debugLog } from './debug';
4
- import { printNode } from './print';
5
- import { find, findAll, findAllChildren, findChild, maybeFind, maybeFindChild, } from './query';
1
+ import { RenderedNodeType } from "../types.js";
2
+ import { EMPTY_RENDERED_CHILD_NODES } from "./constants.js";
3
+ import { debugLog } from "./debug.js";
4
+ import { printNode } from "./print.js";
5
+ import { find, findAll, findAllChildren, findChild, maybeFind, maybeFindChild, } from "./query.js";
6
+ import { asRenderedFragmentNode, asRenderedNode, } from "./type-utils-internal.js";
6
7
  /**
7
8
  * Creates a rendered fragment node.
8
9
  *
@@ -13,10 +14,10 @@ export const createFragmentNode = (document) => {
13
14
  const fragmentNode = {
14
15
  nodeType: RenderedNodeType.Fragment,
15
16
  text: null,
16
- children: EMPTY_CHILDREN,
17
+ childNodes: EMPTY_RENDERED_CHILD_NODES,
17
18
  document,
18
19
  debugLog: (label) => {
19
- debugLog(fragmentNode, label);
20
+ debugLog(asRenderedNode(fragmentNode), label);
20
21
  },
21
22
  find: (targetComponent, matcher) => {
22
23
  return find(fragmentNode, targetComponent, matcher);
@@ -37,8 +38,11 @@ export const createFragmentNode = (document) => {
37
38
  return maybeFindChild(fragmentNode, targetComponent, matcher);
38
39
  },
39
40
  toString: () => {
40
- return printNode(fragmentNode);
41
+ return printNode(asRenderedFragmentNode(fragmentNode));
42
+ },
43
+ isMatch(__component, __matcher) {
44
+ return false;
41
45
  },
42
46
  };
43
- return fragmentNode;
47
+ return asRenderedFragmentNode(fragmentNode);
44
48
  };
@@ -1,5 +1,5 @@
1
- import { HubSpotReactComponent, UnknownComponentProps } from '../../../__synced__/types/shared.synced';
2
- import { ElementMatcher, RenderedElementNode, RenderedNode } from '../types';
1
+ import { UnknownComponentProps } from '../../../shared/types/shared.ts';
2
+ import { ElementMatcher, RenderedElementNode } from '../types.ts';
3
3
  /**
4
4
  * Checks if the element matches the matcher.
5
5
  *
@@ -7,13 +7,4 @@ import { ElementMatcher, RenderedElementNode, RenderedNode } from '../types';
7
7
  * @param matcher An optional matcher to filter the elements.
8
8
  * @returns `true` if the element matches the matcher, `false` otherwise.
9
9
  */
10
- export declare const checkElementMatches: <TProps extends UnknownComponentProps>(element: RenderedElementNode<TProps>, matcher?: ElementMatcher<TProps> | undefined) => boolean;
11
- /**
12
- * Checks if the node matches the component and matcher.
13
- *
14
- * @param node The node to check.
15
- * @param component The component to check.
16
- * @param matcher An optional matcher to filter the elements.
17
- * @returns Whether the node matches the component and matcher.
18
- */
19
- export declare const isMatch: <TComponentProps extends UnknownComponentProps>(node: RenderedNode | null | undefined, component: HubSpotReactComponent<TComponentProps>, matcher?: ElementMatcher<TComponentProps> | undefined) => node is RenderedElementNode<TComponentProps>;
10
+ export declare const checkElementMatches: <TProps extends UnknownComponentProps>(element: RenderedElementNode<TProps>, matcher?: ElementMatcher<TProps>) => boolean;
@@ -1,5 +1,3 @@
1
- import { RenderedNodeType, } from '../types';
2
- import { __hubSpotComponentRegistry } from '../../../__synced__/remoteComponents.synced';
3
1
  /**
4
2
  * Checks if the element matches the matcher.
5
3
  *
@@ -19,24 +17,3 @@ export const checkElementMatches = (element, matcher) => {
19
17
  // Check if all the props in the matcher match the props in the element
20
18
  return Object.keys(matcher).every((key) => element.props[key] === matcher[key]);
21
19
  };
22
- /**
23
- * Checks if the node matches the component and matcher.
24
- *
25
- * @param node The node to check.
26
- * @param component The component to check.
27
- * @param matcher An optional matcher to filter the elements.
28
- * @returns Whether the node matches the component and matcher.
29
- */
30
- export const isMatch = (node, component, matcher) => {
31
- if (node == null) {
32
- return false;
33
- }
34
- if (node.nodeType !== RenderedNodeType.Element) {
35
- return false;
36
- }
37
- const targetComponentName = __hubSpotComponentRegistry.getComponentName(component);
38
- if (node.name !== targetComponentName) {
39
- return false;
40
- }
41
- return checkElementMatches(node, matcher);
42
- };
@@ -0,0 +1,17 @@
1
+ import { RendererSpies } from '../../types.ts';
2
+ import { RendererMocksInternal } from '../types-internal.ts';
3
+ import { ExtensionPointLocation } from '../../../../shared/types/extension-points.ts';
4
+ /**
5
+ * An object containing the mocks and spies.
6
+ */
7
+ export interface MocksWithSpies<TExtensionPointLocation extends ExtensionPointLocation> {
8
+ mocks: RendererMocksInternal<TExtensionPointLocation>;
9
+ spies: RendererSpies<TExtensionPointLocation>;
10
+ }
11
+ /**
12
+ * Creates a set of mocks and spies for the various functions such as the `useCrmProperties` and `useAssociations`
13
+ * hook functions.
14
+ *
15
+ * @returns An object containing the mocks and spies.
16
+ */
17
+ export declare const createMocksWithSpies: <TExtensionPointLocation extends ExtensionPointLocation>(extensionPointLocation: TExtensionPointLocation) => MocksWithSpies<TExtensionPointLocation>;
@@ -0,0 +1,46 @@
1
+ import { spyOn } from 'tinyspy';
2
+ import { createMockHooks } from "./mock-hooks.js";
3
+ import { createMockExtensionPointApi } from "./mock-extension-point-api.js";
4
+ /**
5
+ * This function replaces all methods with a spy using the `spyOn` function from the `tinyspy` library.
6
+ * The object tree is walked recursively to replace all methods with spies. The original object is not modified.
7
+ *
8
+ * @param object The object to spy on.
9
+ * @returns A new object with all of the methods replaced with spies.
10
+ */
11
+ const spyOnAllFunctionsRecursive = (object) => {
12
+ if (!object || typeof object !== 'object' || Array.isArray(object)) {
13
+ return object;
14
+ }
15
+ const objectWithSpies = Object.create(null);
16
+ for (const [key, value] of Object.entries(object)) {
17
+ if (typeof value === 'function') {
18
+ objectWithSpies[key] = spyOn(object, key);
19
+ }
20
+ else {
21
+ objectWithSpies[key] = spyOnAllFunctionsRecursive(value);
22
+ }
23
+ }
24
+ return objectWithSpies;
25
+ };
26
+ /**
27
+ * Creates a set of mocks and spies for the various functions such as the `useCrmProperties` and `useAssociations`
28
+ * hook functions.
29
+ *
30
+ * @returns An object containing the mocks and spies.
31
+ */
32
+ export const createMocksWithSpies = (extensionPointLocation) => {
33
+ const mockExtensionPointApi = createMockExtensionPointApi(extensionPointLocation);
34
+ // Build a mocks object with the default mock functions.
35
+ // NOTE: The mock implementations can be overridden by tests using the spies that are provided in the returned `spies` object.
36
+ const mocks = {
37
+ ...createMockHooks(),
38
+ ...mockExtensionPointApi,
39
+ };
40
+ // Spy on each of the mocks and build the object with all of the spies.
41
+ const spies = spyOnAllFunctionsRecursive(mocks);
42
+ return {
43
+ mocks,
44
+ spies: spies,
45
+ };
46
+ };
@@ -0,0 +1,2 @@
1
+ import { ExtensionPointApi, type ExtensionPointLocation } from '../../../../shared/types/extension-points.ts';
2
+ export declare const createMockExtensionPointApi: (extensionPointLocation: ExtensionPointLocation) => ExtensionPointApi<ExtensionPointLocation>;
@@ -0,0 +1,166 @@
1
+ import { ServerlessExecutionStatus, } from "../../../../shared/types/http-requests.js";
2
+ const fakePrefix = 'fake_';
3
+ const createMockServerlessFuncRunner = () => {
4
+ return () => Promise.resolve({
5
+ status: ServerlessExecutionStatus.Success,
6
+ response: {
7
+ fakeData: 'hello',
8
+ },
9
+ });
10
+ };
11
+ const createMockCrmHostActions = () => {
12
+ return {
13
+ addAlert: () => { },
14
+ reloadPage: () => { },
15
+ fetchCrmObjectProperties: () => Promise.resolve({}),
16
+ openIframeModal: () => { },
17
+ refreshObjectProperties: () => { },
18
+ onCrmPropertiesUpdate: () => { },
19
+ };
20
+ };
21
+ const createMockUiePlatformActions = () => {
22
+ return {
23
+ copyTextToClipboard: async () => { },
24
+ closeOverlay: () => { },
25
+ reloadPage: () => { },
26
+ openIframeModal: () => { },
27
+ };
28
+ };
29
+ const createMockSettingsActions = () => {
30
+ return {
31
+ addAlert: () => { },
32
+ };
33
+ };
34
+ const createMockAppHomeActions = () => {
35
+ return {
36
+ addAlert: () => { },
37
+ };
38
+ };
39
+ const createFakeEmail = () => `${fakePrefix}email@example.com`;
40
+ const createFakeFirstName = () => `${fakePrefix}firstName`;
41
+ const createFakeLastName = () => `${fakePrefix}lastName`;
42
+ const createFakeUser = () => {
43
+ return {
44
+ id: 1,
45
+ emails: [createFakeEmail()],
46
+ email: createFakeEmail(),
47
+ firstName: createFakeFirstName(),
48
+ lastName: createFakeLastName(),
49
+ roles: [],
50
+ teams: [],
51
+ permissions: [],
52
+ };
53
+ };
54
+ const createFakePortalContext = () => {
55
+ return {
56
+ id: 123,
57
+ timezone: 'America/New_York',
58
+ };
59
+ };
60
+ const createFakeCrmRecordContext = () => {
61
+ return {
62
+ objectId: 123,
63
+ objectTypeId: '0-1',
64
+ };
65
+ };
66
+ const createFakeCrmContext = (extensionPointLocationName) => {
67
+ return {
68
+ location: extensionPointLocationName,
69
+ user: createFakeUser(),
70
+ portal: createFakePortalContext(),
71
+ crm: createFakeCrmRecordContext(),
72
+ variables: {
73
+ fake_variable: 'fake_value',
74
+ },
75
+ };
76
+ };
77
+ const mockCreators = {
78
+ 'crm.record.tab': () => {
79
+ return {
80
+ runServerlessFunction: createMockServerlessFuncRunner(),
81
+ actions: {
82
+ ...createMockCrmHostActions(),
83
+ ...createMockUiePlatformActions(),
84
+ },
85
+ context: createFakeCrmContext('crm.record.tab'),
86
+ };
87
+ },
88
+ 'crm.preview': () => {
89
+ return {
90
+ runServerlessFunction: createMockServerlessFuncRunner(),
91
+ actions: {
92
+ ...createMockCrmHostActions(),
93
+ ...createMockUiePlatformActions(),
94
+ },
95
+ context: createFakeCrmContext('crm.preview'),
96
+ };
97
+ },
98
+ 'crm.record.sidebar': () => {
99
+ return {
100
+ runServerlessFunction: createMockServerlessFuncRunner(),
101
+ actions: {
102
+ ...createMockCrmHostActions(),
103
+ ...createMockUiePlatformActions(),
104
+ },
105
+ context: createFakeCrmContext('crm.record.sidebar'),
106
+ };
107
+ },
108
+ 'helpdesk.sidebar': () => {
109
+ return {
110
+ runServerlessFunction: createMockServerlessFuncRunner(),
111
+ actions: {
112
+ ...createMockCrmHostActions(),
113
+ ...createMockUiePlatformActions(),
114
+ },
115
+ context: createFakeCrmContext('helpdesk.sidebar'),
116
+ };
117
+ },
118
+ 'uie.playground.middle': () => {
119
+ return {
120
+ runServerlessFunction: createMockServerlessFuncRunner(),
121
+ actions: {
122
+ warn: () => { },
123
+ },
124
+ context: {
125
+ location: 'uie.playground.middle',
126
+ user: createFakeUser(),
127
+ portal: createFakePortalContext(),
128
+ },
129
+ };
130
+ },
131
+ settings: () => {
132
+ return {
133
+ runServerlessFunction: createMockServerlessFuncRunner(),
134
+ actions: {
135
+ ...createMockSettingsActions(),
136
+ ...createMockUiePlatformActions(),
137
+ },
138
+ context: {
139
+ location: 'settings',
140
+ user: createFakeUser(),
141
+ portal: createFakePortalContext(),
142
+ },
143
+ };
144
+ },
145
+ home: () => {
146
+ return {
147
+ runServerlessFunction: createMockServerlessFuncRunner(),
148
+ actions: {
149
+ ...createMockAppHomeActions(),
150
+ ...createMockUiePlatformActions(),
151
+ },
152
+ context: {
153
+ location: 'home',
154
+ user: createFakeUser(),
155
+ portal: createFakePortalContext(),
156
+ },
157
+ };
158
+ },
159
+ };
160
+ export const createMockExtensionPointApi = (extensionPointLocation) => {
161
+ const mockCreator = mockCreators[extensionPointLocation];
162
+ if (!mockCreator) {
163
+ throw new Error(`No mock creator found for extension point location: ${extensionPointLocation}`);
164
+ }
165
+ return mockCreator();
166
+ };
@@ -0,0 +1,2 @@
1
+ import { RendererMockHooksInternal } from '../types-internal.ts';
2
+ export declare const createMockHooks: () => RendererMockHooksInternal;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Creates a record of property names and their fake values.
3
+ *
4
+ * @param propertyNames The names of the properties to create to create fake properties.
5
+ * @returns A record of property names and their fake values.
6
+ */
7
+ const createFakeProperties = (propertyNames) => {
8
+ if (!propertyNames || propertyNames.length === 0) {
9
+ return {};
10
+ }
11
+ return propertyNames.reduce((acc, propertyName) => {
12
+ acc[propertyName] = `fake_${propertyName}`;
13
+ return acc;
14
+ }, {});
15
+ };
16
+ export const createMockHooks = () => {
17
+ // Build a mocks object with the default mock functions.
18
+ // NOTE: The mock implementations can be overridden by tests using the spies that are provided in the returned `spies` object.
19
+ return {
20
+ useCrmProperties: (propertyNames) => {
21
+ const properties = createFakeProperties(propertyNames);
22
+ return {
23
+ properties,
24
+ error: null,
25
+ isLoading: false,
26
+ };
27
+ },
28
+ useAssociations: (config) => {
29
+ const { properties: propertyNames } = config;
30
+ const properties = createFakeProperties(propertyNames);
31
+ return {
32
+ results: [
33
+ {
34
+ toObjectId: 123,
35
+ associationTypes: [
36
+ {
37
+ category: 'HUBSPOT_DEFINED',
38
+ typeId: 1,
39
+ label: 'Primary',
40
+ },
41
+ ],
42
+ properties,
43
+ },
44
+ ],
45
+ error: null,
46
+ isLoading: false,
47
+ pagination: {
48
+ hasNextPage: false,
49
+ hasPreviousPage: false,
50
+ currentPage: 1,
51
+ pageSize: 10,
52
+ nextPage: () => { },
53
+ previousPage: () => { },
54
+ reset: () => { },
55
+ },
56
+ };
57
+ },
58
+ };
59
+ };
@@ -1,6 +1,6 @@
1
- import type { RenderedParentNode } from '../types';
1
+ import type { RenderedNode } from '../types.ts';
2
2
  export interface PrintOptions {
3
3
  markInvalidComponents: boolean;
4
4
  listInvalidComponents: boolean;
5
5
  }
6
- export declare const printNode: (rootNode: RenderedParentNode, options?: PrintOptions) => string;
6
+ export declare const printNode: (rootNode: RenderedNode, options?: PrintOptions) => string;
@@ -1,5 +1,5 @@
1
- import { __hubSpotComponentRegistry } from '../../../__synced__/remoteComponents.synced';
2
- import { isRenderedElementNode, isRenderedFragmentNode, isRenderedRootNode, isRenderedTextNode, } from '../type-utils';
1
+ import { __hubSpotComponentRegistry } from "../../../shared/remoteComponents.js";
2
+ import { isRenderedElementNode, isRenderedFragmentNode, isRenderedRootNode, isRenderedTextNode, } from "../type-utils.js";
3
3
  const INDENT_STRING = ' ';
4
4
  const printTextNode = (node, indent, printContext) => {
5
5
  printContext.append(`${indent}${JSON.stringify(node.text)}\n`);
@@ -43,7 +43,7 @@ const printElementStart = (node, indent, printContext) => {
43
43
  }
44
44
  };
45
45
  const printElementNode = (node, indent, printContext) => {
46
- const hasChildren = node.children.length > 0;
46
+ const hasChildren = node.childNodes.length > 0;
47
47
  const { name, props } = node;
48
48
  if (hasChildren) {
49
49
  printElementStart(node, indent, printContext);
@@ -59,16 +59,16 @@ const printElementNode = (node, indent, printContext) => {
59
59
  }
60
60
  };
61
61
  const printChildren = (node, indent, printContext) => {
62
- const { children } = node;
63
- for (const child of children) {
64
- if (isRenderedTextNode(child)) {
65
- printTextNode(child, indent, printContext);
62
+ const { childNodes } = node;
63
+ for (const childNode of childNodes) {
64
+ if (isRenderedTextNode(childNode)) {
65
+ printTextNode(childNode, indent, printContext);
66
66
  }
67
- else if (isRenderedElementNode(child)) {
68
- printElementNode(child, indent, printContext);
67
+ else if (isRenderedElementNode(childNode)) {
68
+ printElementNode(childNode, indent, printContext);
69
69
  }
70
70
  else {
71
- throw new Error(`Illegal State. Invalid rendered node type: ${child.nodeType}`);
71
+ throw new Error(`Illegal State. Invalid rendered node type: ${childNode.nodeType}`);
72
72
  }
73
73
  }
74
74
  };
@@ -99,9 +99,15 @@ export const printNode = (rootNode, options = DEFAULT_PRINT_OPTIONS) => {
99
99
  else if (isRenderedFragmentNode(rootNode)) {
100
100
  printFragmentNode(rootNode, '', printContext);
101
101
  }
102
- else {
102
+ else if (isRenderedElementNode(rootNode)) {
103
103
  printElementNode(rootNode, '', printContext);
104
104
  }
105
+ else if (isRenderedTextNode(rootNode)) {
106
+ printTextNode(rootNode, '', printContext);
107
+ }
108
+ else {
109
+ throw new Error(`Illegal State. Invalid rendered node type: ${rootNode.nodeType}`);
110
+ }
105
111
  if (listInvalidComponents && printContext.foundInvalidComponents.size > 0) {
106
112
  printContext.append(`\n⚠️ Invalid components:\n`);
107
113
  const foundInvalidComponents = [...printContext.foundInvalidComponents];