@thoughtspot/visual-embed-sdk 1.50.1 → 1.51.0-test

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 (238) 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 +63 -0
  7. package/cjs/src/css-variables.d.ts.map +1 -1
  8. package/cjs/src/embed/app.d.ts +148 -25
  9. package/cjs/src/embed/app.d.ts.map +1 -1
  10. package/cjs/src/embed/app.js +74 -37
  11. package/cjs/src/embed/app.js.map +1 -1
  12. package/cjs/src/embed/app.spec.js +571 -150
  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 +375 -2
  17. package/cjs/src/embed/conversation.d.ts.map +1 -1
  18. package/cjs/src/embed/conversation.js +21 -15
  19. package/cjs/src/embed/conversation.js.map +1 -1
  20. package/cjs/src/embed/conversation.spec.js +323 -17
  21. package/cjs/src/embed/conversation.spec.js.map +1 -1
  22. package/cjs/src/embed/events.spec.js +45 -0
  23. package/cjs/src/embed/events.spec.js.map +1 -1
  24. package/cjs/src/embed/host-events.spec.js +81 -0
  25. package/cjs/src/embed/host-events.spec.js.map +1 -1
  26. package/cjs/src/embed/hostEventClient/contracts.d.ts +15 -0
  27. package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  28. package/cjs/src/embed/hostEventClient/contracts.js +1 -0
  29. package/cjs/src/embed/hostEventClient/contracts.js.map +1 -1
  30. package/cjs/src/embed/hostEventClient/host-event-client.d.ts +1 -1
  31. package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  32. package/cjs/src/embed/hostEventClient/host-event-client.js +1 -0
  33. package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -1
  34. package/cjs/src/embed/hostEventClient/host-event-client.spec.js +27 -0
  35. package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  36. package/cjs/src/embed/liveboard.d.ts +76 -14
  37. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  38. package/cjs/src/embed/liveboard.js +50 -9
  39. package/cjs/src/embed/liveboard.js.map +1 -1
  40. package/cjs/src/embed/liveboard.spec.js +432 -4
  41. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  42. package/cjs/src/embed/spotter-utils.d.ts +15 -1
  43. package/cjs/src/embed/spotter-utils.d.ts.map +1 -1
  44. package/cjs/src/embed/spotter-utils.js +28 -1
  45. package/cjs/src/embed/spotter-utils.js.map +1 -1
  46. package/cjs/src/embed/spotter-utils.spec.js +129 -0
  47. package/cjs/src/embed/spotter-utils.spec.js.map +1 -1
  48. package/cjs/src/embed/spotter-viz-utils.d.ts +9 -10
  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/ts-embed.d.ts +16 -8
  52. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  53. package/cjs/src/embed/ts-embed.js +82 -30
  54. package/cjs/src/embed/ts-embed.js.map +1 -1
  55. package/cjs/src/embed/ts-embed.spec.js +537 -3
  56. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  57. package/cjs/src/index.d.ts +3 -3
  58. package/cjs/src/index.d.ts.map +1 -1
  59. package/cjs/src/index.js +3 -2
  60. package/cjs/src/index.js.map +1 -1
  61. package/cjs/src/mixpanel-service.d.ts +4 -0
  62. package/cjs/src/mixpanel-service.d.ts.map +1 -1
  63. package/cjs/src/mixpanel-service.js +4 -0
  64. package/cjs/src/mixpanel-service.js.map +1 -1
  65. package/cjs/src/react/all-types-export.d.ts +1 -1
  66. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  67. package/cjs/src/react/all-types-export.js +2 -1
  68. package/cjs/src/react/all-types-export.js.map +1 -1
  69. package/cjs/src/react/all-types-export.parity.spec.d.ts +2 -0
  70. package/cjs/src/react/all-types-export.parity.spec.d.ts.map +1 -0
  71. package/cjs/src/react/all-types-export.parity.spec.js +194 -0
  72. package/cjs/src/react/all-types-export.parity.spec.js.map +1 -0
  73. package/cjs/src/react/index.d.ts +66 -32
  74. package/cjs/src/react/index.d.ts.map +1 -1
  75. package/cjs/src/react/index.js +5 -3
  76. package/cjs/src/react/index.js.map +1 -1
  77. package/cjs/src/react/index.spec.js +101 -0
  78. package/cjs/src/react/index.spec.js.map +1 -1
  79. package/cjs/src/types.d.ts +789 -32
  80. package/cjs/src/types.d.ts.map +1 -1
  81. package/cjs/src/types.js +610 -20
  82. package/cjs/src/types.js.map +1 -1
  83. package/cjs/src/utils.spec.js +4 -0
  84. package/cjs/src/utils.spec.js.map +1 -1
  85. package/dist/{index-fCne7kmU.js → index-Bivg-mDx.js} +1 -1
  86. package/dist/src/config.d.ts +1 -0
  87. package/dist/src/config.d.ts.map +1 -1
  88. package/dist/src/css-variables.d.ts +63 -0
  89. package/dist/src/css-variables.d.ts.map +1 -1
  90. package/dist/src/embed/app.d.ts +148 -25
  91. package/dist/src/embed/app.d.ts.map +1 -1
  92. package/dist/src/embed/base.d.ts +1 -1
  93. package/dist/src/embed/conversation.d.ts +375 -2
  94. package/dist/src/embed/conversation.d.ts.map +1 -1
  95. package/dist/src/embed/hostEventClient/contracts.d.ts +15 -0
  96. package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  97. package/dist/src/embed/hostEventClient/host-event-client.d.ts +1 -1
  98. package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  99. package/dist/src/embed/liveboard.d.ts +76 -14
  100. package/dist/src/embed/liveboard.d.ts.map +1 -1
  101. package/dist/src/embed/spotter-utils.d.ts +15 -1
  102. package/dist/src/embed/spotter-utils.d.ts.map +1 -1
  103. package/dist/src/embed/spotter-viz-utils.d.ts +9 -10
  104. package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
  105. package/dist/src/embed/ts-embed.d.ts +16 -8
  106. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  107. package/dist/src/index.d.ts +3 -3
  108. package/dist/src/index.d.ts.map +1 -1
  109. package/dist/src/mixpanel-service.d.ts +4 -0
  110. package/dist/src/mixpanel-service.d.ts.map +1 -1
  111. package/dist/src/react/all-types-export.d.ts +1 -1
  112. package/dist/src/react/all-types-export.d.ts.map +1 -1
  113. package/dist/src/react/all-types-export.parity.spec.d.ts +2 -0
  114. package/dist/src/react/all-types-export.parity.spec.d.ts.map +1 -0
  115. package/dist/src/react/index.d.ts +66 -32
  116. package/dist/src/react/index.d.ts.map +1 -1
  117. package/dist/src/types.d.ts +789 -32
  118. package/dist/src/types.d.ts.map +1 -1
  119. package/dist/tsembed-react.es.js +878 -120
  120. package/dist/tsembed-react.js +877 -119
  121. package/dist/tsembed.es.js +936 -181
  122. package/dist/tsembed.js +938 -183
  123. package/dist/visual-embed-sdk-react-full.d.ts +1553 -128
  124. package/dist/visual-embed-sdk-react.d.ts +1555 -129
  125. package/dist/visual-embed-sdk.d.ts +1499 -100
  126. package/lib/package.json +1 -1
  127. package/lib/src/config.d.ts +1 -0
  128. package/lib/src/config.d.ts.map +1 -1
  129. package/lib/src/config.js +1 -0
  130. package/lib/src/config.js.map +1 -1
  131. package/lib/src/css-variables.d.ts +63 -0
  132. package/lib/src/css-variables.d.ts.map +1 -1
  133. package/lib/src/embed/app.d.ts +148 -25
  134. package/lib/src/embed/app.d.ts.map +1 -1
  135. package/lib/src/embed/app.js +75 -38
  136. package/lib/src/embed/app.js.map +1 -1
  137. package/lib/src/embed/app.spec.js +572 -151
  138. package/lib/src/embed/app.spec.js.map +1 -1
  139. package/lib/src/embed/base.d.ts +1 -1
  140. package/lib/src/embed/base.js +1 -1
  141. package/lib/src/embed/conversation.d.ts +375 -2
  142. package/lib/src/embed/conversation.d.ts.map +1 -1
  143. package/lib/src/embed/conversation.js +23 -17
  144. package/lib/src/embed/conversation.js.map +1 -1
  145. package/lib/src/embed/conversation.spec.js +323 -17
  146. package/lib/src/embed/conversation.spec.js.map +1 -1
  147. package/lib/src/embed/events.spec.js +45 -0
  148. package/lib/src/embed/events.spec.js.map +1 -1
  149. package/lib/src/embed/host-events.spec.js +81 -0
  150. package/lib/src/embed/host-events.spec.js.map +1 -1
  151. package/lib/src/embed/hostEventClient/contracts.d.ts +15 -0
  152. package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  153. package/lib/src/embed/hostEventClient/contracts.js +1 -0
  154. package/lib/src/embed/hostEventClient/contracts.js.map +1 -1
  155. package/lib/src/embed/hostEventClient/host-event-client.d.ts +1 -1
  156. package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  157. package/lib/src/embed/hostEventClient/host-event-client.js +1 -0
  158. package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -1
  159. package/lib/src/embed/hostEventClient/host-event-client.spec.js +27 -0
  160. package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  161. package/lib/src/embed/liveboard.d.ts +76 -14
  162. package/lib/src/embed/liveboard.d.ts.map +1 -1
  163. package/lib/src/embed/liveboard.js +50 -9
  164. package/lib/src/embed/liveboard.js.map +1 -1
  165. package/lib/src/embed/liveboard.spec.js +432 -4
  166. package/lib/src/embed/liveboard.spec.js.map +1 -1
  167. package/lib/src/embed/spotter-utils.d.ts +15 -1
  168. package/lib/src/embed/spotter-utils.d.ts.map +1 -1
  169. package/lib/src/embed/spotter-utils.js +25 -0
  170. package/lib/src/embed/spotter-utils.js.map +1 -1
  171. package/lib/src/embed/spotter-utils.spec.js +130 -1
  172. package/lib/src/embed/spotter-utils.spec.js.map +1 -1
  173. package/lib/src/embed/spotter-viz-utils.d.ts +9 -10
  174. package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
  175. package/lib/src/embed/spotter-viz-utils.js.map +1 -1
  176. package/lib/src/embed/ts-embed.d.ts +16 -8
  177. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  178. package/lib/src/embed/ts-embed.js +82 -30
  179. package/lib/src/embed/ts-embed.js.map +1 -1
  180. package/lib/src/embed/ts-embed.spec.js +537 -3
  181. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  182. package/lib/src/index.d.ts +3 -3
  183. package/lib/src/index.d.ts.map +1 -1
  184. package/lib/src/index.js +2 -2
  185. package/lib/src/index.js.map +1 -1
  186. package/lib/src/mixpanel-service.d.ts +4 -0
  187. package/lib/src/mixpanel-service.d.ts.map +1 -1
  188. package/lib/src/mixpanel-service.js +4 -0
  189. package/lib/src/mixpanel-service.js.map +1 -1
  190. package/lib/src/react/all-types-export.d.ts +1 -1
  191. package/lib/src/react/all-types-export.d.ts.map +1 -1
  192. package/lib/src/react/all-types-export.js +1 -1
  193. package/lib/src/react/all-types-export.js.map +1 -1
  194. package/lib/src/react/all-types-export.parity.spec.d.ts +2 -0
  195. package/lib/src/react/all-types-export.parity.spec.d.ts.map +1 -0
  196. package/lib/src/react/all-types-export.parity.spec.js +191 -0
  197. package/lib/src/react/all-types-export.parity.spec.js.map +1 -0
  198. package/lib/src/react/index.d.ts +66 -32
  199. package/lib/src/react/index.d.ts.map +1 -1
  200. package/lib/src/react/index.js +5 -3
  201. package/lib/src/react/index.js.map +1 -1
  202. package/lib/src/react/index.spec.js +102 -1
  203. package/lib/src/react/index.spec.js.map +1 -1
  204. package/lib/src/types.d.ts +789 -32
  205. package/lib/src/types.d.ts.map +1 -1
  206. package/lib/src/types.js +610 -20
  207. package/lib/src/types.js.map +1 -1
  208. package/lib/src/utils.spec.js +4 -0
  209. package/lib/src/utils.spec.js.map +1 -1
  210. package/lib/src/visual-embed-sdk.d.ts +1499 -100
  211. package/package.json +1 -1
  212. package/src/config.ts +1 -0
  213. package/src/css-variables.ts +77 -0
  214. package/src/embed/app.spec.ts +729 -188
  215. package/src/embed/app.ts +240 -75
  216. package/src/embed/base.ts +1 -1
  217. package/src/embed/conversation.spec.ts +379 -20
  218. package/src/embed/conversation.ts +412 -18
  219. package/src/embed/events.spec.ts +56 -0
  220. package/src/embed/host-events.spec.ts +118 -0
  221. package/src/embed/hostEventClient/contracts.ts +16 -0
  222. package/src/embed/hostEventClient/host-event-client.spec.ts +46 -0
  223. package/src/embed/hostEventClient/host-event-client.ts +3 -2
  224. package/src/embed/liveboard.spec.ts +565 -4
  225. package/src/embed/liveboard.ts +150 -29
  226. package/src/embed/spotter-utils.spec.ts +140 -1
  227. package/src/embed/spotter-utils.ts +36 -1
  228. package/src/embed/spotter-viz-utils.ts +9 -10
  229. package/src/embed/ts-embed.spec.ts +699 -3
  230. package/src/embed/ts-embed.ts +99 -35
  231. package/src/index.ts +44 -2
  232. package/src/mixpanel-service.ts +4 -0
  233. package/src/react/all-types-export.parity.spec.ts +208 -0
  234. package/src/react/all-types-export.ts +22 -0
  235. package/src/react/index.spec.tsx +158 -0
  236. package/src/react/index.tsx +70 -33
  237. package/src/types.ts +791 -30
  238. package/src/utils.spec.ts +5 -0
