@thoughtspot/visual-embed-sdk 1.50.0 → 1.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/css-variables.d.ts +95 -0
  3. package/cjs/src/css-variables.d.ts.map +1 -1
  4. package/cjs/src/embed/app.d.ts +136 -15
  5. package/cjs/src/embed/app.d.ts.map +1 -1
  6. package/cjs/src/embed/app.js +59 -37
  7. package/cjs/src/embed/app.js.map +1 -1
  8. package/cjs/src/embed/app.spec.js +419 -149
  9. package/cjs/src/embed/app.spec.js.map +1 -1
  10. package/cjs/src/embed/conversation.d.ts +230 -1
  11. package/cjs/src/embed/conversation.d.ts.map +1 -1
  12. package/cjs/src/embed/conversation.js +30 -16
  13. package/cjs/src/embed/conversation.js.map +1 -1
  14. package/cjs/src/embed/conversation.spec.js +221 -17
  15. package/cjs/src/embed/conversation.spec.js.map +1 -1
  16. package/cjs/src/embed/events.spec.js +635 -0
  17. package/cjs/src/embed/events.spec.js.map +1 -1
  18. package/cjs/src/embed/host-events.spec.js +151 -0
  19. package/cjs/src/embed/host-events.spec.js.map +1 -1
  20. package/cjs/src/embed/hostEventClient/contracts.d.ts +51 -14
  21. package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  22. package/cjs/src/embed/hostEventClient/contracts.js +11 -1
  23. package/cjs/src/embed/hostEventClient/contracts.js.map +1 -1
  24. package/cjs/src/embed/hostEventClient/host-event-client.d.ts +1 -0
  25. package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  26. package/cjs/src/embed/hostEventClient/host-event-client.js +9 -0
  27. package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -1
  28. package/cjs/src/embed/hostEventClient/host-event-client.spec.js +218 -0
  29. package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  30. package/cjs/src/embed/hostEventClient/utils.d.ts +2 -0
  31. package/cjs/src/embed/hostEventClient/utils.d.ts.map +1 -1
  32. package/cjs/src/embed/hostEventClient/utils.js +32 -2
  33. package/cjs/src/embed/hostEventClient/utils.js.map +1 -1
  34. package/cjs/src/embed/hostEventClient/utils.spec.js +178 -0
  35. package/cjs/src/embed/hostEventClient/utils.spec.js.map +1 -1
  36. package/cjs/src/embed/liveboard.d.ts +42 -1
  37. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  38. package/cjs/src/embed/liveboard.js +26 -6
  39. package/cjs/src/embed/liveboard.js.map +1 -1
  40. package/cjs/src/embed/liveboard.spec.js +83 -2
  41. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  42. package/cjs/src/embed/spotter-utils.d.ts +8 -1
  43. package/cjs/src/embed/spotter-utils.d.ts.map +1 -1
  44. package/cjs/src/embed/spotter-utils.js +14 -1
  45. package/cjs/src/embed/spotter-utils.js.map +1 -1
  46. package/cjs/src/embed/spotter-utils.spec.js +61 -0
  47. package/cjs/src/embed/spotter-utils.spec.js.map +1 -1
  48. package/cjs/src/embed/spotter-viz-utils.d.ts +34 -0
  49. package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -1
  50. package/cjs/src/embed/spotter-viz-utils.js.map +1 -1
  51. package/cjs/src/embed/spotter-viz-utils.spec.js +17 -0
  52. package/cjs/src/embed/spotter-viz-utils.spec.js.map +1 -1
  53. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  54. package/cjs/src/embed/ts-embed.js +29 -7
  55. package/cjs/src/embed/ts-embed.js.map +1 -1
  56. package/cjs/src/embed/ts-embed.spec.js +146 -0
  57. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  58. package/cjs/src/errors.d.ts +1 -0
  59. package/cjs/src/errors.d.ts.map +1 -1
  60. package/cjs/src/errors.js +1 -0
  61. package/cjs/src/errors.js.map +1 -1
  62. package/cjs/src/index.d.ts +2 -2
  63. package/cjs/src/index.d.ts.map +1 -1
  64. package/cjs/src/index.js +3 -2
  65. package/cjs/src/index.js.map +1 -1
  66. package/cjs/src/mixpanel-service.d.ts +4 -0
  67. package/cjs/src/mixpanel-service.d.ts.map +1 -1
  68. package/cjs/src/mixpanel-service.js +4 -0
  69. package/cjs/src/mixpanel-service.js.map +1 -1
  70. package/cjs/src/react/util.spec.js +251 -0
  71. package/cjs/src/react/util.spec.js.map +1 -1
  72. package/cjs/src/types.d.ts +573 -11
  73. package/cjs/src/types.d.ts.map +1 -1
  74. package/cjs/src/types.js +519 -2
  75. package/cjs/src/types.js.map +1 -1
  76. package/cjs/src/utils/processData.spec.js +93 -0
  77. package/cjs/src/utils/processData.spec.js.map +1 -1
  78. package/cjs/src/utils/processTrigger.spec.js +61 -0
  79. package/cjs/src/utils/processTrigger.spec.js.map +1 -1
  80. package/dist/{index-B5xoN6Cp.js → index-aBzH5ZwF.js} +1 -1
  81. package/dist/src/css-variables.d.ts +95 -0
  82. package/dist/src/css-variables.d.ts.map +1 -1
  83. package/dist/src/embed/app.d.ts +136 -15
  84. package/dist/src/embed/app.d.ts.map +1 -1
  85. package/dist/src/embed/conversation.d.ts +230 -1
  86. package/dist/src/embed/conversation.d.ts.map +1 -1
  87. package/dist/src/embed/hostEventClient/contracts.d.ts +51 -14
  88. package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  89. package/dist/src/embed/hostEventClient/host-event-client.d.ts +1 -0
  90. package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  91. package/dist/src/embed/hostEventClient/utils.d.ts +2 -0
  92. package/dist/src/embed/hostEventClient/utils.d.ts.map +1 -1
  93. package/dist/src/embed/liveboard.d.ts +42 -1
  94. package/dist/src/embed/liveboard.d.ts.map +1 -1
  95. package/dist/src/embed/spotter-utils.d.ts +8 -1
  96. package/dist/src/embed/spotter-utils.d.ts.map +1 -1
  97. package/dist/src/embed/spotter-viz-utils.d.ts +34 -0
  98. package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
  99. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  100. package/dist/src/errors.d.ts +1 -0
  101. package/dist/src/errors.d.ts.map +1 -1
  102. package/dist/src/index.d.ts +2 -2
  103. package/dist/src/index.d.ts.map +1 -1
  104. package/dist/src/mixpanel-service.d.ts +4 -0
  105. package/dist/src/mixpanel-service.d.ts.map +1 -1
  106. package/dist/src/types.d.ts +573 -11
  107. package/dist/src/types.d.ts.map +1 -1
  108. package/dist/tsembed-react.es.js +936 -142
  109. package/dist/tsembed-react.js +935 -141
  110. package/dist/tsembed.es.js +935 -142
  111. package/dist/tsembed.js +933 -140
  112. package/dist/visual-embed-sdk-react-full.d.ts +1147 -44
  113. package/dist/visual-embed-sdk-react.d.ts +1153 -46
  114. package/dist/visual-embed-sdk.d.ts +1161 -46
  115. package/lib/package.json +1 -1
  116. package/lib/src/css-variables.d.ts +95 -0
  117. package/lib/src/css-variables.d.ts.map +1 -1
  118. package/lib/src/embed/app.d.ts +136 -15
  119. package/lib/src/embed/app.d.ts.map +1 -1
  120. package/lib/src/embed/app.js +60 -38
  121. package/lib/src/embed/app.js.map +1 -1
  122. package/lib/src/embed/app.spec.js +420 -150
  123. package/lib/src/embed/app.spec.js.map +1 -1
  124. package/lib/src/embed/conversation.d.ts +230 -1
  125. package/lib/src/embed/conversation.d.ts.map +1 -1
  126. package/lib/src/embed/conversation.js +31 -17
  127. package/lib/src/embed/conversation.js.map +1 -1
  128. package/lib/src/embed/conversation.spec.js +222 -18
  129. package/lib/src/embed/conversation.spec.js.map +1 -1
  130. package/lib/src/embed/events.spec.js +635 -0
  131. package/lib/src/embed/events.spec.js.map +1 -1
  132. package/lib/src/embed/host-events.spec.js +152 -1
  133. package/lib/src/embed/host-events.spec.js.map +1 -1
  134. package/lib/src/embed/hostEventClient/contracts.d.ts +51 -14
  135. package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  136. package/lib/src/embed/hostEventClient/contracts.js +10 -0
  137. package/lib/src/embed/hostEventClient/contracts.js.map +1 -1
  138. package/lib/src/embed/hostEventClient/host-event-client.d.ts +1 -0
  139. package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  140. package/lib/src/embed/hostEventClient/host-event-client.js +10 -1
  141. package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -1
  142. package/lib/src/embed/hostEventClient/host-event-client.spec.js +218 -0
  143. package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  144. package/lib/src/embed/hostEventClient/utils.d.ts +2 -0
  145. package/lib/src/embed/hostEventClient/utils.d.ts.map +1 -1
  146. package/lib/src/embed/hostEventClient/utils.js +28 -1
  147. package/lib/src/embed/hostEventClient/utils.js.map +1 -1
  148. package/lib/src/embed/hostEventClient/utils.spec.js +179 -1
  149. package/lib/src/embed/hostEventClient/utils.spec.js.map +1 -1
  150. package/lib/src/embed/liveboard.d.ts +42 -1
  151. package/lib/src/embed/liveboard.d.ts.map +1 -1
  152. package/lib/src/embed/liveboard.js +26 -6
  153. package/lib/src/embed/liveboard.js.map +1 -1
  154. package/lib/src/embed/liveboard.spec.js +83 -2
  155. package/lib/src/embed/liveboard.spec.js.map +1 -1
  156. package/lib/src/embed/spotter-utils.d.ts +8 -1
  157. package/lib/src/embed/spotter-utils.d.ts.map +1 -1
  158. package/lib/src/embed/spotter-utils.js +12 -0
  159. package/lib/src/embed/spotter-utils.js.map +1 -1
  160. package/lib/src/embed/spotter-utils.spec.js +62 -1
  161. package/lib/src/embed/spotter-utils.spec.js.map +1 -1
  162. package/lib/src/embed/spotter-viz-utils.d.ts +34 -0
  163. package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
  164. package/lib/src/embed/spotter-viz-utils.js.map +1 -1
  165. package/lib/src/embed/spotter-viz-utils.spec.js +17 -0
  166. package/lib/src/embed/spotter-viz-utils.spec.js.map +1 -1
  167. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  168. package/lib/src/embed/ts-embed.js +29 -7
  169. package/lib/src/embed/ts-embed.js.map +1 -1
  170. package/lib/src/embed/ts-embed.spec.js +146 -0
  171. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  172. package/lib/src/errors.d.ts +1 -0
  173. package/lib/src/errors.d.ts.map +1 -1
  174. package/lib/src/errors.js +1 -0
  175. package/lib/src/errors.js.map +1 -1
  176. package/lib/src/index.d.ts +2 -2
  177. package/lib/src/index.d.ts.map +1 -1
  178. package/lib/src/index.js +2 -2
  179. package/lib/src/index.js.map +1 -1
  180. package/lib/src/mixpanel-service.d.ts +4 -0
  181. package/lib/src/mixpanel-service.d.ts.map +1 -1
  182. package/lib/src/mixpanel-service.js +4 -0
  183. package/lib/src/mixpanel-service.js.map +1 -1
  184. package/lib/src/react/util.spec.js +251 -0
  185. package/lib/src/react/util.spec.js.map +1 -1
  186. package/lib/src/types.d.ts +573 -11
  187. package/lib/src/types.d.ts.map +1 -1
  188. package/lib/src/types.js +519 -2
  189. package/lib/src/types.js.map +1 -1
  190. package/lib/src/utils/processData.spec.js +93 -0
  191. package/lib/src/utils/processData.spec.js.map +1 -1
  192. package/lib/src/utils/processTrigger.spec.js +61 -0
  193. package/lib/src/utils/processTrigger.spec.js.map +1 -1
  194. package/lib/src/visual-embed-sdk.d.ts +1161 -46
  195. package/package.json +1 -1
  196. package/src/css-variables.ts +118 -0
  197. package/src/embed/app.spec.ts +530 -183
  198. package/src/embed/app.ts +209 -66
  199. package/src/embed/conversation.spec.ts +275 -21
  200. package/src/embed/conversation.ts +262 -17
  201. package/src/embed/events.spec.ts +757 -1
  202. package/src/embed/host-events.spec.ts +194 -0
  203. package/src/embed/hostEventClient/contracts.ts +57 -14
  204. package/src/embed/hostEventClient/host-event-client.spec.ts +338 -0
  205. package/src/embed/hostEventClient/host-event-client.ts +16 -0
  206. package/src/embed/hostEventClient/utils.spec.ts +204 -0
  207. package/src/embed/hostEventClient/utils.ts +37 -10
  208. package/src/embed/liveboard.spec.ts +108 -2
  209. package/src/embed/liveboard.ts +82 -14
  210. package/src/embed/spotter-utils.spec.ts +68 -1
  211. package/src/embed/spotter-utils.ts +16 -1
  212. package/src/embed/spotter-viz-utils.spec.ts +17 -0
  213. package/src/embed/spotter-viz-utils.ts +34 -0
  214. package/src/embed/ts-embed.spec.ts +186 -0
  215. package/src/embed/ts-embed.ts +30 -4
  216. package/src/errors.ts +1 -0
  217. package/src/index.ts +3 -1
  218. package/src/mixpanel-service.ts +4 -0
  219. package/src/react/util.spec.tsx +255 -0
  220. package/src/types.ts +575 -8
  221. package/src/utils/processData.spec.ts +97 -0
  222. package/src/utils/processTrigger.spec.ts +91 -0
