@thoughtspot/visual-embed-sdk 1.51.0 → 1.51.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/config.d.ts +1 -0
  3. package/cjs/src/config.d.ts.map +1 -1
  4. package/cjs/src/config.js +2 -1
  5. package/cjs/src/config.js.map +1 -1
  6. package/cjs/src/css-variables.d.ts +27 -0
  7. package/cjs/src/css-variables.d.ts.map +1 -1
  8. package/cjs/src/embed/app.d.ts +43 -12
  9. package/cjs/src/embed/app.d.ts.map +1 -1
  10. package/cjs/src/embed/app.js +29 -3
  11. package/cjs/src/embed/app.js.map +1 -1
  12. package/cjs/src/embed/app.spec.js +253 -1
  13. package/cjs/src/embed/app.spec.js.map +1 -1
  14. package/cjs/src/embed/base.d.ts +1 -1
  15. package/cjs/src/embed/base.js +1 -1
  16. package/cjs/src/embed/conversation.d.ts +171 -1
  17. package/cjs/src/embed/conversation.d.ts.map +1 -1
  18. package/cjs/src/embed/conversation.js +4 -2
  19. package/cjs/src/embed/conversation.js.map +1 -1
  20. package/cjs/src/embed/conversation.spec.js +125 -0
  21. package/cjs/src/embed/conversation.spec.js.map +1 -1
  22. package/cjs/src/embed/events.spec.js +3 -0
  23. package/cjs/src/embed/events.spec.js.map +1 -1
  24. package/cjs/src/embed/host-events.spec.js +36 -0
  25. package/cjs/src/embed/host-events.spec.js.map +1 -1
  26. package/cjs/src/embed/hostEventClient/host-event-client.d.ts +1 -1
  27. package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  28. package/cjs/src/embed/hostEventClient/host-event-client.spec.js +18 -0
  29. package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  30. package/cjs/src/embed/liveboard.d.ts +40 -13
  31. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  32. package/cjs/src/embed/liveboard.js +25 -4
  33. package/cjs/src/embed/liveboard.js.map +1 -1
  34. package/cjs/src/embed/liveboard.spec.js +349 -2
  35. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  36. package/cjs/src/embed/spotter-utils.d.ts +8 -1
  37. package/cjs/src/embed/spotter-utils.d.ts.map +1 -1
  38. package/cjs/src/embed/spotter-utils.js +15 -1
  39. package/cjs/src/embed/spotter-utils.js.map +1 -1
  40. package/cjs/src/embed/spotter-utils.spec.js +68 -0
  41. package/cjs/src/embed/spotter-utils.spec.js.map +1 -1
  42. package/cjs/src/embed/spotter-viz-utils.d.ts +9 -10
  43. package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -1
  44. package/cjs/src/embed/spotter-viz-utils.js.map +1 -1
  45. package/cjs/src/embed/ts-embed.d.ts +16 -8
  46. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  47. package/cjs/src/embed/ts-embed.js +69 -32
  48. package/cjs/src/embed/ts-embed.js.map +1 -1
  49. package/cjs/src/embed/ts-embed.spec.js +537 -3
  50. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  51. package/cjs/src/index.d.ts +3 -3
  52. package/cjs/src/index.d.ts.map +1 -1
  53. package/cjs/src/index.js +3 -2
  54. package/cjs/src/index.js.map +1 -1
  55. package/cjs/src/react/all-types-export.d.ts +1 -1
  56. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  57. package/cjs/src/react/all-types-export.js +2 -1
  58. package/cjs/src/react/all-types-export.js.map +1 -1
  59. package/cjs/src/react/all-types-export.parity.spec.d.ts +2 -0
  60. package/cjs/src/react/all-types-export.parity.spec.d.ts.map +1 -0
  61. package/cjs/src/react/all-types-export.parity.spec.js +194 -0
  62. package/cjs/src/react/all-types-export.parity.spec.js.map +1 -0
  63. package/cjs/src/react/index.d.ts +66 -32
  64. package/cjs/src/react/index.d.ts.map +1 -1
  65. package/cjs/src/react/index.js +5 -3
  66. package/cjs/src/react/index.js.map +1 -1
  67. package/cjs/src/react/index.spec.js +101 -0
  68. package/cjs/src/react/index.spec.js.map +1 -1
  69. package/cjs/src/types.d.ts +330 -18
  70. package/cjs/src/types.d.ts.map +1 -1
  71. package/cjs/src/types.js +182 -12
  72. package/cjs/src/types.js.map +1 -1
  73. package/cjs/src/utils.spec.js +4 -0
  74. package/cjs/src/utils.spec.js.map +1 -1
  75. package/dist/{index-aBzH5ZwF.js → index-DxLfQxoT.js} +1 -1
  76. package/dist/src/config.d.ts +1 -0
  77. package/dist/src/config.d.ts.map +1 -1
  78. package/dist/src/css-variables.d.ts +27 -0
  79. package/dist/src/css-variables.d.ts.map +1 -1
  80. package/dist/src/embed/app.d.ts +43 -12
  81. package/dist/src/embed/app.d.ts.map +1 -1
  82. package/dist/src/embed/base.d.ts +1 -1
  83. package/dist/src/embed/conversation.d.ts +171 -1
  84. package/dist/src/embed/conversation.d.ts.map +1 -1
  85. package/dist/src/embed/hostEventClient/host-event-client.d.ts +1 -1
  86. package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  87. package/dist/src/embed/liveboard.d.ts +40 -13
  88. package/dist/src/embed/liveboard.d.ts.map +1 -1
  89. package/dist/src/embed/spotter-utils.d.ts +8 -1
  90. package/dist/src/embed/spotter-utils.d.ts.map +1 -1
  91. package/dist/src/embed/spotter-viz-utils.d.ts +9 -10
  92. package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
  93. package/dist/src/embed/ts-embed.d.ts +16 -8
  94. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  95. package/dist/src/index.d.ts +3 -3
  96. package/dist/src/index.d.ts.map +1 -1
  97. package/dist/src/react/all-types-export.d.ts +1 -1
  98. package/dist/src/react/all-types-export.d.ts.map +1 -1
  99. package/dist/src/react/all-types-export.parity.spec.d.ts +2 -0
  100. package/dist/src/react/all-types-export.parity.spec.d.ts.map +1 -0
  101. package/dist/src/react/index.d.ts +66 -32
  102. package/dist/src/react/index.d.ts.map +1 -1
  103. package/dist/src/types.d.ts +330 -18
  104. package/dist/src/types.d.ts.map +1 -1
  105. package/dist/tsembed-react.es.js +330 -61
  106. package/dist/tsembed-react.js +329 -60
  107. package/dist/tsembed.es.js +390 -123
  108. package/dist/tsembed.js +392 -125
  109. package/dist/visual-embed-sdk-react-full.d.ts +696 -89
  110. package/dist/visual-embed-sdk-react.d.ts +692 -88
  111. package/dist/visual-embed-sdk.d.ts +632 -59
  112. package/lib/package.json +1 -1
  113. package/lib/src/config.d.ts +1 -0
  114. package/lib/src/config.d.ts.map +1 -1
  115. package/lib/src/config.js +1 -0
  116. package/lib/src/config.js.map +1 -1
  117. package/lib/src/css-variables.d.ts +27 -0
  118. package/lib/src/css-variables.d.ts.map +1 -1
  119. package/lib/src/embed/app.d.ts +43 -12
  120. package/lib/src/embed/app.d.ts.map +1 -1
  121. package/lib/src/embed/app.js +30 -4
  122. package/lib/src/embed/app.js.map +1 -1
  123. package/lib/src/embed/app.spec.js +253 -1
  124. package/lib/src/embed/app.spec.js.map +1 -1
  125. package/lib/src/embed/base.d.ts +1 -1
  126. package/lib/src/embed/base.js +1 -1
  127. package/lib/src/embed/conversation.d.ts +171 -1
  128. package/lib/src/embed/conversation.d.ts.map +1 -1
  129. package/lib/src/embed/conversation.js +5 -3
  130. package/lib/src/embed/conversation.js.map +1 -1
  131. package/lib/src/embed/conversation.spec.js +125 -0
  132. package/lib/src/embed/conversation.spec.js.map +1 -1
  133. package/lib/src/embed/events.spec.js +3 -0
  134. package/lib/src/embed/events.spec.js.map +1 -1
  135. package/lib/src/embed/host-events.spec.js +36 -0
  136. package/lib/src/embed/host-events.spec.js.map +1 -1
  137. package/lib/src/embed/hostEventClient/host-event-client.d.ts +1 -1
  138. package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  139. package/lib/src/embed/hostEventClient/host-event-client.spec.js +18 -0
  140. package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  141. package/lib/src/embed/liveboard.d.ts +40 -13
  142. package/lib/src/embed/liveboard.d.ts.map +1 -1
  143. package/lib/src/embed/liveboard.js +25 -4
  144. package/lib/src/embed/liveboard.js.map +1 -1
  145. package/lib/src/embed/liveboard.spec.js +349 -2
  146. package/lib/src/embed/liveboard.spec.js.map +1 -1
  147. package/lib/src/embed/spotter-utils.d.ts +8 -1
  148. package/lib/src/embed/spotter-utils.d.ts.map +1 -1
  149. package/lib/src/embed/spotter-utils.js +13 -0
  150. package/lib/src/embed/spotter-utils.js.map +1 -1
  151. package/lib/src/embed/spotter-utils.spec.js +69 -1
  152. package/lib/src/embed/spotter-utils.spec.js.map +1 -1
  153. package/lib/src/embed/spotter-viz-utils.d.ts +9 -10
  154. package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
  155. package/lib/src/embed/spotter-viz-utils.js.map +1 -1
  156. package/lib/src/embed/ts-embed.d.ts +16 -8
  157. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  158. package/lib/src/embed/ts-embed.js +69 -32
  159. package/lib/src/embed/ts-embed.js.map +1 -1
  160. package/lib/src/embed/ts-embed.spec.js +537 -3
  161. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  162. package/lib/src/index.d.ts +3 -3
  163. package/lib/src/index.d.ts.map +1 -1
  164. package/lib/src/index.js +2 -2
  165. package/lib/src/index.js.map +1 -1
  166. package/lib/src/react/all-types-export.d.ts +1 -1
  167. package/lib/src/react/all-types-export.d.ts.map +1 -1
  168. package/lib/src/react/all-types-export.js +1 -1
  169. package/lib/src/react/all-types-export.js.map +1 -1
  170. package/lib/src/react/all-types-export.parity.spec.d.ts +2 -0
  171. package/lib/src/react/all-types-export.parity.spec.d.ts.map +1 -0
  172. package/lib/src/react/all-types-export.parity.spec.js +191 -0
  173. package/lib/src/react/all-types-export.parity.spec.js.map +1 -0
  174. package/lib/src/react/index.d.ts +66 -32
  175. package/lib/src/react/index.d.ts.map +1 -1
  176. package/lib/src/react/index.js +5 -3
  177. package/lib/src/react/index.js.map +1 -1
  178. package/lib/src/react/index.spec.js +102 -1
  179. package/lib/src/react/index.spec.js.map +1 -1
  180. package/lib/src/types.d.ts +330 -18
  181. package/lib/src/types.d.ts.map +1 -1
  182. package/lib/src/types.js +182 -12
  183. package/lib/src/types.js.map +1 -1
  184. package/lib/src/utils.spec.js +4 -0
  185. package/lib/src/utils.spec.js.map +1 -1
  186. package/lib/src/visual-embed-sdk.d.ts +632 -59
  187. package/package.json +1 -1
  188. package/src/config.ts +1 -0
  189. package/src/css-variables.ts +32 -0
  190. package/src/embed/app.spec.ts +335 -1
  191. package/src/embed/app.ts +71 -13
  192. package/src/embed/base.ts +1 -1
  193. package/src/embed/conversation.spec.ts +136 -0
  194. package/src/embed/conversation.ts +181 -3
  195. package/src/embed/events.spec.ts +4 -0
  196. package/src/embed/host-events.spec.ts +48 -0
  197. package/src/embed/hostEventClient/host-event-client.spec.ts +34 -0
  198. package/src/embed/hostEventClient/host-event-client.ts +2 -2
  199. package/src/embed/liveboard.spec.ts +457 -2
  200. package/src/embed/liveboard.ts +74 -15
  201. package/src/embed/spotter-utils.spec.ts +72 -0
  202. package/src/embed/spotter-utils.ts +21 -1
  203. package/src/embed/spotter-viz-utils.ts +9 -10
  204. package/src/embed/ts-embed.spec.ts +699 -3
  205. package/src/embed/ts-embed.ts +83 -37
  206. package/src/index.ts +43 -2
  207. package/src/react/all-types-export.parity.spec.ts +208 -0
  208. package/src/react/all-types-export.ts +22 -0
  209. package/src/react/index.spec.tsx +158 -0
  210. package/src/react/index.tsx +70 -33
  211. package/src/types.ts +329 -16
  212. package/src/utils.spec.ts +5 -0