@@ -28,6 +28,7 @@ import * as auth from '../auth';
28
28
  import * as previewService from '../utils/graphql/preview-service';
29
29
  import * as SessionInfoService from '../utils/sessionInfoService';
30
30
  import { logger } from '../utils/logger';
31
+ import { DEFAULT_LAZY_LOADING_MARGIN } from '../config';
31
32
 
32
33
  const defaultViewConfig = {
33
34
  frameParams: {
@@ -156,6 +157,23 @@ describe('Liveboard/viz embed tests', () => {
156
157
  });
157
158
  });
158
159
 
160
+ test('should hide and disable the Spotter button on the Liveboard header', async () => {
161
+ expect(Action.SpotterOnLiveboard).toBe('spotterOnLiveboard');
162
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
163
+ hiddenActions: [Action.SpotterOnLiveboard],
164
+ disabledActions: [Action.SpotterOnLiveboard],
165
+ ...defaultViewConfig,
166
+ liveboardId,
167
+ } as LiveboardViewConfig);
168
+ liveboardEmbed.render();
169
+ await executeAfterWait(() => {
170
+ expectUrlToHaveParamsWithValues(getIFrameSrc(), {
171
+ hideAction: JSON.stringify([Action.ReportError, Action.SpotterOnLiveboard]),
172
+ disableAction: JSON.stringify([Action.SpotterOnLiveboard]),
173
+ });
174
+ });
175
+ });
176
+
159
177
  test('should set visible actions', async () => {
160
178
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
161
179
  visibleActions: [Action.DownloadAsCsv, Action.DownloadAsPdf, Action.DownloadAsXlsx],
@@ -200,6 +218,21 @@ describe('Liveboard/viz embed tests', () => {
200
218
  });
201
219
  });