@@ -38,6 +38,52 @@ describe('test communication between host app and ThoughtSpot', () => {
38
38
  });
39
39
  });
40
40
  });
41
+ test('should capture SpotterResponseComplete event from ThoughtSpot app', (done) => {
42
+ const appEmbed = new AppEmbed(getRootEl(), defaultViewConfig);
43
+ appEmbed
44
+ .on(EmbedEvent.SpotterResponseComplete, (data) => {
45
+ expect(data.data).toEqual({ convId: 'c1', messageId: 'm1' });
46
+ done();
47
+ })
48
+ .render();
49
+ executeAfterWait(() => {
50
+ const iframe = getIFrameEl();
51
+ postMessageToParent(iframe.contentWindow, {
52
+ type: EmbedEvent.SpotterResponseComplete,
53
+ data: { convId: 'c1', messageId: 'm1' },
54
+ });
55
+ });
56
+ });
57
+ test('should trigger PinSpotterConversation host event to ThoughtSpot app', async () => {
58
+ mockMessageChannel();
59
+ const appEmbed = new AppEmbed(getRootEl(), defaultViewConfig);
60
+ await appEmbed.render();
61
+ const iframe = getIFrameEl();
62
+ jest.spyOn(iframe.contentWindow, 'postMessage');
63
+ await executeAfterWait(() => {
64
+ appEmbed.trigger(HostEvent.PinSpotterConversation, {
65
+ conversationId: 'c1',
66
+ });
67
+ expect(iframe.contentWindow.postMessage).toHaveBeenCalledWith(expect.objectContaining({
68
+ type: HostEvent.PinSpotterConversation,
69
+ }), expect.anything(), expect.anything());
70
+ });
71
+ });
72
+ test('should trigger UnpinSpotterConversation host event to ThoughtSpot app', async () => {
73
+ mockMessageChannel();
74
+ const appEmbed = new AppEmbed(getRootEl(), defaultViewConfig);
75
+ await appEmbed.render();
76
+ const iframe = getIFrameEl();
77
+ jest.spyOn(iframe.contentWindow, 'postMessage');
78
+ await executeAfterWait(() => {
79
+ appEmbed.trigger(HostEvent.UnpinSpotterConversation, {
80
+ conversationId: 'c1',
81
+ });
82
+ expect(iframe.contentWindow.postMessage).toHaveBeenCalledWith(expect.objectContaining({
83
+ type: HostEvent.UnpinSpotterConversation,
84
+ }), expect.anything(), expect.anything());
85
+ });
86
+ });
41
87
  // TODO: enable test once we are actually able to load stuff in the iframe