@@ -152,6 +152,7 @@ describe('App embed tests', () => {
152
152
  [Page.SpotIQ]: 'insights/results',
153
153
  [Page.Monitor]: 'insights/monitor-alerts',
154
154
  [Page.Collections]: 'collections',
155
+ [Page.LiveboardSchedules]: 'home/liveboard-schedules',
155
156
  };
156
157
  const pageIds = Object.keys(pageRouteMap);
157
158
  for (let i = 0; i < pageIds.length; i++) {
@@ -179,6 +180,7 @@ describe('App embed tests', () => {
179
180
  [Page.SpotIQ]: 'home/spotiq-analysis',
180
181
  [Page.Monitor]: 'home/monitor-alerts',
181
182
  [Page.Collections]: 'collections',
183
+ [Page.LiveboardSchedules]: 'home/liveboard-schedules',
182
184
  };
183
185
  const pageIdsForModularHomes = Object.keys(pageRouteMapForModularHome);
184
186
  for (let i = 0; i < pageIdsForModularHomes.length; i++) {
@@ -286,6 +288,16 @@ describe('App embed tests', () => {
286
288
  expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&enable2ColumnLayout=true&navigationVersion=v3&homepageVersion=v3${defaultParamsPost}#/home`);
287
289
  });
288
290
  });
291
+ test('should set isLiveboardAlwaysOn12ColLayout to true in url', async () => {
292
+ const appEmbed = new AppEmbed(getRootEl(), {
293
+ ...defaultViewConfig,
294
+ isLiveboardAlwaysOn12ColLayout: true,
295
+ });
296
+ appEmbed.render();
297
+ await executeAfterWait(() => {
298
+ expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&isLiveboardAlwaysOn12ColLayout=true&navigationVersion=v3&homepageVersion=v3${defaultParamsPost}#/home`);
299
+ });
300
+ });
289
301
  test('should set coverAndFilterOptionInPDF to false in url', async () => {
290
302
  const appEmbed = new AppEmbed(getRootEl(), {
291
303
  ...defaultViewConfig,
@@ -306,6 +318,16 @@ describe('App embed tests', () => {
306
318
  expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&isLiveboardStylingAndGroupingEnabled=true&navigationVersion=v3&homepageVersion=v3${defaultParamsPost}#/home`);
307
319
  });
308
320
  });
321
+ test('should set liveboardGutter in url', async () => {
322
+ const appEmbed = new AppEmbed(getRootEl(), {
323
+ ...defaultViewConfig,
324
+ liveboardGutter: 8,
325
+ });
326
+ appEmbed.render();
327
+ await executeAfterWait(() => {
328
+ expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&liveboardGutter=8&navigationVersion=v3&homepageVersion=v3${defaultParamsPost}#/home`);
329
+ });
330
+ });
309
331
  test('should set isThisPeriodInDateFiltersEnabled to true in url', async () => {
310
332
  const appEmbed = new AppEmbed(getRootEl(), {
311
333
  ...defaultViewConfig,
@@ -546,6 +568,33 @@ describe('App embed tests', () => {
546
568
  });
547
569
  });
548
570
  });
571
+ test('should include starterPrompts in APP_INIT embedParams', async () => {
572
+ const starterPrompts = {
573
+ enable: true,
574
+ quick: {
575
+ label: 'Quick',
576
+ questions: [
577
+ { label: 'Q1', prompt: 'P1' },
578
+ { label: 'Q2', prompt: 'P2' },
579
+ ],
580
+ },
581
+ research: { label: 'Research' },
582
+ };
583
+ const appEmbed = new AppEmbed(getRootEl(), {
584
+ ...defaultViewConfig,
585
+ spotterChatConfig: { starterPrompts },
586
+ });
587
+ mockMessageChannel();
588
+ appEmbed.render();
589
+ const mockPort = { postMessage: jest.fn() };
590
+ await executeAfterWait(() => {
591
+ postMessageToParent(getIFrameEl().contentWindow, { type: EmbedEvent.APP_INIT, data: {} }, mockPort);
592
+ });
593
+ await executeAfterWait(() => {
594
+ expect(mockPort.postMessage.mock.calls[0][0].data.embedParams.starterPrompts)
595
+ .toEqual(starterPrompts);
596
+ });
597
+ });
549
598
  test('should pass brandHeadline through spotterVizConfig in APP_INIT', async () => {
550
599
  const spotterViz = { brandName: 'MyBrand', brandHeadline: "Hi, there! I'm" };
551
600
  const appEmbed = new AppEmbed(getRootEl(), {
@@ -722,7 +771,41 @@ describe('App embed tests', () => {
722
771
  });
723
772
  appEmbed.render();
724
773
  await executeAfterWait(() => {
725
- expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&enableStarterPrompts=true${defaultParamsPost}#/home`);
774
+ expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&enableStarterPrompts=true&navigationVersion=v3&homepageVersion=v3${defaultParamsPost}#/home`);
775
+ });
776
+ });
777
+ test('should set openSpotterOnLiveboardByDefault to true in url', async () => {
778
+ const appEmbed = new AppEmbed(getRootEl(), {
779
+ ...defaultViewConfig,
780
+ spotterChatConfig: { openSpotterOnLiveboardByDefault: true },
781
+ });
782
+ appEmbed.render();
783
+ await executeAfterWait(() => {
784
+ expectUrlToHaveParamsWithValues(getIFrameSrc(), {
785
+ openSpotterOnLiveboardByDefault: 'true',
786
+ });
787
+ });
788
+ });
789
+ test('should set openSpotterOnLiveboardByDefault to false when explicitly disabled', async () => {
790
+ const appEmbed = new AppEmbed(getRootEl(), {
791
+ ...defaultViewConfig,
792
+ spotterChatConfig: { openSpotterOnLiveboardByDefault: false },
793
+ });
794
+ appEmbed.render();
795
+ await executeAfterWait(() => {
796
+ expectUrlToHaveParamsWithValues(getIFrameSrc(), {
797
+ openSpotterOnLiveboardByDefault: 'false',
798
+ });
799
+ });
800
+ });
801
+ test('should not set openSpotterOnLiveboardByDefault when it is not configured', async () => {
802
+ const appEmbed = new AppEmbed(getRootEl(), {
803
+ ...defaultViewConfig,
804
+ spotterChatConfig: { enableStarterPrompts: true },
805
+ });
806
+ appEmbed.render();
807
+ await executeAfterWait(() => {
808
+ expect(getIFrameSrc()).not.toContain('openSpotterOnLiveboardByDefault');
726
809
  });
727
810
  });
728
811
  test('should set spotterFileUploadFileTypes in url', async () => {
@@ -1499,6 +1582,175 @@ describe('App embed tests', () => {
1499
1582
  expect(iframeSrc).toContain('isFullHeightPinboard=true');
1500
1583
  }, 100);
1501
1584
  });
1585
+ test('should default lazy loading flags to true when fullHeight is enabled', async () => {
1586
+ const appEmbed = new AppEmbed(getRootEl(), {
1587
+ ...defaultViewConfig,
1588
+ fullHeight: true,
1589
+ });
1590
+ expect(appEmbed.viewConfig.lazyLoadingForFullHeight).toBe(true);
1591
+ expect(appEmbed.viewConfig.enableScrollableContainerLazyLoading).toBe(true);
1592
+ expect(appEmbed.viewConfig.lazyLoadingMargin).toBe('500px 0px');
1593
+ await appEmbed.render();
1594
+ await executeAfterWait(() => {
1595
+ const iframeSrc = getIFrameSrc();
1596
+ expect(iframeSrc).toContain('isLazyLoadingForEmbedEnabled=true');
1597
+ expect(iframeSrc).toContain('isFullHeightPinboard=true');
1598
+ expect(iframeSrc).toContain('rootMarginForLazyLoad=500px%200px');
1599
+ }, 100);
1600
+ });
1601
+ test('should not default lazy loading flags when fullHeight is not enabled', async () => {
1602
+ const appEmbed = new AppEmbed(getRootEl(), {
1603
+ ...defaultViewConfig,
1604
+ });
1605
+ expect(appEmbed.viewConfig.lazyLoadingForFullHeight).toBeUndefined();
1606
+ expect(appEmbed.viewConfig.enableScrollableContainerLazyLoading).toBeUndefined();
1607
+ expect(appEmbed.viewConfig.lazyLoadingMargin).toBeUndefined();
1608
+ });
1609
+ test('should not write the defaults back onto the caller view config', async () => {
1610
+ const callerViewConfig = {
1611
+ ...defaultViewConfig,
1612
+ fullHeight: true,
1613
+ };
1614
+ new AppEmbed(getRootEl(), callerViewConfig);
1615
+ expect(callerViewConfig.lazyLoadingForFullHeight).toBeUndefined();
1616
+ expect(callerViewConfig.enableScrollableContainerLazyLoading).toBeUndefined();
1617
+ expect(callerViewConfig.lazyLoadingMargin).toBeUndefined();
1618
+ });
1619
+ test('should not default lazy loading flags when fullHeight is explicitly false', async () => {
1620
+ const appEmbed = new AppEmbed(getRootEl(), {
1621
+ ...defaultViewConfig,
1622
+ fullHeight: false,
1623
+ });
1624
+ expect(appEmbed.viewConfig.lazyLoadingForFullHeight).toBeUndefined();
1625
+ expect(appEmbed.viewConfig.enableScrollableContainerLazyLoading).toBeUndefined();
1626
+ expect(appEmbed.viewConfig.lazyLoadingMargin).toBeUndefined();
1627
+ });
1628
+ test('should default lazyLoadingMargin when lazyLoadingForFullHeight is set explicitly', async () => {
1629
+ const appEmbed = new AppEmbed(getRootEl(), {
1630
+ ...defaultViewConfig,
1631
+ fullHeight: true,
1632
+ lazyLoadingForFullHeight: true,
1633
+ });
1634
+ expect(appEmbed.viewConfig.lazyLoadingMargin).toBe(config.DEFAULT_LAZY_LOADING_MARGIN);
1635
+ await appEmbed.render();
1636
+ await executeAfterWait(() => {
1637
+ expect(getIFrameSrc()).toContain('rootMarginForLazyLoad=500px%200px');
1638
+ }, 100);
1639
+ });
1640
+ test('should let an explicit lazyLoadingMargin win over the default', async () => {
1641
+ const appEmbed = new AppEmbed(getRootEl(), {
1642
+ ...defaultViewConfig,
1643
+ fullHeight: true,
1644
+ lazyLoadingMargin: '250px',
1645
+ });
1646
+ await appEmbed.render();
1647
+ await executeAfterWait(() => {
1648
+ const iframeSrc = getIFrameSrc();
1649
+ expect(iframeSrc).toContain('rootMarginForLazyLoad=250px');
1650
+ expect(iframeSrc).not.toContain('rootMarginForLazyLoad=500px%200px');
1651
+ }, 100);
1652
+ });
1653
+ test('should drop an invalid lazyLoadingMargin and log an error', async () => {
1654
+ const loggerErrorSpy = jest.spyOn(logger, 'error').mockImplementation(() => undefined);
1655
+ const appEmbed = new AppEmbed(getRootEl(), {
1656
+ ...defaultViewConfig,
1657
+ fullHeight: true,
1658
+ lazyLoadingMargin: 'not-a-margin',
1659
+ });
1660
+ await appEmbed.render();
1661
+ await executeAfterWait(() => {
1662
+ const iframeSrc = getIFrameSrc();
1663
+ expect(iframeSrc).toContain('isLazyLoadingForEmbedEnabled=true');
1664
+ expect(iframeSrc).not.toContain('rootMarginForLazyLoad');
1665
+ expect(loggerErrorSpy).toHaveBeenCalledWith('Please provide a valid lazyLoadingMargin value (e.g., "10px")');
1666
+ }, 100);
1667
+ });
1668
+ test('should track scrollable ancestors by default when only fullHeight is set', async () => {
1669
+ const scrollContainer = getRootEl();
1670
+ scrollContainer.style.overflow = 'auto';
1671
+ const scrollContainerSpy = jest.spyOn(scrollContainer, 'addEventListener');
1672
+ const resizeObserveSpy = jest.fn();
1673
+ const resizeDisconnectSpy = jest.fn();
1674
+ window.ResizeObserver = jest.fn().mockImplementation(() => ({
1675
+ observe: resizeObserveSpy,
1676
+ disconnect: resizeDisconnectSpy,
1677
+ }));
1678
+ const appEmbed = new AppEmbed(getRootEl(), {
1679
+ ...defaultViewConfig,
1680
+ fullHeight: true,
1681
+ });
1682
+ await appEmbed.render();
1683
+ await executeAfterWait(() => {
1684
+ expect(scrollContainerSpy).toHaveBeenCalledWith('scroll', expect.any(Function));
1685
+ expect(resizeObserveSpy).toHaveBeenCalledWith(scrollContainer);
1686
+ }, 100);
1687
+ appEmbed.destroy();
1688
+ expect(resizeDisconnectSpy).toHaveBeenCalled();
1689
+ scrollContainer.style.overflow = '';
1690
+ window.ResizeObserver = originalResizeObserver;
1691
+ });
1692
+ test('should skip ancestor tracking when enableScrollableContainerLazyLoading is false', async () => {
1693
+ const scrollContainer = getRootEl();
1694
+ scrollContainer.style.overflow = 'auto';
1695
+ const scrollContainerSpy = jest.spyOn(scrollContainer, 'addEventListener');
1696
+ const windowSpy = jest.spyOn(window, 'addEventListener');
1697
+ const appEmbed = new AppEmbed(getRootEl(), {
1698
+ ...defaultViewConfig,
1699
+ fullHeight: true,
1700
+ enableScrollableContainerLazyLoading: false,
1701
+ });
1702
+ await appEmbed.render();
1703
+ await executeAfterWait(() => {
1704
+ expect(windowSpy).toHaveBeenCalledWith('scroll', expect.anything(), true);
1705
+ expect(scrollContainerSpy).not.toHaveBeenCalledWith('scroll', expect.any(Function));
1706
+ }, 100);
1707
+ appEmbed.destroy();
1708
+ scrollContainer.style.overflow = '';
1709
+ });
1710
+ test('should wire the window scroll listener to the coordinates sender by default', async () => {
1711
+ const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
1712
+ const appEmbed = new AppEmbed(getRootEl(), {
1713
+ ...defaultViewConfig,
1714
+ fullHeight: true,
1715
+ });
1716
+ const mockTrigger = jest
1717
+ .spyOn(appEmbed, 'trigger')
1718
+ .mockImplementation(() => Promise.resolve(undefined));
1719
+ await appEmbed.render();
1720
+ await executeAfterWait(() => {
1721
+ const scrollCall = addEventListenerSpy.mock.calls.find(([eventName, , capture]) => eventName === 'scroll' && capture === true);
1722
+ expect(scrollCall).toBeDefined();
1723
+ // Call the handler the way a real scroll event would.
1724
+ scrollCall[1]();
1725
+ expect(mockTrigger).toHaveBeenCalledWith(HostEvent.VisibleEmbedCoordinates, expect.objectContaining({ top: expect.any(Number) }));
1726
+ }, 100);
1727
+ appEmbed.destroy();
1728
+ addEventListenerSpy.mockRestore();
1729
+ });
1730
+ test('should remove listeners on destroy when the flags come from defaults', async () => {
1731
+ const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
1732
+ const appEmbed = new AppEmbed(getRootEl(), {
1733
+ ...defaultViewConfig,
1734
+ fullHeight: true,
1735
+ });
1736
+ await appEmbed.render();
1737
+ appEmbed.destroy();
1738
+ expect(removeEventListenerSpy).toHaveBeenCalledWith('resize', expect.anything());
1739
+ expect(removeEventListenerSpy).toHaveBeenCalledWith('scroll', expect.anything(), true);
1740
+ removeEventListenerSpy.mockRestore();
1741
+ });
1742
+ test('should keep an explicit false for the lazy loading flags', async () => {
1743
+ const appEmbed = new AppEmbed(getRootEl(), {
1744
+ ...defaultViewConfig,
1745
+ fullHeight: true,
1746
+ lazyLoadingForFullHeight: false,
1747
+ enableScrollableContainerLazyLoading: false,
1748
+ lazyLoadingMargin: '0px',
1749
+ });
1750
+ expect(appEmbed.viewConfig.lazyLoadingForFullHeight).toBe(false);
1751
+ expect(appEmbed.viewConfig.enableScrollableContainerLazyLoading).toBe(false);
1752
+ expect(appEmbed.viewConfig.lazyLoadingMargin).toBe('0px');
1753
+ });
1502
1754
  test('should not set lazyLoadingForEmbed when lazyLoadingForFullHeight is enabled but fullHeight is false', async () => {
1503
1755
  const appEmbed = new AppEmbed(getRootEl(), {
1504
1756
  ...defaultViewConfig,