202
220
 
221
+ test('should set isLiveboardAlwaysOn12ColLayout to true in url', async () => {
222
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
223
+ isLiveboardAlwaysOn12ColLayout: true,
224
+ ...defaultViewConfig,
225
+ liveboardId,
226
+ } as LiveboardViewConfig);
227
+ liveboardEmbed.render();
228
+ await executeAfterWait(() => {
229
+ expectUrlMatchesWithParams(
230
+ getIFrameSrc(),
231
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isLiveboardAlwaysOn12ColLayout=true${prefixParams}#/embed/viz/${liveboardId}`,
232
+ );
233
+ });
234
+ });
235
+
203
236
  test('should set isLiveboardStylingAndGroupingEnabled to true in url (deprecated, use isLiveboardMasterpiecesEnabled)', async () => {
204
237
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
205
238
  isLiveboardStylingAndGroupingEnabled: true,
@@ -215,6 +248,36 @@ describe('Liveboard/viz embed tests', () => {
215
248
  });
216
249
  });
217
250
 
251
+ test('should set liveboardGutter in url', async () => {
252
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
253
+ ...defaultViewConfig,
254
+ liveboardId,
255
+ liveboardGutter: 8,
256
+ } as LiveboardViewConfig);
257
+ liveboardEmbed.render();
258
+ await executeAfterWait(() => {
259
+ expectUrlMatchesWithParams(
260
+ getIFrameSrc(),
261
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&liveboardGutter=8${prefixParams}#/embed/viz/${liveboardId}`,
262
+ );
263
+ });
264
+ });
265
+
266
+ test('should set liveboardGutter to 0 in url', async () => {
267
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
268
+ ...defaultViewConfig,
269
+ liveboardId,
270
+ liveboardGutter: 0,
271
+ } as LiveboardViewConfig);
272
+ liveboardEmbed.render();
273
+ await executeAfterWait(() => {
274
+ expectUrlMatchesWithParams(
275
+ getIFrameSrc(),
276
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&liveboardGutter=0${prefixParams}#/embed/viz/${liveboardId}`,
277
+ );
278
+ });
279
+ });
280
+
218
281
  test('should set isThisPeriodInDateFiltersEnabled to true in url', async () => {
219
282
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
220
283
  ...defaultViewConfig,
@@ -275,7 +338,7 @@ describe('Liveboard/viz embed tests', () => {
275
338
  });
276
339
  });