42
88
  xtest('should trigger iframe load event', async () => {
43
89
  const onLoadSpy = jest.fn();
@@ -263,6 +309,36 @@ describe('test communication between host app and ThoughtSpot', () => {
263
309
  expect(handler.mock.calls[0][0].data).toBe(PAYLOAD);
264
310
  }, EVENT_WAIT_TIME);
265
311
  });
312
+ test('should fire QueryChanged handler when {type:queryChanged} postMessage arrives from iframe', async () => {
313
+ const handler = jest.fn();
314
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
315
+ searchEmbed.on(EmbedEvent.QueryChanged, handler).render();
316
+ await executeAfterWait(() => {
317
+ const iframe = getIFrameEl();
318
+ postMessageToParent(iframe.contentWindow, {
319
+ type: EmbedEvent.QueryChanged,
320
+ data: PAYLOAD,
321
+ });
322
+ });
323
+ await executeAfterWait(() => {
324
+ expect(handler).toHaveBeenCalled();
325
+ expect(handler.mock.calls[0][0].data).toBe(PAYLOAD);
326
+ }, EVENT_WAIT_TIME);
327
+ });
328
+ test('should not fire QueryChanged handler for postMessage from non-iframe source', async () => {
329
+ const handler = jest.fn();
330
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
331
+ searchEmbed.on(EmbedEvent.QueryChanged, handler).render();
332
+ await executeAfterWait(() => {
333
+ postMessageToParent(window, {
334
+ type: EmbedEvent.QueryChanged,
335
+ data: PAYLOAD,
336
+ });
337
+ });
338
+ await executeAfterWait(() => {
339
+ expect(handler).not.toHaveBeenCalled();
340
+ }, EVENT_WAIT_TIME);
341
+ });
266
342
  test('ALL event listener should fire for all events with the event type set correctly', async () => {
267
343
  const embed = new AppEmbed(getRootEl(), defaultViewConfig);
268
344
  const spy = jest.fn();
@@ -313,4 +389,563 @@ describe('Action enum values', () => {
313
389
  expect(Action.RemoveFromFavorites).toBe('removeFromFavorites');
314
390
  });
315
391
  });