277
340
 
278
- test('should disable isWYSIWYGLiveboardPDFEnabled by default in url', async () => {
341
+ test('should not set isWYSIWYGLiveboardPDFEnabled in url by default', async () => {
279
342
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
280
343
  ...defaultViewConfig,
281
344
  liveboardId,
@@ -284,7 +347,7 @@ describe('Liveboard/viz embed tests', () => {
284
347
  await executeAfterWait(() => {
285
348
  expectUrlMatchesWithParams(
286
349
  getIFrameSrc(),
287
- `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isWYSIWYGLiveboardPDFEnabled=false${prefixParams}#/embed/viz/${liveboardId}`,
350
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}#/embed/viz/${liveboardId}`,
288
351
  );
289
352
  });
290
353
  });
@@ -756,6 +819,47 @@ describe('Liveboard/viz embed tests', () => {
756
819
  });
757
820
  });
758
821
 
822
+ test('should add isScopedLiveboardFilteringEnabled flag and set value to true to the iframe src', async () => {
823
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
824
+ ...defaultViewConfig,
825
+ liveboardId,
826
+ isScopedLiveboardFilteringEnabled: true,
827
+ } as LiveboardViewConfig);
828
+ liveboardEmbed.render();
829
+ await executeAfterWait(() => {
830
+ expectUrlMatchesWithParams(
831
+ getIFrameSrc(),
832
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isScopedLiveboardFilteringEnabled=true${prefixParams}#/embed/viz/${liveboardId}`,
833
+ );
834
+ });
835
+ });
836
+
837
+ test('should add isScopedLiveboardFilteringEnabled flag and set value to false to the iframe src', async () => {
838
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
839
+ ...defaultViewConfig,
840
+ liveboardId,
841
+ isScopedLiveboardFilteringEnabled: false,
842
+ } as LiveboardViewConfig);
843
+ liveboardEmbed.render();
844
+ await executeAfterWait(() => {
845
+ expectUrlMatchesWithParams(
846
+ getIFrameSrc(),
847
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isScopedLiveboardFilteringEnabled=false${prefixParams}#/embed/viz/${liveboardId}`,
848
+ );
849
+ });
850
+ });
851
+
852
+ test('should not add isScopedLiveboardFilteringEnabled flag to the iframe src when undefined', async () => {
853
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
854
+ ...defaultViewConfig,
855
+ liveboardId,
856
+ } as LiveboardViewConfig);
857
+ liveboardEmbed.render();
858
+ await executeAfterWait(() => {
859
+ expect(getIFrameSrc()).not.toContain('isScopedLiveboardFilteringEnabled');
860
+ });
861
+ });
862
+
759
863
  test('should not append runtime filters in URL if excludeRuntimeFiltersfromURL is true', async () => {
760
864
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
761
865
  ...defaultViewConfig,
@@ -1230,6 +1334,44 @@ describe('Liveboard/viz embed tests', () => {
1230
1334
  expect(onSpy).toHaveBeenCalledWith(HostEvent.Navigate, 'embed/viz/lb1/viz1');
1231
1335
  }, 1002);
1232
1336
  });