392
+ describe('EmbedEvent basic routing', () => {
393
+ beforeEach(() => {
394
+ document.body.innerHTML = getDocumentBody();
395
+ });
396
+ const UNCOVERED_EVENTS = [
397
+ ['Drilldown', EmbedEvent.Drilldown],
398
+ ['DataSourceSelected', EmbedEvent.DataSourceSelected],
399
+ ['AddRemoveColumns', EmbedEvent.AddRemoveColumns],
400
+ ['VizPointDoubleClick', EmbedEvent.VizPointDoubleClick],
401
+ ['VizPointClick', EmbedEvent.VizPointClick],
402
+ ['Alert', EmbedEvent.Alert],
403
+ ['GetDataClick', EmbedEvent.GetDataClick],
404
+ ['DialogClose', EmbedEvent.DialogClose],
405
+ ['Download', EmbedEvent.Download],
406
+ ['DownloadAsPng', EmbedEvent.DownloadAsPng],
407
+ ['DownloadAsPdf', EmbedEvent.DownloadAsPdf],
408
+ ['DownloadAsCsv', EmbedEvent.DownloadAsCsv],
409
+ ['DownloadAsXlsx', EmbedEvent.DownloadAsXlsx],
410
+ ['DownloadLiveboardAsContinuousPDF', EmbedEvent.DownloadLiveboardAsContinuousPDF],
411
+ ['AnswerDelete', EmbedEvent.AnswerDelete],
412
+ ['AIHighlights', EmbedEvent.AIHighlights],
413
+ ['Pin', EmbedEvent.Pin],
414
+ ['SpotIQAnalyze', EmbedEvent.SpotIQAnalyze],
415
+ ['Share', EmbedEvent.Share],
416
+ ['DrillInclude', EmbedEvent.DrillInclude],
417
+ ['DrillExclude', EmbedEvent.DrillExclude],
418
+ ['CopyToClipboard', EmbedEvent.CopyToClipboard],
419
+ ['UpdateTML', EmbedEvent.UpdateTML],
420
+ ['EditTML', EmbedEvent.EditTML],
421
+ ['ExportTML', EmbedEvent.ExportTML],
422
+ ['SaveAsView', EmbedEvent.SaveAsView],
423
+ ['CopyAEdit', EmbedEvent.CopyAEdit],
424
+ ['ShowUnderlyingData', EmbedEvent.ShowUnderlyingData],
425
+ ['AnswerChartSwitcher', EmbedEvent.AnswerChartSwitcher],
426
+ ['LiveboardInfo', EmbedEvent.LiveboardInfo],
427
+ ['AddToFavorites', EmbedEvent.AddToFavorites],
428
+ ['Schedule', EmbedEvent.Schedule],
429
+ ['Edit', EmbedEvent.Edit],
430
+ ['MakeACopy', EmbedEvent.MakeACopy],
431
+ ['Present', EmbedEvent.Present],
432
+ ['Delete', EmbedEvent.Delete],
433
+ ['SchedulesList', EmbedEvent.SchedulesList],
434
+ ['Cancel', EmbedEvent.Cancel],
435
+ ['Explore', EmbedEvent.Explore],
436
+ ['CopyLink', EmbedEvent.CopyLink],
437
+ ['CrossFilterChanged', EmbedEvent.CrossFilterChanged],
438
+ ['VizPointRightClick', EmbedEvent.VizPointRightClick],
439
+ ['InsertIntoSlide', EmbedEvent.InsertIntoSlide],
440
+ ['FilterChanged', EmbedEvent.FilterChanged],
441
+ ['UpdateConnection', EmbedEvent.UpdateConnection],
442
+ ['CreateConnection', EmbedEvent.CreateConnection],
443
+ ['ResetLiveboard', EmbedEvent.ResetLiveboard],
444
+ ['ChangePersonalizedView', EmbedEvent.ChangePersonalizedView],
445
+ ['CreateWorksheet', EmbedEvent.CreateWorksheet],
446
+ ['AskSageInit', EmbedEvent.AskSageInit],
447
+ ['Rename', EmbedEvent.Rename],
448
+ ['ParameterChanged', EmbedEvent.ParameterChanged],
449
+ ['TableVizRendered', EmbedEvent.TableVizRendered],
450
+ ['CreateLiveboard', EmbedEvent.CreateLiveboard],
451
+ ['CreateModel', EmbedEvent.CreateModel],
452
+ ['SpotterData', EmbedEvent.SpotterData],
453
+ ['PreviewSpotterData', EmbedEvent.PreviewSpotterData],
454
+ ['AddToCoaching', EmbedEvent.AddToCoaching],
455
+ ['DataModelInstructions', EmbedEvent.DataModelInstructions],
456
+ ['SpotterQueryTriggered', EmbedEvent.SpotterQueryTriggered],
457
+ ['LastPromptEdited', EmbedEvent.LastPromptEdited],
458
+ ['LastPromptDeleted', EmbedEvent.LastPromptDeleted],
459
+ ['ResetSpotterConversation', EmbedEvent.ResetSpotterConversation],
460
+ ['SpotterInit', EmbedEvent.SpotterInit],
461
+ ['SpotterLoadComplete', EmbedEvent.SpotterLoadComplete],
462
+ ['OrgSwitched', EmbedEvent.OrgSwitched],
463
+ ['SpotterConversationRenamed', EmbedEvent.SpotterConversationRenamed],
464
+ ['SpotterConversationDeleted', EmbedEvent.SpotterConversationDeleted],
465
+ ['SpotterConversationSelected', EmbedEvent.SpotterConversationSelected],
466
+ ['SpotterConversationPinned', EmbedEvent.SpotterConversationPinned],
467
+ ['SpotterConversationUnpinned', EmbedEvent.SpotterConversationUnpinned],
468
+ ['EmbedPageContextChanged', EmbedEvent.EmbedPageContextChanged],
469
+ ['Subscribed', EmbedEvent.Subscribed],
470
+ ['SendTestScheduleEmail', EmbedEvent.SendTestScheduleEmail],
471
+ ['SpotterVizInit', EmbedEvent.SpotterVizInit],
472
+ ['SpotterVizQueryTriggered', EmbedEvent.SpotterVizQueryTriggered],
473
+ ['SpotterVizResponseComplete', EmbedEvent.SpotterVizResponseComplete],
474
+ ['SpotterVizCheckpointCreated', EmbedEvent.SpotterVizCheckpointCreated],
475
+ ['SpotterVizCheckpointRestored', EmbedEvent.SpotterVizCheckpointRestored],
476
+ ['SpotterVizError', EmbedEvent.SpotterVizError],
477
+ ['SpotterVizClosed', EmbedEvent.SpotterVizClosed],
478
+ ['RefreshLiveboardBrowserCache', EmbedEvent.RefreshLiveboardBrowserCache],
479
+ ['V1Data', EmbedEvent.V1Data],
480
+ ['SpotterShareConversationButtonHeaderClicked', EmbedEvent.SpotterShareConversationButtonHeaderClicked],
481
+ ['SpotterShareConversationMenuItemSidebarClicked', EmbedEvent.SpotterShareConversationMenuItemSidebarClicked],
482
+ ['SpotterConversationShared', EmbedEvent.SpotterConversationShared],
483
+ ['SpotterConversationShareRevoked', EmbedEvent.SpotterConversationShareRevoked],
484
+ ['SpotterSharedConversationViewed', EmbedEvent.SpotterSharedConversationViewed],
485
+ ['SpotterShareIncludeNewMessagesCheckboxToggled', EmbedEvent.SpotterShareIncludeNewMessagesCheckboxToggled],
486
+ ['SpotterShareStaleInfoBannerDismissed', EmbedEvent.SpotterShareStaleInfoBannerDismissed],
487
+ ['SpotterShareModalConfirmButtonClicked', EmbedEvent.SpotterShareModalConfirmButtonClicked],
488
+ ['SpotterShareModalCancelButtonClicked', EmbedEvent.SpotterShareModalCancelButtonClicked],
489
+ ['SpotterSharedConversationExitButtonClicked', EmbedEvent.SpotterSharedConversationExitButtonClicked],
490
+ ];
491
+ test.each(UNCOVERED_EVENTS)('%s handler fires on iframe postMessage', async (eventName, embedEvent) => {
492
+ const handler = jest.fn();
493
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
494
+ searchEmbed.on(embedEvent, handler).render();
495
+ await executeAfterWait(() => {
496
+ const iframe = getIFrameEl();
497
+ postMessageToParent(iframe.contentWindow, {
498
+ type: embedEvent,
499
+ data: PAYLOAD,
500
+ });
501
+ });
502
+ await executeAfterWait(() => {
503
+ expect(handler).toHaveBeenCalled();
504
+ expect(handler.mock.calls[0][0].data).toBe(PAYLOAD);
505
+ }, EVENT_WAIT_TIME);
506
+ });
507
+ });
508
+ describe('EmbedEvent start/end status', () => {
509
+ beforeEach(() => {
510
+ document.body.innerHTML = getDocumentBody();
511
+ });
512
+ const START_END_EVENTS = [
513
+ ['DownloadAsPng', EmbedEvent.DownloadAsPng],
514
+ ['DownloadAsPdf', EmbedEvent.DownloadAsPdf],
515
+ ['DownloadAsCsv', EmbedEvent.DownloadAsCsv],
516
+ ['DownloadAsXlsx', EmbedEvent.DownloadAsXlsx],
517
+ ['AnswerDelete', EmbedEvent.AnswerDelete],
518
+ ['Pin', EmbedEvent.Pin],
519
+ ['SpotIQAnalyze', EmbedEvent.SpotIQAnalyze],
520
+ ['Share', EmbedEvent.Share],
521
+ ['ExportTML', EmbedEvent.ExportTML],
522
+ ['CopyAEdit', EmbedEvent.CopyAEdit],
523
+ ];
524
+ test.each(START_END_EVENTS)('%s start handler fires on START, not END', async (eventName, embedEvent) => {
525
+ const startHandler = jest.fn();
526
+ const endHandler = jest.fn();
527
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
528
+ searchEmbed
529
+ .on(embedEvent, startHandler, { start: true })
530
+ .on(embedEvent, endHandler)
531
+ .render();
532
+ await executeAfterWait(() => {
533
+ const iframe = getIFrameEl();
534
+ postMessageToParent(iframe.contentWindow, {
535
+ type: embedEvent,
536
+ data: PAYLOAD,
537
+ status: 'start',
538
+ });
539
+ });
540
+ await executeAfterWait(() => {
541
+ expect(startHandler).toHaveBeenCalled();
542
+ expect(endHandler).not.toHaveBeenCalled();
543
+ }, EVENT_WAIT_TIME);
544
+ });
545
+ test.each(START_END_EVENTS)('%s end handler fires on END, not START', async (eventName, embedEvent) => {
546
+ const startHandler = jest.fn();
547
+ const endHandler = jest.fn();
548
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
549
+ searchEmbed
550
+ .on(embedEvent, startHandler, { start: true })
551
+ .on(embedEvent, endHandler)
552
+ .render();
553
+ await executeAfterWait(() => {
554
+ const iframe = getIFrameEl();
555
+ postMessageToParent(iframe.contentWindow, {
556
+ type: embedEvent,
557
+ data: PAYLOAD,
558
+ status: 'end',
559
+ });
560
+ });
561
+ await executeAfterWait(() => {
562
+ expect(endHandler).toHaveBeenCalled();
563
+ expect(startHandler).not.toHaveBeenCalled();
564
+ }, EVENT_WAIT_TIME);
565
+ });
566
+ const END_ONLY_EVENTS = [
567
+ ['Download', EmbedEvent.Download],
568
+ ['DownloadLiveboardAsContinuousPDF', EmbedEvent.DownloadLiveboardAsContinuousPDF],
569
+ ];
570
+ test.each(END_ONLY_EVENTS)('%s ignores start handler (end-only event)', async (eventName, embedEvent) => {
571
+ const startHandler = jest.fn();
572
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
573
+ searchEmbed.on(embedEvent, startHandler, { start: true }).render();
574
+ await executeAfterWait(() => {
575
+ const iframe = getIFrameEl();
576
+ postMessageToParent(iframe.contentWindow, {
577
+ type: embedEvent,
578
+ data: PAYLOAD,
579
+ });
580
+ });
581
+ await executeAfterWait(() => {
582
+ expect(startHandler).not.toHaveBeenCalled();
583
+ }, EVENT_WAIT_TIME);
584
+ });
585
+ });
586
+ describe('EmbedEvent payload and routing', () => {
587
+ beforeEach(() => {
588
+ document.body.innerHTML = getDocumentBody();
589
+ });
590
+ test('Drilldown payload includes additionalFilters, drillDownColumns, nonFilteredColumns', async () => {
591
+ const handler = jest.fn();
592
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
593
+ searchEmbed.on(EmbedEvent.Drilldown, handler).render();
594
+ const drilldownData = {
595
+ additionalFilters: [{ column: 'region', value: 'west' }],
596
+ drillDownColumns: ['revenue'],
597
+ nonFilteredColumns: ['date'],
598
+ };
599
+ await executeAfterWait(() => {
600
+ const iframe = getIFrameEl();
601
+ postMessageToParent(iframe.contentWindow, {
602
+ type: EmbedEvent.Drilldown,
603
+ data: drilldownData,
604
+ });
605
+ });
606
+ await executeAfterWait(() => {
607
+ expect(handler).toHaveBeenCalled();
608
+ const received = handler.mock.calls[0][0].data;
609
+ expect(received.additionalFilters).toEqual(drilldownData.additionalFilters);
610
+ expect(received.drillDownColumns).toEqual(drilldownData.drillDownColumns);
611
+ expect(received.nonFilteredColumns).toEqual(drilldownData.nonFilteredColumns);
612
+ }, EVENT_WAIT_TIME);
613
+ });
614
+ test('DataSourceSelected payload contains dataSourceIds array', async () => {
615
+ const handler = jest.fn();
616
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
617
+ searchEmbed.on(EmbedEvent.DataSourceSelected, handler).render();
618
+ const dataSourceIds = ['ds-aaa', 'ds-bbb'];
619
+ await executeAfterWait(() => {
620
+ const iframe = getIFrameEl();
621
+ postMessageToParent(iframe.contentWindow, {
622
+ type: EmbedEvent.DataSourceSelected,
623
+ data: { dataSourceIds },
624
+ });
625
+ });
626
+ await executeAfterWait(() => {
627
+ expect(handler).toHaveBeenCalled();
628
+ expect(handler.mock.calls[0][0].data.dataSourceIds).toEqual(dataSourceIds);
629
+ }, EVENT_WAIT_TIME);
630
+ });
631
+ test('V1Data fires via __type field when type is absent', async () => {
632
+ const handler = jest.fn();
633
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
634
+ searchEmbed.on(EmbedEvent.V1Data, handler).render();
635
+ await executeAfterWait(() => {
636
+ const iframe = getIFrameEl();
637
+ postMessageToParent(iframe.contentWindow, {
638
+ __type: EmbedEvent.V1Data,
639
+ data: PAYLOAD,
640
+ });
641
+ });
642
+ await executeAfterWait(() => {
643
+ expect(handler).toHaveBeenCalled();
644
+ }, EVENT_WAIT_TIME);
645
+ });
646
+ test('subscribedEvent builds composed key and routes to registered handler', async () => {
647
+ const handler = jest.fn();
648
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
649
+ const composedEvent = searchEmbed.subscribedEvent(HostEvent.Save);
650
+ expect(composedEvent).toBe(`${HostEvent.Save} ${EmbedEvent.Subscribed}`);
651
+ searchEmbed.on(composedEvent, handler).render();
652
+ await executeAfterWait(() => {
653
+ const iframe = getIFrameEl();
654
+ postMessageToParent(iframe.contentWindow, {
655
+ type: composedEvent,
656
+ data: PAYLOAD,
657
+ });
658
+ });
659
+ await executeAfterWait(() => {
660
+ expect(handler).toHaveBeenCalled();
661
+ }, EVENT_WAIT_TIME);
662
+ });
663
+ test('non-iframe postMessage does not trigger registered handler', async () => {
664
+ const handler = jest.fn();
665
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
666
+ searchEmbed.on(EmbedEvent.Drilldown, handler).render();
667
+ await executeAfterWait(() => {
668
+ postMessageToParent(window, {
669
+ type: EmbedEvent.Drilldown,
670
+ data: PAYLOAD,
671
+ });
672
+ });
673
+ await executeAfterWait(() => {
674
+ expect(handler).not.toHaveBeenCalled();
675
+ }, EVENT_WAIT_TIME);
676
+ });
677
+ test('DataSourceSelected falls back to payload field when data is absent', async () => {
678
+ const handler = jest.fn();
679
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
680
+ searchEmbed.on(EmbedEvent.DataSourceSelected, handler).render();
681
+ const dataSourceIds = ['ds-fallback'];
682
+ await executeAfterWait(() => {
683
+ const iframe = getIFrameEl();
684
+ postMessageToParent(iframe.contentWindow, {
685
+ type: EmbedEvent.DataSourceSelected,
686
+ payload: { dataSourceIds },
687
+ // no data field — formatEventData should copy payload → data
688
+ });
689
+ });
690
+ await executeAfterWait(() => {
691
+ expect(handler).toHaveBeenCalled();
692
+ expect(handler.mock.calls[0][0].data.dataSourceIds).toEqual(dataSourceIds);
693
+ }, EVENT_WAIT_TIME);
694
+ });
695
+ test('Alert handler fires independently of window.alert', async () => {
696
+ const alertSpy = jest.spyOn(window, 'alert').mockImplementation(() => undefined);
697
+ const handler = jest.fn();
698
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
699
+ searchEmbed.on(EmbedEvent.Alert, handler).render();
700
+ await executeAfterWait(() => {
701
+ const iframe = getIFrameEl();
702
+ postMessageToParent(iframe.contentWindow, {
703
+ type: EmbedEvent.Alert,
704
+ data: { message: 'test alert' },
705
+ });
706
+ });
707
+ await executeAfterWait(() => {
708
+ expect(handler).toHaveBeenCalled();
709
+ expect(alertSpy).not.toHaveBeenCalled();
710
+ }, EVENT_WAIT_TIME);
711
+ alertSpy.mockRestore();
712
+ });
713
+ test('Share reaches EmbedEvent.ALL wildcard handler', async () => {
714
+ const allHandler = jest.fn();
715
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
716
+ searchEmbed.on(EmbedEvent.ALL, allHandler).render();
717
+ await executeAfterWait(() => {
718
+ const iframe = getIFrameEl();
719
+ postMessageToParent(iframe.contentWindow, {
720
+ type: EmbedEvent.Share,
721
+ data: PAYLOAD,
722
+ });
723
+ });
724
+ await executeAfterWait(() => {
725
+ const types = allHandler.mock.calls.map((c) => c[0].type);
726
+ expect(types).toContain(EmbedEvent.Share);
727
+ }, EVENT_WAIT_TIME);
728
+ });
729
+ test('DialogClose reaches EmbedEvent.ALL wildcard handler', async () => {
730
+ const allHandler = jest.fn();
731
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
732
+ searchEmbed.on(EmbedEvent.ALL, allHandler).render();
733
+ await executeAfterWait(() => {
734
+ const iframe = getIFrameEl();
735
+ postMessageToParent(iframe.contentWindow, {
736
+ type: EmbedEvent.DialogClose,
737
+ data: PAYLOAD,
738
+ });
739
+ });
740
+ await executeAfterWait(() => {
741
+ const types = allHandler.mock.calls.map((c) => c[0].type);
742
+ expect(types).toContain(EmbedEvent.DialogClose);
743
+ }, EVENT_WAIT_TIME);
744
+ });
745
+ test('SpotterConversationRenamed payload contains convId, oldTitle, newTitle', async () => {
746
+ const handler = jest.fn();
747
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
748
+ searchEmbed.on(EmbedEvent.SpotterConversationRenamed, handler).render();
749
+ const convData = { convId: 'conv-1', oldTitle: 'Old', newTitle: 'New' };
750
+ await executeAfterWait(() => {
751
+ const iframe = getIFrameEl();
752
+ postMessageToParent(iframe.contentWindow, {
753
+ type: EmbedEvent.SpotterConversationRenamed,
754
+ data: convData,
755
+ });
756
+ });
757
+ await executeAfterWait(() => {
758
+ expect(handler).toHaveBeenCalled();
759
+ expect(handler.mock.calls[0][0].data).toMatchObject(convData);
760
+ }, EVENT_WAIT_TIME);
761
+ });
762
+ test('SpotterConversationDeleted payload contains convId and title', async () => {
763
+ const handler = jest.fn();
764
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
765
+ searchEmbed.on(EmbedEvent.SpotterConversationDeleted, handler).render();
766
+ const convData = { convId: 'conv-2', title: 'My Conversation' };
767
+ await executeAfterWait(() => {
768
+ const iframe = getIFrameEl();
769
+ postMessageToParent(iframe.contentWindow, {
770
+ type: EmbedEvent.SpotterConversationDeleted,
771
+ data: convData,
772
+ });
773
+ });
774
+ await executeAfterWait(() => {
775
+ expect(handler).toHaveBeenCalled();
776
+ expect(handler.mock.calls[0][0].data).toMatchObject(convData);
777
+ }, EVENT_WAIT_TIME);
778
+ });
779
+ test('SpotterConversationSelected payload contains convId, title, worksheetId', async () => {
780
+ const handler = jest.fn();
781
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
782
+ searchEmbed.on(EmbedEvent.SpotterConversationSelected, handler).render();
783
+ const convData = { convId: 'conv-3', title: 'My Conv', worksheetId: 'ws-1' };
784
+ await executeAfterWait(() => {
785
+ const iframe = getIFrameEl();
786
+ postMessageToParent(iframe.contentWindow, {
787
+ type: EmbedEvent.SpotterConversationSelected,
788
+ data: convData,
789
+ });
790
+ });
791
+ await executeAfterWait(() => {
792
+ expect(handler).toHaveBeenCalled();
793
+ expect(handler.mock.calls[0][0].data).toMatchObject(convData);
794
+ }, EVENT_WAIT_TIME);
795
+ });
796
+ test('TableVizRendered payload forwards columnDataLite array intact', async () => {
797
+ const handler = jest.fn();
798
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
799
+ searchEmbed.on(EmbedEvent.TableVizRendered, handler).render();
800
+ const columnDataLite = [['col1', 'col2'], ['val1', 'val2']];
801
+ await executeAfterWait(() => {
802
+ const iframe = getIFrameEl();
803
+ postMessageToParent(iframe.contentWindow, {
804
+ type: EmbedEvent.TableVizRendered,
805
+ data: { data: { columnDataLite } },
806
+ });
807
+ });
808
+ await executeAfterWait(() => {
809
+ expect(handler).toHaveBeenCalled();
810
+ expect(handler.mock.calls[0][0].data.data.columnDataLite).toEqual(columnDataLite);
811
+ }, EVENT_WAIT_TIME);
812
+ });
813
+ test('SendTestScheduleEmail payload preserves liveboardId and sendToSelf boolean', async () => {
814
+ const handler = jest.fn();
815
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
816
+ searchEmbed.on(EmbedEvent.SendTestScheduleEmail, handler).render();
817
+ const emailData = { liveboardId: 'lb-123', sendToSelf: true };
818
+ await executeAfterWait(() => {
819
+ const iframe = getIFrameEl();
820
+ postMessageToParent(iframe.contentWindow, {
821
+ type: EmbedEvent.SendTestScheduleEmail,
822
+ data: emailData,
823
+ });
824
+ });
825
+ await executeAfterWait(() => {
826
+ expect(handler).toHaveBeenCalled();
827
+ const received = handler.mock.calls[0][0].data;
828
+ expect(received.liveboardId).toBe('lb-123');
829
+ expect(received.sendToSelf).toBe(true);
830
+ expect(typeof received.sendToSelf).toBe('boolean');
831
+ }, EVENT_WAIT_TIME);
832
+ });
833
+ test('ChangePersonalizedView payload viewId can be null (reset-to-default)', async () => {
834
+ const handler = jest.fn();
835
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
836
+ searchEmbed.on(EmbedEvent.ChangePersonalizedView, handler).render();
837
+ await executeAfterWait(() => {
838
+ const iframe = getIFrameEl();
839
+ postMessageToParent(iframe.contentWindow, {
840
+ type: EmbedEvent.ChangePersonalizedView,
841
+ data: { viewId: null, viewName: 'Original View', liveboardId: 'lb-1', isPublic: false },
842
+ });
843
+ });
844
+ await executeAfterWait(() => {
845
+ expect(handler).toHaveBeenCalled();
846
+ expect(handler.mock.calls[0][0].data.viewId).toBeNull();
847
+ expect(handler.mock.calls[0][0].data.viewName).toBe('Original View');
848
+ }, EVENT_WAIT_TIME);
849
+ });
850
+ test('VizPointDoubleClick payload exposes vizId and clickedPoint.selectedPoints', async () => {
851
+ const handler = jest.fn();
852
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
853
+ searchEmbed.on(EmbedEvent.VizPointDoubleClick, handler).render();
854
+ const pointData = {
855
+ vizId: 'viz-1',
856
+ clickedPoint: { selectedPoints: [{ x: 10, y: 20 }] },
857
+ };
858
+ await executeAfterWait(() => {
859
+ const iframe = getIFrameEl();
860
+ postMessageToParent(iframe.contentWindow, {
861
+ type: EmbedEvent.VizPointDoubleClick,
862
+ data: pointData,
863
+ });
864
+ });
865
+ await executeAfterWait(() => {
866
+ expect(handler).toHaveBeenCalled();
867
+ const { data } = handler.mock.calls[0][0];
868
+ expect(data.vizId).toBe('viz-1');
869
+ expect(data.clickedPoint.selectedPoints).toEqual(pointData.clickedPoint.selectedPoints);
870
+ }, EVENT_WAIT_TIME);
871
+ });
872
+ test('VizPointClick payload exposes vizId, selectedAttributes and selectedMeasures', async () => {
873
+ const handler = jest.fn();
874
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
875
+ searchEmbed.on(EmbedEvent.VizPointClick, handler).render();
876
+ const pointData = {
877
+ vizId: 'viz-2',
878
+ clickedPoint: {
879
+ selectedAttributes: [{ value: 'West', column: { name: 'region' } }],
880
+ selectedMeasures: [{ value: 42, column: { name: 'revenue' } }],
881
+ },
882
+ };
883
+ await executeAfterWait(() => {
884
+ const iframe = getIFrameEl();
885
+ postMessageToParent(iframe.contentWindow, {
886
+ type: EmbedEvent.VizPointClick,
887
+ data: pointData,
888
+ });
889
+ });
890
+ await executeAfterWait(() => {
891
+ expect(handler).toHaveBeenCalled();
892
+ const { data } = handler.mock.calls[0][0];
893
+ expect(data.vizId).toBe('viz-2');
894
+ expect(data.clickedPoint.selectedAttributes[0].value).toBe('West');
895
+ expect(data.clickedPoint.selectedAttributes[0].column.name).toBe('region');
896
+ expect(data.clickedPoint.selectedMeasures[0].value).toBe(42);
897
+ expect(data.clickedPoint.selectedMeasures[0].column.name).toBe('revenue');
898
+ }, EVENT_WAIT_TIME);
899
+ });
900
+ test('SpotterVizError reaches EmbedEvent.ALL handler', async () => {
901
+ const allHandler = jest.fn();
902
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
903
+ searchEmbed.on(EmbedEvent.ALL, allHandler).render();
904
+ await executeAfterWait(() => {
905
+ const iframe = getIFrameEl();
906
+ postMessageToParent(iframe.contentWindow, {
907
+ type: EmbedEvent.SpotterVizError,
908
+ data: PAYLOAD,
909
+ });
910
+ });
911
+ await executeAfterWait(() => {
912
+ const types = allHandler.mock.calls.map((c) => c[0].type);
913
+ expect(types).toContain(EmbedEvent.SpotterVizError);
914
+ }, EVENT_WAIT_TIME);
915
+ });
916
+ test('SpotterVizClosed reaches EmbedEvent.ALL handler', async () => {
917
+ const allHandler = jest.fn();
918
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
919
+ searchEmbed.on(EmbedEvent.ALL, allHandler).render();
920
+ await executeAfterWait(() => {
921
+ const iframe = getIFrameEl();
922
+ postMessageToParent(iframe.contentWindow, {
923
+ type: EmbedEvent.SpotterVizClosed,
924
+ data: PAYLOAD,
925
+ });
926
+ });
927
+ await executeAfterWait(() => {
928
+ const types = allHandler.mock.calls.map((c) => c[0].type);
929
+ expect(types).toContain(EmbedEvent.SpotterVizClosed);
930
+ }, EVENT_WAIT_TIME);
931
+ });
932
+ test('SpotterVizCheckpointRestored payload newGenNumber is a number', async () => {
933
+ const handler = jest.fn();
934
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
935
+ searchEmbed.on(EmbedEvent.SpotterVizCheckpointRestored, handler).render();
936
+ await executeAfterWait(() => {
937
+ const iframe = getIFrameEl();
938
+ postMessageToParent(iframe.contentWindow, {
939
+ type: EmbedEvent.SpotterVizCheckpointRestored,
940
+ data: { checkpointId: 'cp-1', newGenNumber: 42 },
941
+ });
942
+ });
943
+ await executeAfterWait(() => {
944
+ expect(handler).toHaveBeenCalled();
945
+ const { newGenNumber } = handler.mock.calls[0][0].data;
946
+ expect(newGenNumber).toBe(42);
947
+ expect(typeof newGenNumber).toBe('number');
948
+ }, EVENT_WAIT_TIME);
949
+ });
950
+ });
316
951
  //# sourceMappingURL=events.spec.js.map