1337
+
1338
+ test('navigateToLiveboard should call preRender when preRenderConfig.preRenderId is set', () => {
1339
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1340
+ ...defaultViewConfig,
1341
+ liveboardId,
1342
+ preRenderConfig: {
1343
+ preRenderId: 'config-pre-render-id',
1344
+ },
1345
+ } as LiveboardViewConfig);
1346
+
1347
+ const preRenderSpy = jest
1348
+ .spyOn(liveboardEmbed, 'preRender')
1349
+ .mockResolvedValue(liveboardEmbed);
1350
+ liveboardEmbed.navigateToLiveboard('lb1');
1351
+
1352
+ expect(preRenderSpy).toHaveBeenCalledTimes(1);
1353
+ expect(preRenderSpy).toHaveBeenCalledWith(true);
1354
+ });
1355
+
1356
+ test('navigateToLiveboard should prefer preRenderConfig.preRenderId over top-level preRenderId', () => {
1357
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1358
+ ...defaultViewConfig,
1359
+ liveboardId,
1360
+ preRenderId: 'top-level-id',
1361
+ preRenderConfig: {
1362
+ preRenderId: 'config-level-id',
1363
+ },
1364
+ } as LiveboardViewConfig);
1365
+
1366
+ const preRenderSpy = jest
1367
+ .spyOn(liveboardEmbed, 'preRender')
1368
+ .mockResolvedValue(liveboardEmbed);
1369
+ liveboardEmbed.navigateToLiveboard('lb1');
1370
+
1371
+ expect(preRenderSpy).toHaveBeenCalledTimes(1);
1372
+ expect(preRenderSpy).toHaveBeenCalledWith(true);
1373
+ });
1374
+
1233
1375
  test('should set runtime parametere values in url params', async () => {
1234
1376
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1235
1377
  ...defaultViewConfig,
@@ -1296,6 +1438,46 @@ describe('Liveboard/viz embed tests', () => {
1296
1438
  });
1297
1439
  });
1298
1440
 
1441
+ test('should set openSpotterOnLiveboardByDefault parameter in url params', async () => {
1442
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1443
+ ...defaultViewConfig,
1444
+ liveboardId,
1445
+ spotterChatConfig: { openSpotterOnLiveboardByDefault: true },
1446
+ } as LiveboardViewConfig);
1447
+ await liveboardEmbed.render();
1448
+ await executeAfterWait(() => {
1449
+ expectUrlToHaveParamsWithValues(getIFrameSrc(), {
1450
+ openSpotterOnLiveboardByDefault: 'true',
1451
+ });
1452
+ });
1453
+ });
1454
+
1455
+ test('should set openSpotterOnLiveboardByDefault to false when explicitly disabled', async () => {
1456
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1457
+ ...defaultViewConfig,
1458
+ liveboardId,
1459
+ spotterChatConfig: { openSpotterOnLiveboardByDefault: false },
1460
+ } as LiveboardViewConfig);
1461
+ await liveboardEmbed.render();
1462
+ await executeAfterWait(() => {
1463
+ expectUrlToHaveParamsWithValues(getIFrameSrc(), {
1464
+ openSpotterOnLiveboardByDefault: 'false',
1465
+ });
1466
+ });
1467
+ });
1468
+
1469
+ test('should not set openSpotterOnLiveboardByDefault when it is not configured', async () => {
1470
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1471
+ ...defaultViewConfig,
1472
+ liveboardId,
1473
+ spotterChatConfig: { enableStarterPrompts: true },
1474
+ } as LiveboardViewConfig);
1475
+ await liveboardEmbed.render();
1476
+ await executeAfterWait(() => {
1477
+ expect(getIFrameSrc()).not.toContain('openSpotterOnLiveboardByDefault');
1478
+ });
1479
+ });
1480
+
1299
1481
  test('should set spotterFileUploadFileTypes parameter in url params', async () => {
1300
1482
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1301
1483
  ...defaultViewConfig,
@@ -1339,6 +1521,35 @@ describe('Liveboard/viz embed tests', () => {
1339
1521
  });
1340
1522
  });
1341
1523
 
1524
+ test('should render the liveboard embed with showSpotterRadiance', async () => {
1525
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1526
+ ...defaultViewConfig,
1527
+ liveboardId,
1528
+ showSpotterRadiance: true,
1529
+ } as LiveboardViewConfig);
1530
+ await liveboardEmbed.render();
1531
+ await executeAfterWait(() => {
1532
+ expectUrlMatchesWithParams(
1533
+ getIFrameSrc(),
1534
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}&showSpotterRadiance=true#/embed/viz/${liveboardId}`,
1535
+ );
1536
+ });
1537
+ });
1538
+ test('should render the liveboard embed with showSpotterRadiance disabled', async () => {
1539
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1540
+ ...defaultViewConfig,
1541
+ liveboardId,
1542
+ showSpotterRadiance: false,
1543
+ } as LiveboardViewConfig);
1544
+ await liveboardEmbed.render();
1545
+ await executeAfterWait(() => {
1546
+ expectUrlMatchesWithParams(
1547
+ getIFrameSrc(),
1548
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}&showSpotterRadiance=false#/embed/viz/${liveboardId}`,
1549
+ );
1550
+ });
1551
+ });
1552
+
1342
1553
  test('should set hideToolResponseCardBranding parameter in url params via spotterChatConfig', async () => {
1343
1554
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1344
1555
  ...defaultViewConfig,
@@ -1410,6 +1621,37 @@ describe('Liveboard/viz embed tests', () => {
1410
1621
  });
1411
1622
  });
1412
1623
 
1624
+ test('should include starterPrompts in APP_INIT embedParams', async () => {
1625
+ const starterPrompts = {
1626
+ enable: true,
1627
+ quick: {
1628
+ label: 'Quick',
1629
+ questions: [
1630
+ { label: 'Q1', prompt: 'P1' },
1631
+ { label: 'Q2', prompt: 'P2' },
1632
+ ],
1633
+ },
1634
+ research: { label: 'Research' },
1635
+ };
1636
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1637
+ ...defaultViewConfig,
1638
+ liveboardId,
1639
+ spotterChatConfig: { starterPrompts },
1640
+ } as LiveboardViewConfig);
1641
+
1642
+ mockMessageChannel();
1643
+ await liveboardEmbed.render();
1644
+
1645
+ const mockPort: any = { postMessage: jest.fn() };
1646
+ await executeAfterWait(() => {
1647
+ postMessageToParent(getIFrameEl().contentWindow, { type: EmbedEvent.APP_INIT, data: {} }, mockPort);
1648
+ });
1649
+ await executeAfterWait(() => {
1650
+ expect(mockPort.postMessage.mock.calls[0][0].data.embedParams.starterPrompts)
1651
+ .toEqual(starterPrompts);
1652
+ });
1653
+ });
1654
+
1413
1655
  test('should pass brandHeadline through spotterVizConfig in APP_INIT', async () => {
1414
1656
  const spotterViz = { brandName: 'MyBrand', brandHeadline: "Hi, there! I'm" };
1415
1657
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
@@ -1810,6 +2052,255 @@ describe('Liveboard/viz embed tests', () => {
1810
2052
  }, 100);
1811
2053
  });
1812
2054
 
2055
+ test('should default lazy loading flags to true when fullHeight is enabled', async () => {
2056
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2057
+ ...defaultViewConfig,
2058
+ liveboardId,
2059
+ fullHeight: true,
2060
+ } as LiveboardViewConfig);
2061
+
2062
+ expect((liveboardEmbed as any).viewConfig.lazyLoadingForFullHeight).toBe(true);
2063
+ expect(
2064
+ (liveboardEmbed as any).viewConfig.enableScrollableContainerLazyLoading,
2065
+ ).toBe(true);
2066
+ expect((liveboardEmbed as any).viewConfig.lazyLoadingMargin).toBe('500px 0px');
2067
+
2068
+ await liveboardEmbed.render();
2069
+
2070
+ await executeAfterWait(() => {
2071
+ const iframeSrc = getIFrameSrc();
2072
+ expect(iframeSrc).toContain('isLazyLoadingForEmbedEnabled=true');
2073
+ expect(iframeSrc).toContain('isFullHeightPinboard=true');
2074
+ expect(iframeSrc).toContain('rootMarginForLazyLoad=500px%200px');
2075
+ }, 100);
2076
+ });
2077
+
2078
+ test('should not default lazy loading flags when fullHeight is not enabled', async () => {
2079
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2080
+ ...defaultViewConfig,
2081
+ liveboardId,
2082
+ } as LiveboardViewConfig);
2083
+
2084
+ expect((liveboardEmbed as any).viewConfig.lazyLoadingForFullHeight).toBeUndefined();
2085
+ expect(
2086
+ (liveboardEmbed as any).viewConfig.enableScrollableContainerLazyLoading,
2087
+ ).toBeUndefined();
2088
+ expect((liveboardEmbed as any).viewConfig.lazyLoadingMargin).toBeUndefined();
2089
+ });
2090
+
2091
+ test('should not write the defaults back onto the caller view config', async () => {
2092
+ const callerViewConfig = {
2093
+ ...defaultViewConfig,
2094
+ liveboardId,
2095
+ fullHeight: true,
2096
+ } as LiveboardViewConfig;
2097
+
2098
+ new LiveboardEmbed(getRootEl(), callerViewConfig);
2099
+
2100
+ expect(callerViewConfig.lazyLoadingForFullHeight).toBeUndefined();
2101
+ expect(callerViewConfig.enableScrollableContainerLazyLoading).toBeUndefined();
2102
+ expect(callerViewConfig.lazyLoadingMargin).toBeUndefined();
2103
+ });
2104
+
2105
+ test('should not default lazy loading flags when fullHeight is explicitly false', async () => {
2106
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2107
+ ...defaultViewConfig,
2108
+ liveboardId,
2109
+ fullHeight: false,
2110
+ } as LiveboardViewConfig);
2111
+
2112
+ expect((liveboardEmbed as any).viewConfig.lazyLoadingForFullHeight).toBeUndefined();
2113
+ expect(
2114
+ (liveboardEmbed as any).viewConfig.enableScrollableContainerLazyLoading,
2115
+ ).toBeUndefined();
2116
+ expect((liveboardEmbed as any).viewConfig.lazyLoadingMargin).toBeUndefined();
2117
+ });
2118
+
2119
+ test('should default lazyLoadingMargin when lazyLoadingForFullHeight is set explicitly', async () => {
2120
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2121
+ ...defaultViewConfig,
2122
+ liveboardId,
2123
+ fullHeight: true,
2124
+ lazyLoadingForFullHeight: true,
2125
+ } as LiveboardViewConfig);
2126
+
2127
+ expect((liveboardEmbed as any).viewConfig.lazyLoadingMargin).toBe(
2128
+ DEFAULT_LAZY_LOADING_MARGIN,
2129
+ );
2130
+
2131
+ await liveboardEmbed.render();
2132
+
2133
+ await executeAfterWait(() => {
2134
+ expect(getIFrameSrc()).toContain('rootMarginForLazyLoad=500px%200px');
2135
+ }, 100);
2136
+ });
2137
+
2138
+ test('should let an explicit lazyLoadingMargin win over the default', async () => {
2139
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2140
+ ...defaultViewConfig,
2141
+ liveboardId,
2142
+ fullHeight: true,
2143
+ lazyLoadingMargin: '250px',
2144
+ } as LiveboardViewConfig);
2145
+
2146
+ await liveboardEmbed.render();
2147
+
2148
+ await executeAfterWait(() => {
2149
+ const iframeSrc = getIFrameSrc();
2150
+ expect(iframeSrc).toContain('rootMarginForLazyLoad=250px');
2151
+ expect(iframeSrc).not.toContain('rootMarginForLazyLoad=500px%200px');
2152
+ }, 100);
2153
+ });
2154
+
2155
+ test('should drop an invalid lazyLoadingMargin and log an error', async () => {
2156
+ const loggerErrorSpy = jest.spyOn(logger, 'error').mockImplementation(() => undefined);
2157
+
2158
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2159
+ ...defaultViewConfig,
2160
+ liveboardId,
2161
+ fullHeight: true,
2162
+ lazyLoadingMargin: 'not-a-margin',
2163
+ } as LiveboardViewConfig);
2164
+
2165
+ await liveboardEmbed.render();
2166
+
2167
+ await executeAfterWait(() => {
2168
+ const iframeSrc = getIFrameSrc();
2169
+ expect(iframeSrc).toContain('isLazyLoadingForEmbedEnabled=true');
2170
+ expect(iframeSrc).not.toContain('rootMarginForLazyLoad');
2171
+ expect(loggerErrorSpy).toHaveBeenCalledWith(
2172
+ 'Please provide a valid lazyLoadingMargin value (e.g., "10px")',
2173
+ );
2174
+ }, 100);
2175
+ });
2176
+
2177
+ test('should track scrollable ancestors by default when only fullHeight is set', async () => {
2178
+ const scrollContainer = getRootEl();
2179
+ scrollContainer.style.overflow = 'auto';
2180
+
2181
+ const scrollContainerSpy = jest.spyOn(scrollContainer, 'addEventListener');
2182
+ const resizeObserveSpy = jest.fn();
2183
+ const resizeDisconnectSpy = jest.fn();
2184
+ const originalResizeObserver = (window as any).ResizeObserver;
2185
+ (window as any).ResizeObserver = jest.fn().mockImplementation(() => ({
2186
+ observe: resizeObserveSpy,
2187
+ disconnect: resizeDisconnectSpy,
2188
+ }));
2189
+
2190
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2191
+ ...defaultViewConfig,
2192
+ liveboardId,
2193
+ fullHeight: true,
2194
+ } as LiveboardViewConfig);
2195
+
2196
+ await liveboardEmbed.render();
2197
+
2198
+ await executeAfterWait(() => {
2199
+ expect(scrollContainerSpy).toHaveBeenCalledWith('scroll', expect.any(Function));
2200
+ expect(resizeObserveSpy).toHaveBeenCalledWith(scrollContainer);
2201
+ }, 100);
2202
+
2203
+ liveboardEmbed.destroy();
2204
+ expect(resizeDisconnectSpy).toHaveBeenCalled();
2205
+
2206
+ scrollContainer.style.overflow = '';
2207
+ (window as any).ResizeObserver = originalResizeObserver;
2208
+ });
2209
+
2210
+ test('should skip ancestor tracking when enableScrollableContainerLazyLoading is false', async () => {
2211
+ const scrollContainer = getRootEl();
2212
+ scrollContainer.style.overflow = 'auto';
2213
+
2214
+ const scrollContainerSpy = jest.spyOn(scrollContainer, 'addEventListener');
2215
+ const windowSpy = jest.spyOn(window, 'addEventListener');
2216
+
2217
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2218
+ ...defaultViewConfig,
2219
+ liveboardId,
2220
+ fullHeight: true,
2221
+ enableScrollableContainerLazyLoading: false,
2222
+ } as LiveboardViewConfig);
2223
+
2224
+ await liveboardEmbed.render();
2225
+
2226
+ await executeAfterWait(() => {
2227
+ expect(windowSpy).toHaveBeenCalledWith('scroll', expect.anything(), true);
2228
+ expect(scrollContainerSpy).not.toHaveBeenCalledWith('scroll', expect.any(Function));
2229
+ }, 100);
2230
+
2231
+ liveboardEmbed.destroy();
2232
+ scrollContainer.style.overflow = '';
2233
+ });
2234
+
2235
+ test('should wire the window scroll listener to the coordinates sender by default', async () => {
2236
+ const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
2237
+
2238
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2239
+ ...defaultViewConfig,
2240
+ liveboardId,
2241
+ fullHeight: true,
2242
+ } as LiveboardViewConfig);
2243
+
2244
+ const mockTrigger = jest
2245
+ .spyOn(liveboardEmbed, 'trigger')
2246
+ .mockImplementation(() => Promise.resolve(undefined as any));
2247
+
2248
+ await liveboardEmbed.render();
2249
+
2250
+ await executeAfterWait(() => {
2251
+ const scrollCall = addEventListenerSpy.mock.calls.find(
2252
+ ([eventName, , capture]) => eventName === 'scroll' && capture === true,
2253
+ );
2254
+ expect(scrollCall).toBeDefined();
2255
+
2256
+ // Call the handler the way a real scroll event would.
2257
+ (scrollCall as any)[1]();
2258
+
2259
+ expect(mockTrigger).toHaveBeenCalledWith(
2260
+ HostEvent.VisibleEmbedCoordinates,
2261
+ expect.objectContaining({ top: expect.any(Number) }),
2262
+ );
2263
+ }, 100);
2264
+
2265
+ liveboardEmbed.destroy();
2266
+ addEventListenerSpy.mockRestore();
2267
+ });
2268
+
2269
+ test('should remove listeners on destroy when the flags come from defaults', async () => {
2270
+ const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
2271
+
2272
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2273
+ ...defaultViewConfig,
2274
+ liveboardId,
2275
+ fullHeight: true,
2276
+ } as LiveboardViewConfig);
2277
+
2278
+ await liveboardEmbed.render();
2279
+ liveboardEmbed.destroy();
2280
+
2281
+ expect(removeEventListenerSpy).toHaveBeenCalledWith('resize', expect.anything());
2282
+ expect(removeEventListenerSpy).toHaveBeenCalledWith('scroll', expect.anything(), true);
2283
+
2284
+ removeEventListenerSpy.mockRestore();
2285
+ });
2286
+
2287
+ test('should keep an explicit false for the lazy loading flags', async () => {
2288
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2289
+ ...defaultViewConfig,
2290
+ liveboardId,
2291
+ fullHeight: true,
2292
+ lazyLoadingForFullHeight: false,
2293
+ enableScrollableContainerLazyLoading: false,
2294
+ lazyLoadingMargin: '0px',
2295
+ } as LiveboardViewConfig);
2296
+
2297
+ expect((liveboardEmbed as any).viewConfig.lazyLoadingForFullHeight).toBe(false);
2298
+ expect(
2299
+ (liveboardEmbed as any).viewConfig.enableScrollableContainerLazyLoading,
2300
+ ).toBe(false);
2301
+ expect((liveboardEmbed as any).viewConfig.lazyLoadingMargin).toBe('0px');
2302
+ });
2303
+
1813
2304
  test('should not set lazyLoadingForEmbed when lazyLoadingForFullHeight is enabled but fullHeight is false', async () => {
1814
2305
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1815
2306
  ...defaultViewConfig,
@@ -1889,7 +2380,7 @@ describe('Liveboard/viz embed tests', () => {
1889
2380
  });
1890
2381
  });
1891
2382
 
1892
- test('should send correct visible data when RequestVisibleEmbedCoordinates is triggered', async () => {
2383
+ test('should send visible data when fullHeight is enabled and lazyLoadingForFullHeight is omitted', async () => {
1893
2384
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1894
2385
  ...defaultViewConfig,
1895
2386
  liveboardId,
@@ -1904,7 +2395,7 @@ describe('Liveboard/viz embed tests', () => {
1904
2395
  // Trigger the lazy load data calculation
1905
2396
  (liveboardEmbed as any).sendFullHeightLazyLoadData();
1906
2397
 
1907
- expect(mockTrigger).not.toHaveBeenCalledWith(HostEvent.VisibleEmbedCoordinates, {
2398
+ expect(mockTrigger).toHaveBeenCalledWith(HostEvent.VisibleEmbedCoordinates, {
1908
2399
  top: 0,
1909
2400
  height: 500,
1910
2401
  left: 0,
@@ -2306,3 +2797,73 @@ describe('Liveboard/viz embed tests', () => {
2306
2797
  });
2307
2798
  });
2308
2799
  });
2800
+
2801
+ describe('LiveboardEmbed updatedSpotterExperience tests', () => {
2802
+ beforeEach(() => {
2803
+ document.body.innerHTML = getDocumentBody();
2804
+ });
2805
+
2806
+ test('should render the liveboard embed with updatedSpotterExperience', async () => {
2807
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2808
+ ...defaultViewConfig,
2809
+ liveboardId,
2810
+ updatedSpotterExperience: true,
2811
+ } as LiveboardViewConfig);
2812
+ await liveboardEmbed.render();
2813
+ await executeAfterWait(() => {
2814
+ expectUrlMatchesWithParams(
2815
+ getIFrameSrc(),
2816
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}&updatedSpotterExperience=true#/embed/viz/${liveboardId}`,
2817
+ );
2818
+ });
2819
+ });
2820
+
2821
+ test('should render the liveboard embed with updatedSpotterExperience disabled', async () => {
2822
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2823
+ ...defaultViewConfig,
2824
+ liveboardId,
2825
+ updatedSpotterExperience: false,
2826
+ } as LiveboardViewConfig);
2827
+ await liveboardEmbed.render();
2828
+ await executeAfterWait(() => {
2829
+ expectUrlMatchesWithParams(
2830
+ getIFrameSrc(),
2831
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}&updatedSpotterExperience=false#/embed/viz/${liveboardId}`,
2832
+ );
2833
+ });
2834
+ });
2835
+
2836
+ describe('trigger typing contracts (compile-time)', () => {
2837
+ // Enforced by ts-jest at compile time. LiveboardEmbed OVERRIDES
2838
+ // TsEmbed.trigger, so its generic defaults must be asserted separately —
2839
+ // a bare `PayloadT` on the override silently collapses no-payload
2840
+ // responses back to `any` for every LiveboardEmbed consumer.
2841
+ type IsAny<T> = 0 extends 1 & T ? true : false;
2842
+ type Extends<A, B> = A extends B ? true : false;
2843
+
2844
+ it('infers typed response for no-payload calls through the LiveboardEmbed override', () => {
2845
+ const embed = new LiveboardEmbed(getRootEl(), {
2846
+ liveboardId: 'test-liveboard-id',
2847
+ } as LiveboardViewConfig);
2848
+
2849
+ const getTabs = () => embed.trigger(HostEvent.GetTabs);
2850
+ type TabsResponse = Awaited<ReturnType<typeof getTabs>>;
2851
+ const tabsIsTyped: IsAny<TabsResponse> = false;
2852
+ const tabsHasContractFields: Extends<
2853
+ TabsResponse,
2854
+ { numberOfTabs: number; orderedTabIds: string[] }
2855
+ > = true;
2856
+ const probeUnknownField = (r: TabsResponse) =>
2857
+ // @ts-expect-error — field not on the GetTabs contract (was silent when `any`)
2858
+ r.tabCount;
2859
+ void probeUnknownField;
2860
+
2861
+ const reload = () => embed.trigger(HostEvent.Reload);
2862
+ type ReloadResponse = Awaited<ReturnType<typeof reload>>;
2863
+ const reloadStaysAny: IsAny<ReloadResponse> = true;
2864
+
2865
+ expect([tabsIsTyped, tabsHasContractFields, reloadStaysAny])
2866
+ .toEqual([false, true, true]);
2867
+ });
2868
+ });
2869
+ });