@thoughtspot/visual-embed-sdk 1.51.2 → 1.52.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 (316) hide show
  1. package/cjs/package.json +9 -1
  2. package/cjs/src/api-intercept.d.ts.map +1 -1
  3. package/cjs/src/api-intercept.js +1 -0
  4. package/cjs/src/api-intercept.js.map +1 -1
  5. package/cjs/src/contracts/contracts.spec.d.ts +2 -0
  6. package/cjs/src/contracts/contracts.spec.d.ts.map +1 -0
  7. package/cjs/src/contracts/contracts.spec.js +345 -0
  8. package/cjs/src/contracts/contracts.spec.js.map +1 -0
  9. package/cjs/src/contracts/embed-event-payloads.d.ts +73 -0
  10. package/cjs/src/contracts/embed-event-payloads.d.ts.map +1 -0
  11. package/cjs/src/contracts/embed-event-payloads.js +3 -0
  12. package/cjs/src/contracts/embed-event-payloads.js.map +1 -0
  13. package/cjs/src/contracts/host-event-contracts.d.ts +378 -0
  14. package/cjs/src/contracts/host-event-contracts.d.ts.map +1 -0
  15. package/cjs/src/contracts/host-event-contracts.js +3 -0
  16. package/cjs/src/contracts/host-event-contracts.js.map +1 -0
  17. package/cjs/src/contracts/index.d.ts +22 -0
  18. package/cjs/src/contracts/index.d.ts.map +1 -0
  19. package/cjs/src/contracts/index.js +33 -0
  20. package/cjs/src/contracts/index.js.map +1 -0
  21. package/cjs/src/contracts/ui-passthrough-contracts.d.ts +277 -0
  22. package/cjs/src/contracts/ui-passthrough-contracts.d.ts.map +1 -0
  23. package/cjs/src/{embed/hostEventClient/contracts.js → contracts/ui-passthrough-contracts.js} +6 -2
  24. package/cjs/src/contracts/ui-passthrough-contracts.js.map +1 -0
  25. package/cjs/src/css-variables.d.ts +1 -1
  26. package/cjs/src/embed/app.d.ts +17 -140
  27. package/cjs/src/embed/app.d.ts.map +1 -1
  28. package/cjs/src/embed/app.js +20 -120
  29. package/cjs/src/embed/app.js.map +1 -1
  30. package/cjs/src/embed/app.spec.js +70 -26
  31. package/cjs/src/embed/app.spec.js.map +1 -1
  32. package/cjs/src/embed/conversation.d.ts +5 -5
  33. package/cjs/src/embed/events.spec.js +12 -2
  34. package/cjs/src/embed/events.spec.js.map +1 -1
  35. package/cjs/src/embed/hostEventClient/host-event-client.d.ts +3 -2
  36. package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  37. package/cjs/src/embed/hostEventClient/host-event-client.js +23 -18
  38. package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -1
  39. package/cjs/src/embed/hostEventClient/host-event-client.spec.js +36 -36
  40. package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  41. package/cjs/src/embed/hostEventClient/utils.d.ts +1 -1
  42. package/cjs/src/embed/hostEventClient/utils.d.ts.map +1 -1
  43. package/cjs/src/embed/hostEventClient/utils.js +3 -3
  44. package/cjs/src/embed/hostEventClient/utils.js.map +1 -1
  45. package/cjs/src/embed/liveboard.d.ts +9 -161
  46. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  47. package/cjs/src/embed/liveboard.js +68 -135
  48. package/cjs/src/embed/liveboard.js.map +1 -1
  49. package/cjs/src/embed/liveboard.spec.js +215 -32
  50. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  51. package/cjs/src/embed/search.d.ts +14 -0
  52. package/cjs/src/embed/search.d.ts.map +1 -1
  53. package/cjs/src/embed/search.js +4 -1
  54. package/cjs/src/embed/search.js.map +1 -1
  55. package/cjs/src/embed/search.spec.js +65 -0
  56. package/cjs/src/embed/search.spec.js.map +1 -1
  57. package/cjs/src/embed/ts-embed.d.ts +21 -25
  58. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  59. package/cjs/src/embed/ts-embed.js +105 -72
  60. package/cjs/src/embed/ts-embed.js.map +1 -1
  61. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  62. package/cjs/src/embed/ts-embed.spec.js +380 -33
  63. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  64. package/cjs/src/full-height.d.ts +137 -0
  65. package/cjs/src/full-height.d.ts.map +1 -0
  66. package/cjs/src/full-height.js +272 -0
  67. package/cjs/src/full-height.js.map +1 -0
  68. package/cjs/src/full-height.spec.d.ts +2 -0
  69. package/cjs/src/full-height.spec.d.ts.map +1 -0
  70. package/cjs/src/full-height.spec.js +835 -0
  71. package/cjs/src/full-height.spec.js.map +1 -0
  72. package/cjs/src/index.d.ts +4 -3
  73. package/cjs/src/index.d.ts.map +1 -1
  74. package/cjs/src/index.js +5 -4
  75. package/cjs/src/index.js.map +1 -1
  76. package/cjs/src/react/all-types-export.d.ts +1 -1
  77. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  78. package/cjs/src/react/all-types-export.js +2 -1
  79. package/cjs/src/react/all-types-export.js.map +1 -1
  80. package/cjs/src/react/all-types-export.parity.spec.js +55 -3
  81. package/cjs/src/react/all-types-export.parity.spec.js.map +1 -1
  82. package/cjs/src/react/index.d.ts +8 -8
  83. package/cjs/src/react/index.d.ts.map +1 -1
  84. package/cjs/src/react/index.js +1 -1
  85. package/cjs/src/react/index.js.map +1 -1
  86. package/cjs/src/react/index.spec.js +7 -7
  87. package/cjs/src/react/index.spec.js.map +1 -1
  88. package/cjs/src/types.d.ts +664 -39
  89. package/cjs/src/types.d.ts.map +1 -1
  90. package/cjs/src/types.js +406 -13
  91. package/cjs/src/types.js.map +1 -1
  92. package/cjs/src/utils/processTrigger.d.ts +3 -1
  93. package/cjs/src/utils/processTrigger.d.ts.map +1 -1
  94. package/cjs/src/utils/processTrigger.js +19 -51
  95. package/cjs/src/utils/processTrigger.js.map +1 -1
  96. package/cjs/src/utils/transport/iframe-transport.d.ts +55 -0
  97. package/cjs/src/utils/transport/iframe-transport.d.ts.map +1 -0
  98. package/cjs/src/utils/transport/iframe-transport.js +108 -0
  99. package/cjs/src/utils/transport/iframe-transport.js.map +1 -0
  100. package/cjs/src/utils/transport/iframe-transport.spec.d.ts +2 -0
  101. package/cjs/src/utils/transport/iframe-transport.spec.d.ts.map +1 -0
  102. package/cjs/src/utils/transport/iframe-transport.spec.js +140 -0
  103. package/cjs/src/utils/transport/iframe-transport.spec.js.map +1 -0
  104. package/cjs/src/utils.d.ts +18 -0
  105. package/cjs/src/utils.d.ts.map +1 -1
  106. package/cjs/src/utils.js +39 -1
  107. package/cjs/src/utils.js.map +1 -1
  108. package/cjs/src/utils.spec.js +62 -0
  109. package/cjs/src/utils.spec.js.map +1 -1
  110. package/dist/{index-D8_Zs-Nr.js → index-C1pmYb5H.js} +1 -1
  111. package/dist/src/api-intercept.d.ts.map +1 -1
  112. package/dist/src/contracts/contracts.spec.d.ts +2 -0
  113. package/dist/src/contracts/contracts.spec.d.ts.map +1 -0
  114. package/dist/src/contracts/embed-event-payloads.d.ts +73 -0
  115. package/dist/src/contracts/embed-event-payloads.d.ts.map +1 -0
  116. package/dist/src/contracts/host-event-contracts.d.ts +378 -0
  117. package/dist/src/contracts/host-event-contracts.d.ts.map +1 -0
  118. package/dist/src/contracts/index.d.ts +22 -0
  119. package/dist/src/contracts/index.d.ts.map +1 -0
  120. package/dist/src/contracts/ui-passthrough-contracts.d.ts +277 -0
  121. package/dist/src/contracts/ui-passthrough-contracts.d.ts.map +1 -0
  122. package/dist/src/css-variables.d.ts +1 -1
  123. package/dist/src/embed/app.d.ts +17 -140
  124. package/dist/src/embed/app.d.ts.map +1 -1
  125. package/dist/src/embed/conversation.d.ts +5 -5
  126. package/dist/src/embed/hostEventClient/host-event-client.d.ts +3 -2
  127. package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  128. package/dist/src/embed/hostEventClient/utils.d.ts +1 -1
  129. package/dist/src/embed/hostEventClient/utils.d.ts.map +1 -1
  130. package/dist/src/embed/liveboard.d.ts +9 -161
  131. package/dist/src/embed/liveboard.d.ts.map +1 -1
  132. package/dist/src/embed/search.d.ts +14 -0
  133. package/dist/src/embed/search.d.ts.map +1 -1
  134. package/dist/src/embed/ts-embed.d.ts +21 -25
  135. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  136. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  137. package/dist/src/full-height.d.ts +137 -0
  138. package/dist/src/full-height.d.ts.map +1 -0
  139. package/dist/src/full-height.spec.d.ts +2 -0
  140. package/dist/src/full-height.spec.d.ts.map +1 -0
  141. package/dist/src/index.d.ts +4 -3
  142. package/dist/src/index.d.ts.map +1 -1
  143. package/dist/src/react/all-types-export.d.ts +1 -1
  144. package/dist/src/react/all-types-export.d.ts.map +1 -1
  145. package/dist/src/react/index.d.ts +8 -8
  146. package/dist/src/react/index.d.ts.map +1 -1
  147. package/dist/src/types.d.ts +664 -39
  148. package/dist/src/types.d.ts.map +1 -1
  149. package/dist/src/utils/processTrigger.d.ts +3 -1
  150. package/dist/src/utils/processTrigger.d.ts.map +1 -1
  151. package/dist/src/utils/transport/iframe-transport.d.ts +55 -0
  152. package/dist/src/utils/transport/iframe-transport.d.ts.map +1 -0
  153. package/dist/src/utils/transport/iframe-transport.spec.d.ts +2 -0
  154. package/dist/src/utils/transport/iframe-transport.spec.d.ts.map +1 -0
  155. package/dist/src/utils.d.ts +18 -0
  156. package/dist/src/utils.d.ts.map +1 -1
  157. package/dist/tsembed-react.es.js +1031 -392
  158. package/dist/tsembed-react.js +1030 -391
  159. package/dist/tsembed.es.js +1031 -392
  160. package/dist/tsembed.js +1029 -390
  161. package/dist/visual-embed-sdk-react-full.d.ts +1483 -693
  162. package/dist/visual-embed-sdk-react.d.ts +1364 -647
  163. package/dist/visual-embed-sdk.d.ts +1426 -659
  164. package/lib/package.json +9 -1
  165. package/lib/src/api-intercept.d.ts.map +1 -1
  166. package/lib/src/api-intercept.js +2 -1
  167. package/lib/src/api-intercept.js.map +1 -1
  168. package/lib/src/contracts/contracts.spec.d.ts +2 -0
  169. package/lib/src/contracts/contracts.spec.d.ts.map +1 -0
  170. package/lib/src/contracts/contracts.spec.js +342 -0
  171. package/lib/src/contracts/contracts.spec.js.map +1 -0
  172. package/lib/src/contracts/embed-event-payloads.d.ts +73 -0
  173. package/lib/src/contracts/embed-event-payloads.d.ts.map +1 -0
  174. package/lib/src/contracts/embed-event-payloads.js +2 -0
  175. package/lib/src/contracts/embed-event-payloads.js.map +1 -0
  176. package/lib/src/contracts/host-event-contracts.d.ts +378 -0
  177. package/lib/src/contracts/host-event-contracts.d.ts.map +1 -0
  178. package/lib/src/contracts/host-event-contracts.js +2 -0
  179. package/lib/src/contracts/host-event-contracts.js.map +1 -0
  180. package/lib/src/contracts/index.d.ts +22 -0
  181. package/lib/src/contracts/index.d.ts.map +1 -0
  182. package/lib/src/contracts/index.js +22 -0
  183. package/lib/src/contracts/index.js.map +1 -0
  184. package/lib/src/contracts/ui-passthrough-contracts.d.ts +277 -0
  185. package/lib/src/contracts/ui-passthrough-contracts.d.ts.map +1 -0
  186. package/lib/src/{embed/hostEventClient/contracts.js → contracts/ui-passthrough-contracts.js} +6 -2
  187. package/lib/src/contracts/ui-passthrough-contracts.js.map +1 -0
  188. package/lib/src/css-variables.d.ts +1 -1
  189. package/lib/src/embed/app.d.ts +17 -140
  190. package/lib/src/embed/app.d.ts.map +1 -1
  191. package/lib/src/embed/app.js +22 -122
  192. package/lib/src/embed/app.js.map +1 -1
  193. package/lib/src/embed/app.spec.js +70 -26
  194. package/lib/src/embed/app.spec.js.map +1 -1
  195. package/lib/src/embed/conversation.d.ts +5 -5
  196. package/lib/src/embed/events.spec.js +12 -2
  197. package/lib/src/embed/events.spec.js.map +1 -1
  198. package/lib/src/embed/hostEventClient/host-event-client.d.ts +3 -2
  199. package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  200. package/lib/src/embed/hostEventClient/host-event-client.js +6 -1
  201. package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -1
  202. package/lib/src/embed/hostEventClient/host-event-client.spec.js +1 -1
  203. package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  204. package/lib/src/embed/hostEventClient/utils.d.ts +1 -1
  205. package/lib/src/embed/hostEventClient/utils.d.ts.map +1 -1
  206. package/lib/src/embed/hostEventClient/utils.js +1 -1
  207. package/lib/src/embed/hostEventClient/utils.js.map +1 -1
  208. package/lib/src/embed/liveboard.d.ts +9 -161
  209. package/lib/src/embed/liveboard.d.ts.map +1 -1
  210. package/lib/src/embed/liveboard.js +70 -137
  211. package/lib/src/embed/liveboard.js.map +1 -1
  212. package/lib/src/embed/liveboard.spec.js +215 -32
  213. package/lib/src/embed/liveboard.spec.js.map +1 -1
  214. package/lib/src/embed/search.d.ts +14 -0
  215. package/lib/src/embed/search.d.ts.map +1 -1
  216. package/lib/src/embed/search.js +4 -1
  217. package/lib/src/embed/search.js.map +1 -1
  218. package/lib/src/embed/search.spec.js +65 -0
  219. package/lib/src/embed/search.spec.js.map +1 -1
  220. package/lib/src/embed/ts-embed.d.ts +21 -25
  221. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  222. package/lib/src/embed/ts-embed.js +106 -73
  223. package/lib/src/embed/ts-embed.js.map +1 -1
  224. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  225. package/lib/src/embed/ts-embed.spec.js +378 -31
  226. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  227. package/lib/src/full-height.d.ts +137 -0
  228. package/lib/src/full-height.d.ts.map +1 -0
  229. package/lib/src/full-height.js +268 -0
  230. package/lib/src/full-height.js.map +1 -0
  231. package/lib/src/full-height.spec.d.ts +2 -0
  232. package/lib/src/full-height.spec.d.ts.map +1 -0
  233. package/lib/src/full-height.spec.js +833 -0
  234. package/lib/src/full-height.spec.js.map +1 -0
  235. package/lib/src/index.d.ts +4 -3
  236. package/lib/src/index.d.ts.map +1 -1
  237. package/lib/src/index.js +3 -3
  238. package/lib/src/index.js.map +1 -1
  239. package/lib/src/react/all-types-export.d.ts +1 -1
  240. package/lib/src/react/all-types-export.d.ts.map +1 -1
  241. package/lib/src/react/all-types-export.js +1 -1
  242. package/lib/src/react/all-types-export.js.map +1 -1
  243. package/lib/src/react/all-types-export.parity.spec.js +55 -3
  244. package/lib/src/react/all-types-export.parity.spec.js.map +1 -1
  245. package/lib/src/react/index.d.ts +8 -8
  246. package/lib/src/react/index.d.ts.map +1 -1
  247. package/lib/src/react/index.js +1 -1
  248. package/lib/src/react/index.js.map +1 -1
  249. package/lib/src/react/index.spec.js +7 -7
  250. package/lib/src/react/index.spec.js.map +1 -1
  251. package/lib/src/types.d.ts +664 -39
  252. package/lib/src/types.d.ts.map +1 -1
  253. package/lib/src/types.js +405 -12
  254. package/lib/src/types.js.map +1 -1
  255. package/lib/src/utils/processTrigger.d.ts +3 -1
  256. package/lib/src/utils/processTrigger.d.ts.map +1 -1
  257. package/lib/src/utils/processTrigger.js +19 -51
  258. package/lib/src/utils/processTrigger.js.map +1 -1
  259. package/lib/src/utils/transport/iframe-transport.d.ts +55 -0
  260. package/lib/src/utils/transport/iframe-transport.d.ts.map +1 -0
  261. package/lib/src/utils/transport/iframe-transport.js +101 -0
  262. package/lib/src/utils/transport/iframe-transport.js.map +1 -0
  263. package/lib/src/utils/transport/iframe-transport.spec.d.ts +2 -0
  264. package/lib/src/utils/transport/iframe-transport.spec.d.ts.map +1 -0
  265. package/lib/src/utils/transport/iframe-transport.spec.js +138 -0
  266. package/lib/src/utils/transport/iframe-transport.spec.js.map +1 -0
  267. package/lib/src/utils.d.ts +18 -0
  268. package/lib/src/utils.d.ts.map +1 -1
  269. package/lib/src/utils.js +37 -0
  270. package/lib/src/utils.js.map +1 -1
  271. package/lib/src/utils.spec.js +63 -1
  272. package/lib/src/utils.spec.js.map +1 -1
  273. package/lib/src/visual-embed-sdk.d.ts +1426 -659
  274. package/package.json +9 -1
  275. package/src/api-intercept.ts +2 -1
  276. package/src/contracts/contracts.spec.ts +392 -0
  277. package/src/contracts/embed-event-payloads.ts +83 -0
  278. package/src/contracts/host-event-contracts.ts +456 -0
  279. package/src/contracts/index.ts +53 -0
  280. package/src/contracts/ui-passthrough-contracts.ts +301 -0
  281. package/src/css-variables.ts +1 -1
  282. package/src/embed/app.spec.ts +86 -34
  283. package/src/embed/app.ts +37 -264
  284. package/src/embed/conversation.ts +5 -5
  285. package/src/embed/events.spec.ts +14 -2
  286. package/src/embed/hostEventClient/host-event-client.spec.ts +2 -2
  287. package/src/embed/hostEventClient/host-event-client.ts +18 -5
  288. package/src/embed/hostEventClient/utils.ts +2 -1
  289. package/src/embed/liveboard.spec.ts +261 -42
  290. package/src/embed/liveboard.ts +78 -297
  291. package/src/embed/search.spec.ts +80 -0
  292. package/src/embed/search.ts +20 -0
  293. package/src/embed/ts-embed.spec.ts +518 -31
  294. package/src/embed/ts-embed.ts +133 -82
  295. package/src/full-height.spec.ts +1008 -0
  296. package/src/full-height.ts +361 -0
  297. package/src/index.ts +95 -5
  298. package/src/react/all-types-export.parity.spec.ts +63 -3
  299. package/src/react/all-types-export.ts +46 -0
  300. package/src/react/index.spec.tsx +7 -7
  301. package/src/react/index.tsx +9 -9
  302. package/src/types.ts +665 -37
  303. package/src/utils/processTrigger.ts +28 -58
  304. package/src/utils/transport/iframe-transport.spec.ts +177 -0
  305. package/src/utils/transport/iframe-transport.ts +122 -0
  306. package/src/utils.spec.ts +71 -0
  307. package/src/utils.ts +38 -0
  308. package/cjs/src/embed/hostEventClient/contracts.d.ts +0 -231
  309. package/cjs/src/embed/hostEventClient/contracts.d.ts.map +0 -1
  310. package/cjs/src/embed/hostEventClient/contracts.js.map +0 -1
  311. package/dist/src/embed/hostEventClient/contracts.d.ts +0 -231
  312. package/dist/src/embed/hostEventClient/contracts.d.ts.map +0 -1
  313. package/lib/src/embed/hostEventClient/contracts.d.ts +0 -231
  314. package/lib/src/embed/hostEventClient/contracts.d.ts.map +0 -1
  315. package/lib/src/embed/hostEventClient/contracts.js.map +0 -1
  316. package/src/embed/hostEventClient/contracts.ts +0 -262
@@ -31,6 +31,7 @@ import {
31
31
  DefaultAppInitData,
32
32
  ErrorDetailsTypes,
33
33
  EmbedErrorCodes,
34
+ EmbedErrorSeverity,
34
35
  ContextObject,
35
36
  } from '../types';
36
37
  import {
@@ -61,7 +62,7 @@ import { logger } from '../utils/logger';
61
62
  import { version } from '../../package.json';
62
63
  import { HiddenActionItemByDefaultForSearchEmbed } from './search';
63
64
  import { processTrigger } from '../utils/processTrigger';
64
- import { UIPassthroughEvent } from './hostEventClient/contracts';
65
+ import { UIPassthroughEvent } from '../contracts/ui-passthrough-contracts';
65
66
  import * as sessionInfoService from '../utils/sessionInfoService';
66
67
  import * as authToken from '../authToken';
67
68
  import * as apiIntercept from '../api-intercept';
@@ -242,7 +243,10 @@ describe('Unit test case for ts embed', () => {
242
243
  liveboardEmbed.render();
243
244
  mockProcessTrigger.mockResolvedValue({ session: 'test' });
244
245
  await executeAfterWait(async () => {
245
- await liveboardEmbed.trigger(HostEvent.Save, false);
246
+ // `false` is a deliberately off-contract payload here — this
247
+ // asserts raw passthrough to processTrigger, not a real Save
248
+ // payload — so it is cast past the typed `data` parameter.
249
+ await liveboardEmbed.trigger(HostEvent.Save, false as any);
246
250
  expect(mockProcessTrigger).toHaveBeenCalledWith(
247
251
  getIFrameEl(),
248
252
  HostEvent.Save,
@@ -1897,9 +1901,62 @@ describe('Unit test case for ts embed', () => {
1897
1901
  errorType: ErrorDetailsTypes.VALIDATION_ERROR,
1898
1902
  message: ERROR_MESSAGE.INIT_SDK_REQUIRED,
1899
1903
  code: EmbedErrorCodes.INIT_ERROR,
1904
+ severity: EmbedErrorSeverity.SEV1,
1900
1905
  error: ERROR_MESSAGE.INIT_SDK_REQUIRED,
1901
1906
  });
1902
1907
  });
1908
+
1909
+ test('a missing init is reported to the host as SEV1', async () => {
1910
+ const errorHandler = jest.fn();
1911
+ const tsEmbed = new SearchEmbed(getRootEl(), {});
1912
+ tsEmbed.on(EmbedEvent.Error, errorHandler);
1913
+ await tsEmbed.render();
1914
+ expect(errorHandler.mock.calls[0][0]).toEqual(
1915
+ expect.objectContaining({
1916
+ code: EmbedErrorCodes.INIT_ERROR,
1917
+ severity: EmbedErrorSeverity.SEV1,
1918
+ }),
1919
+ );
1920
+ });
1921
+ });
1922
+
1923
+ describe('error severity', () => {
1924
+ beforeEach(() => {
1925
+ jest.spyOn(config, 'getThoughtSpotHost').mockImplementation(() => 'http://tshost');
1926
+ });
1927
+
1928
+ test('defaults to SEV3 when the raising site does not set one', () => {
1929
+ const errorHandler = jest.fn();
1930
+ const tsEmbed = new SearchEmbed(getRootEl(), {});
1931
+ tsEmbed.on(EmbedEvent.Error, errorHandler);
1932
+
1933
+ (tsEmbed as any).handleError({
1934
+ errorType: ErrorDetailsTypes.VALIDATION_ERROR,
1935
+ message: 'no severity set',
1936
+ code: EmbedErrorCodes.HOST_EVENT_VALIDATION,
1937
+ });
1938
+
1939
+ expect(errorHandler.mock.calls[0][0]).toEqual(
1940
+ expect.objectContaining({ severity: EmbedErrorSeverity.SEV3 }),
1941
+ );
1942
+ });
1943
+
1944
+ test('does not override a severity the raising site set', () => {
1945
+ const errorHandler = jest.fn();
1946
+ const tsEmbed = new SearchEmbed(getRootEl(), {});
1947
+ tsEmbed.on(EmbedEvent.Error, errorHandler);
1948
+
1949
+ (tsEmbed as any).handleError({
1950
+ errorType: ErrorDetailsTypes.VALIDATION_ERROR,
1951
+ message: 'explicitly fatal',
1952
+ code: EmbedErrorCodes.HOST_EVENT_VALIDATION,
1953
+ severity: EmbedErrorSeverity.SEV1,
1954
+ });
1955
+
1956
+ expect(errorHandler.mock.calls[0][0]).toEqual(
1957
+ expect.objectContaining({ severity: EmbedErrorSeverity.SEV1 }),
1958
+ );
1959
+ });
1903
1960
  });
1904
1961
 
1905
1962
  describe('V1Embed ', () => {
@@ -3540,13 +3597,13 @@ describe('Unit test case for ts embed', () => {
3540
3597
  libEmbed.destroy();
3541
3598
  });
3542
3599
 
3543
- it('should use preRenderConfig.preRenderId to identify the pre-render instance', async () => {
3600
+ it('should use preRenderConfig.id to identify the pre-render instance', async () => {
3544
3601
  createRootEleForEmbed();
3545
3602
 
3546
3603
  const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
3547
3604
  liveboardId: 'myLiveboardId',
3548
3605
  preRenderConfig: {
3549
- preRenderId: 'config-level-id',
3606
+ id: 'config-level-id',
3550
3607
  },
3551
3608
  });
3552
3609
 
@@ -3560,14 +3617,14 @@ describe('Unit test case for ts embed', () => {
3560
3617
  libEmbed.destroy();
3561
3618
  });
3562
3619
 
3563
- it('should prefer preRenderConfig.preRenderId over top-level preRenderId', async () => {
3620
+ it('should prefer preRenderConfig.id over top-level preRenderId', async () => {
3564
3621
  createRootEleForEmbed();
3565
3622
 
3566
3623
  const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
3567
3624
  liveboardId: 'myLiveboardId',
3568
3625
  preRenderId: 'top-level-id',
3569
3626
  preRenderConfig: {
3570
- preRenderId: 'config-level-id',
3627
+ id: 'config-level-id',
3571
3628
  },
3572
3629
  });
3573
3630
 
@@ -3581,7 +3638,7 @@ describe('Unit test case for ts embed', () => {
3581
3638
  libEmbed.destroy();
3582
3639
  });
3583
3640
 
3584
- it('should mount the wrapper into preRenderConfig.preRenderContainer', async () => {
3641
+ it('should mount the wrapper into preRenderConfig.containerSelector', async () => {
3585
3642
  createRootEleForEmbed();
3586
3643
  const customContainer = document.createElement('div');
3587
3644
  customContainer.id = 'config-level-container';
@@ -3590,8 +3647,8 @@ describe('Unit test case for ts embed', () => {
3590
3647
  const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
3591
3648
  liveboardId: 'myLiveboardId',
3592
3649
  preRenderConfig: {
3593
- preRenderId: 'container-via-config',
3594
- preRenderContainer: '#config-level-container',
3650
+ id: 'container-via-config',
3651
+ containerSelector: '#config-level-container',
3595
3652
  },
3596
3653
  });
3597
3654
 
@@ -3606,7 +3663,7 @@ describe('Unit test case for ts embed', () => {
3606
3663
  customContainer.remove();
3607
3664
  });
3608
3665
 
3609
- it('should prefer preRenderConfig.preRenderContainer over top-level preRenderContainer', async () => {
3666
+ it('should prefer preRenderConfig.containerSelector over top-level preRenderContainer', async () => {
3610
3667
  createRootEleForEmbed();
3611
3668
  const topContainer = document.createElement('div');
3612
3669
  topContainer.id = 'top-level-container';
@@ -3619,8 +3676,8 @@ describe('Unit test case for ts embed', () => {
3619
3676
  liveboardId: 'myLiveboardId',
3620
3677
  preRenderContainer: '#top-level-container',
3621
3678
  preRenderConfig: {
3622
- preRenderId: 'container-precedence',
3623
- preRenderContainer: '#config-level-container-2',
3679
+ id: 'container-precedence',
3680
+ containerSelector: '#config-level-container-2',
3624
3681
  },
3625
3682
  });
3626
3683
 
@@ -3637,7 +3694,7 @@ describe('Unit test case for ts embed', () => {
3637
3694
  configContainer.remove();
3638
3695
  });
3639
3696
 
3640
- it('should not attach ResizeObserver when preRenderConfig.doNotTrackPreRenderSize is true', async () => {
3697
+ it('should not attach ResizeObserver when preRenderConfig.doNotTrackSize is true', async () => {
3641
3698
  createRootEleForEmbed();
3642
3699
  const observeMock = jest.fn();
3643
3700
  (window as any).ResizeObserver = jest.fn().mockImplementation(() => ({
@@ -3649,8 +3706,8 @@ describe('Unit test case for ts embed', () => {
3649
3706
  const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
3650
3707
  liveboardId: 'myLiveboardId',
3651
3708
  preRenderConfig: {
3652
- preRenderId: 'no-track-via-config',
3653
- doNotTrackPreRenderSize: true,
3709
+ id: 'no-track-via-config',
3710
+ doNotTrackSize: true,
3654
3711
  },
3655
3712
  });
3656
3713
 
@@ -3663,7 +3720,7 @@ describe('Unit test case for ts embed', () => {
3663
3720
  libEmbed.destroy();
3664
3721
  });
3665
3722
 
3666
- it('should prefer preRenderConfig.doNotTrackPreRenderSize over top-level doNotTrackPreRenderSize', async () => {
3723
+ it('should prefer preRenderConfig.doNotTrackSize over top-level doNotTrackPreRenderSize', async () => {
3667
3724
  createRootEleForEmbed();
3668
3725
  const observeMock = jest.fn();
3669
3726
  (window as any).ResizeObserver = jest.fn().mockImplementation(() => ({
@@ -3676,8 +3733,8 @@ describe('Unit test case for ts embed', () => {
3676
3733
  liveboardId: 'myLiveboardId',
3677
3734
  doNotTrackPreRenderSize: false,
3678
3735
  preRenderConfig: {
3679
- preRenderId: 'no-track-precedence',
3680
- doNotTrackPreRenderSize: true,
3736
+ id: 'no-track-precedence',
3737
+ doNotTrackSize: true,
3681
3738
  },
3682
3739
  });
3683
3740
 
@@ -4323,7 +4380,9 @@ describe('Unit test case for ts embed', () => {
4323
4380
 
4324
4381
  test('should return getPreRenderObj and log if same object', () => {
4325
4382
  const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
4326
- const loggerSpy = jest.spyOn(logger, 'info');
4383
+ // debug, not info: the wrapper points at the embed being shown, so
4384
+ // this is now the common case rather than a rare diagnostic.
4385
+ const loggerSpy = jest.spyOn(logger, 'debug');
4327
4386
 
4328
4387
  // getPreRenderObj reads the embed reference from preRenderWrapper
4329
4388
  (searchEmbed as any).preRenderWrapper = {
@@ -5215,16 +5274,6 @@ describe('Additional Coverage Tests', () => {
5215
5274
  });
5216
5275
  });
5217
5276
 
5218
- test('should test getIframeCenter calculation', async () => {
5219
- const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
5220
- await searchEmbed.render();
5221
- await executeAfterWait(() => {
5222
- const center = searchEmbed['getIframeCenter']();
5223
- expect(center).toHaveProperty('iframeCenter');
5224
- expect(center).toHaveProperty('iframeHeight');
5225
- expect(center).toHaveProperty('viewPortHeight');
5226
- });
5227
- });
5228
5277
 
5229
5278
  test('should handle preRender with replaceExistingPreRender=true', async () => {
5230
5279
  createRootEleForEmbed();
@@ -5626,7 +5675,8 @@ describe('ShowPreRender with UpdateEmbedParams', () => {
5626
5675
  embed2.showPreRender();
5627
5676
 
5628
5677
  await executeAfterWait(() => {
5629
- expect(mockProcessTrigger).toHaveBeenLastCalledWith(
5678
+ // Not LastCalledWith: LiveboardEmbed fires Navigate after this.
5679
+ expect(mockProcessTrigger).toHaveBeenCalledWith(
5630
5680
  expect.any(Object),
5631
5681
  HostEvent.UpdateEmbedParams,
5632
5682
  expect.any(String),
@@ -5679,7 +5729,8 @@ describe('ShowPreRender with UpdateEmbedParams', () => {
5679
5729
  embed2.showPreRender();
5680
5730
 
5681
5731
  await executeAfterWait(() => {
5682
- expect(mockProcessTrigger).toHaveBeenLastCalledWith(
5732
+ // Not LastCalledWith: LiveboardEmbed fires Navigate after this.
5733
+ expect(mockProcessTrigger).toHaveBeenCalledWith(
5683
5734
  expect.any(Object),
5684
5735
  HostEvent.UpdateEmbedParams,
5685
5736
  expect.any(String),
@@ -5699,6 +5750,442 @@ describe('ShowPreRender with UpdateEmbedParams', () => {
5699
5750
  });
5700
5751
  });
5701
5752
 
5753
+ test('should carry the new config filters in UpdateEmbedParams', async () => {
5754
+ await setupPreRenderTest('params-new-filters', { liveboardId: 'original-lb' });
5755
+
5756
+ const runtimeFilters = [
5757
+ {
5758
+ columnName: 'Color',
5759
+ operator: RuntimeFilterOp.IN,
5760
+ values: ['red', 'blue'],
5761
+ },
5762
+ ];
5763
+
5764
+ const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
5765
+ preRenderId: 'params-new-filters',
5766
+ liveboardId: 'original-lb',
5767
+ runtimeFilters,
5768
+ });
5769
+
5770
+ embed2.showPreRender();
5771
+
5772
+ await executeAfterWait(() => {
5773
+ expect(mockProcessTrigger).toHaveBeenCalledWith(
5774
+ expect.any(Object),
5775
+ HostEvent.UpdateEmbedParams,
5776
+ expect.any(String),
5777
+ expect.objectContaining({
5778
+ runtimeFilters,
5779
+ // The serialized form is the one the container reads.
5780
+ runtimeFilterParams: 'col1=Color&op1=IN&val1=red&val1=blue',
5781
+ }),
5782
+ undefined,
5783
+ );
5784
+
5785
+ // Everything rides in the params payload; nothing follows it.
5786
+ const runtimeFilterCalls = mockProcessTrigger.mock.calls.filter(
5787
+ (call: any[]) => call[1] === HostEvent.UpdateRuntimeFilters,
5788
+ );
5789
+ expect(runtimeFilterCalls).toHaveLength(0);
5790
+ });
5791
+ });
5792
+
5793
+ test('should serialize the filters when they are not excluded from the URL', async () => {
5794
+ await setupPreRenderTest('params-url-filters', { liveboardId: 'original-lb' });
5795
+
5796
+ // With the flag off, getDefaultAppInitData leaves runtimeFilterParams
5797
+ // null and a URL render carries the filters in the iframe's query
5798
+ // string. A show cycle has no URL, so the payload has to carry them.
5799
+ const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
5800
+ preRenderId: 'params-url-filters',
5801
+ liveboardId: 'original-lb',
5802
+ excludeRuntimeFiltersfromURL: false,
5803
+ runtimeFilters: [
5804
+ {
5805
+ columnName: 'Color',
5806
+ operator: RuntimeFilterOp.IN,
5807
+ values: ['red'],
5808
+ },
5809
+ ],
5810
+ });
5811
+
5812
+ embed2.showPreRender();
5813
+
5814
+ await executeAfterWait(() => {
5815
+ expect(mockProcessTrigger).toHaveBeenCalledWith(
5816
+ expect.any(Object),
5817
+ HostEvent.UpdateEmbedParams,
5818
+ expect.any(String),
5819
+ expect.objectContaining({
5820
+ runtimeFilterParams: 'col1=Color&op1=IN&val1=red',
5821
+ }),
5822
+ undefined,
5823
+ );
5824
+ });
5825
+ });
5826
+
5827
+ test('should trigger Navigate only after UpdateEmbedParams has settled', async () => {
5828
+ await setupPreRenderTest('navigate-after-params', {
5829
+ liveboardId: 'original-lb',
5830
+ runtimeFilters: [
5831
+ {
5832
+ columnName: 'Color',
5833
+ operator: RuntimeFilterOp.IN,
5834
+ values: ['red'],
5835
+ },
5836
+ ],
5837
+ });
5838
+
5839
+ const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
5840
+ preRenderId: 'navigate-after-params',
5841
+ liveboardId: 'updated-lb',
5842
+ });
5843
+
5844
+ embed2.showPreRender();
5845
+
5846
+ // Inside the settle window the params are already out
5847
+ // and Navigate is not.
5848
+ await executeAfterWait(() => {
5849
+ const eventTypes = mockProcessTrigger.mock.calls.map((call: any[]) => call[1]);
5850
+ expect(eventTypes).toContain(HostEvent.UpdateEmbedParams);
5851
+ expect(eventTypes).not.toContain(HostEvent.Navigate);
5852
+ }, 50);
5853
+
5854
+ await executeAfterWait(() => {
5855
+ const eventTypes = mockProcessTrigger.mock.calls.map((call: any[]) => call[1]);
5856
+ // A Navigate that beat the params would make the container load
5857
+ // `updated-lb` while still holding `original-lb`'s runtime filters,
5858
+ // and drop the params that then arrive mid-load (SCAL-336321).
5859
+ expect(eventTypes).toContain(HostEvent.Navigate);
5860
+ expect(eventTypes.indexOf(HostEvent.UpdateEmbedParams)).toBeLessThan(
5861
+ eventTypes.indexOf(HostEvent.Navigate),
5862
+ );
5863
+ }, 300);
5864
+ });
5865
+
5866
+ test('should mark the params empty when the config declares no filters', async () => {
5867
+ await setupPreRenderTest('params-clear-filters', {
5868
+ liveboardId: 'original-lb',
5869
+ runtimeFilters: [
5870
+ {
5871
+ columnName: 'Color',
5872
+ operator: RuntimeFilterOp.IN,
5873
+ values: ['red', 'blue'],
5874
+ },
5875
+ ],
5876
+ });
5877
+
5878
+ const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
5879
+ preRenderId: 'params-clear-filters',
5880
+ liveboardId: 'original-lb',
5881
+ });
5882
+
5883
+ embed2.showPreRender();
5884
+
5885
+ await executeAfterWait(() => {
5886
+ // Not null and not '': the container only reads this field when it
5887
+ // is truthy, so either would leave the previous embed's filters in
5888
+ // place. A lone separator passes that gate and parses to {}.
5889
+ expect(mockProcessTrigger).toHaveBeenCalledWith(
5890
+ expect.any(Object),
5891
+ HostEvent.UpdateEmbedParams,
5892
+ expect.any(String),
5893
+ expect.objectContaining({ runtimeFilterParams: '&' }),
5894
+ undefined,
5895
+ );
5896
+
5897
+ const runtimeFilterCalls = mockProcessTrigger.mock.calls.filter(
5898
+ (call: any[]) => call[1] === HostEvent.UpdateRuntimeFilters,
5899
+ );
5900
+ expect(runtimeFilterCalls).toHaveLength(0);
5901
+ });
5902
+ });
5903
+
5904
+ test('should mark the params empty for an explicitly empty filter array', async () => {
5905
+ await setupPreRenderTest('params-empty-array', {
5906
+ liveboardId: 'original-lb',
5907
+ runtimeFilters: [
5908
+ {
5909
+ columnName: 'Color',
5910
+ operator: RuntimeFilterOp.IN,
5911
+ values: ['red'],
5912
+ },
5913
+ ],
5914
+ });
5915
+
5916
+ // `runtimeFilters: []` is the shape the customer reported as not
5917
+ // resetting anything.
5918
+ const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
5919
+ preRenderId: 'params-empty-array',
5920
+ liveboardId: 'original-lb',
5921
+ runtimeFilters: [],
5922
+ });
5923
+
5924
+ embed2.showPreRender();
5925
+
5926
+ await executeAfterWait(() => {
5927
+ expect(mockProcessTrigger).toHaveBeenCalledWith(
5928
+ expect.any(Object),
5929
+ HostEvent.UpdateEmbedParams,
5930
+ expect.any(String),
5931
+ expect.objectContaining({ runtimeFilterParams: '&' }),
5932
+ undefined,
5933
+ );
5934
+ });
5935
+ });
5936
+
5937
+ test('should mark the params empty when no config in the chain has filters', async () => {
5938
+ await setupPreRenderTest('params-no-filters', { liveboardId: 'original-lb' });
5939
+
5940
+ const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
5941
+ preRenderId: 'params-no-filters',
5942
+ liveboardId: 'updated-lb',
5943
+ });
5944
+
5945
+ embed2.showPreRender();
5946
+
5947
+ await executeAfterWait(() => {
5948
+ const paramsCall = mockProcessTrigger.mock.calls.find(
5949
+ (call: any[]) => call[1] === HostEvent.UpdateEmbedParams,
5950
+ );
5951
+ expect(paramsCall?.[3]).not.toHaveProperty('runtimeFilters');
5952
+ expect(paramsCall?.[3].runtimeFilterParams).toBe('&');
5953
+ });
5954
+ });
5955
+
5956
+ test('should state each embed filters as the pre-render is handed along', async () => {
5957
+ await setupPreRenderTest('params-chain', {
5958
+ liveboardId: 'original-lb',
5959
+ runtimeFilters: [
5960
+ {
5961
+ columnName: 'Color',
5962
+ operator: RuntimeFilterOp.IN,
5963
+ values: ['red', 'blue'],
5964
+ },
5965
+ ],
5966
+ });
5967
+
5968
+ // Second in the chain declares none, so it empties the field rather
5969
+ // than letting the creator's filters stand.
5970
+ const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
5971
+ preRenderId: 'params-chain',
5972
+ liveboardId: 'second-lb',
5973
+ });
5974
+ await embed2.showPreRender();
5975
+ await executeAfterWait(() => {
5976
+ expect(mockProcessTrigger).toHaveBeenCalledWith(
5977
+ expect.any(Object),
5978
+ HostEvent.UpdateEmbedParams,
5979
+ expect.any(String),
5980
+ expect.objectContaining({ runtimeFilterParams: '&' }),
5981
+ undefined,
5982
+ );
5983
+ });
5984
+
5985
+ mockProcessTrigger.mockClear();
5986
+
5987
+ // Third declares its own, and states them without reference to either
5988
+ // embed before it.
5989
+ const embed3 = new LiveboardEmbed('#tsEmbedDiv', {
5990
+ preRenderId: 'params-chain',
5991
+ liveboardId: 'third-lb',
5992
+ runtimeFilters: [
5993
+ {
5994
+ columnName: 'Region',
5995
+ operator: RuntimeFilterOp.EQ,
5996
+ values: ['North'],
5997
+ },
5998
+ ],
5999
+ });
6000
+ await embed3.showPreRender();
6001
+
6002
+ await executeAfterWait(() => {
6003
+ expect(mockProcessTrigger).toHaveBeenCalledWith(
6004
+ expect.any(Object),
6005
+ HostEvent.UpdateEmbedParams,
6006
+ expect.any(String),
6007
+ expect.objectContaining({
6008
+ runtimeFilterParams: 'col1=Region&op1=EQ&val1=North',
6009
+ }),
6010
+ undefined,
6011
+ );
6012
+ });
6013
+ });
6014
+
6015
+ test('should carry the new config runtime parameters in UpdateEmbedParams', async () => {
6016
+ await setupPreRenderTest('params-parameters', {
6017
+ liveboardId: 'original-lb',
6018
+ runtimeParameters: [{ name: 'Region Param', value: 'East' }],
6019
+ });
6020
+
6021
+ const runtimeParameters = [{ name: 'Region Param', value: 'West' }];
6022
+ const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
6023
+ preRenderId: 'params-parameters',
6024
+ liveboardId: 'original-lb',
6025
+ runtimeParameters,
6026
+ });
6027
+
6028
+ embed2.showPreRender();
6029
+
6030
+ await executeAfterWait(() => {
6031
+ expect(mockProcessTrigger).toHaveBeenCalledWith(
6032
+ expect.any(Object),
6033
+ HostEvent.UpdateEmbedParams,
6034
+ expect.any(String),
6035
+ expect.objectContaining({
6036
+ runtimeParameters,
6037
+ runtimeParameterParams: 'param1=Region%20Param&paramVal1=West',
6038
+ }),
6039
+ undefined,
6040
+ );
6041
+
6042
+ // A parameter always carries a value, so the payload says everything
6043
+ // there is to say — no follow-up event.
6044
+ const parameterCalls = mockProcessTrigger.mock.calls.filter(
6045
+ (call: any[]) => call[1] === HostEvent.UpdateParameters,
6046
+ );
6047
+ expect(parameterCalls).toHaveLength(0);
6048
+ });
6049
+ });
6050
+
6051
+ test('should mark the params empty when the config declares no parameters', async () => {
6052
+ await setupPreRenderTest('params-clear-parameters', {
6053
+ liveboardId: 'original-lb',
6054
+ runtimeParameters: [{ name: 'Region Param', value: 'East' }],
6055
+ });
6056
+
6057
+ const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
6058
+ preRenderId: 'params-clear-parameters',
6059
+ liveboardId: 'original-lb',
6060
+ });
6061
+
6062
+ embed2.showPreRender();
6063
+
6064
+ await executeAfterWait(() => {
6065
+ // Same gate as the filters: the container only reads this field
6066
+ // when it is truthy, so null would leave 'East' standing.
6067
+ expect(mockProcessTrigger).toHaveBeenCalledWith(
6068
+ expect.any(Object),
6069
+ HostEvent.UpdateEmbedParams,
6070
+ expect.any(String),
6071
+ expect.objectContaining({ runtimeParameterParams: '&' }),
6072
+ undefined,
6073
+ );
6074
+ });
6075
+ });
6076
+
6077
+ test('should keep an empty string parameter value distinct from having none', async () => {
6078
+ await setupPreRenderTest('params-empty-value', { liveboardId: 'original-lb' });
6079
+
6080
+ // `paramVal1=` is that parameter's value, not an absence — so it must
6081
+ // not collapse to the empty marker.
6082
+ const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
6083
+ preRenderId: 'params-empty-value',
6084
+ liveboardId: 'original-lb',
6085
+ runtimeParameters: [{ name: 'Region Param', value: '' }],
6086
+ });
6087
+
6088
+ embed2.showPreRender();
6089
+
6090
+ await executeAfterWait(() => {
6091
+ expect(mockProcessTrigger).toHaveBeenCalledWith(
6092
+ expect.any(Object),
6093
+ HostEvent.UpdateEmbedParams,
6094
+ expect.any(String),
6095
+ expect.objectContaining({
6096
+ runtimeParameterParams: 'param1=Region%20Param&paramVal1=',
6097
+ }),
6098
+ undefined,
6099
+ );
6100
+ });
6101
+ });
6102
+
6103
+
6104
+ test('should hand the pre-render over to the embed being shown', async () => {
6105
+ const embed1 = await setupPreRenderTest('take-over-state', { liveboardId: 'original-lb' });
6106
+
6107
+ const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
6108
+ preRenderId: 'take-over-state',
6109
+ liveboardId: 'second-lb',
6110
+ });
6111
+
6112
+ await embed2.showPreRender();
6113
+
6114
+ // It connected to embed1's pre-render and is now what the wrapper
6115
+ // points at, so getPreRenderObj() means "what is showing".
6116
+ expect((embed2 as any).getPreRenderObj()).toBe(embed2);
6117
+ expect((embed1 as any).getPreRenderObj()).toBe(embed2);
6118
+ });
6119
+
6120
+ test('should not strand callbacks when the container loads after the shown embed was hidden', async () => {
6121
+ // The creator is subscribed but the container has NOT announced itself
6122
+ // yet, which is the state a real pre-render starts in.
6123
+ const embed1 = await setupPreRenderTest('loaded-after-hide', { liveboardId: 'original-lb' });
6124
+ embed1.isEmbedContainerLoaded = false;
6125
+
6126
+ // Second embed shows, takes the pre-render over, then is hidden — which
6127
+ // unsubscribes it, so it will never hear EmbedListenerReady itself.
6128
+ const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
6129
+ preRenderId: 'loaded-after-hide',
6130
+ liveboardId: 'second-lb',
6131
+ });
6132
+ await embed2.showPreRender();
6133
+ embed2.hidePreRender();
6134
+ expect(embed2.isEmbedContainerLoaded).toBe(false);
6135
+
6136
+ // Container comes up and the creator hears it.
6137
+ (embed1 as any).createEmbedContainerHandler(EmbedEvent.EmbedListenerReady)();
6138
+
6139
+ mockProcessTrigger.mockClear();
6140
+ mockProcessTrigger.mockResolvedValue({});
6141
+
6142
+ // A third embed reads the state off embed2, which owns the wrapper and
6143
+ // never learned the container was up. Reading a per-instance snapshot
6144
+ // here leaves UpdateEmbedParams queued forever and the pre-render stuck
6145
+ // on the previous liveboard.
6146
+ const embed3 = new LiveboardEmbed('#tsEmbedDiv', {
6147
+ preRenderId: 'loaded-after-hide',
6148
+ liveboardId: 'third-lb',
6149
+ });
6150
+ await embed3.showPreRender();
6151
+
6152
+ expect(embed3.isEmbedContainerLoaded).toBe(true);
6153
+ await executeAfterWait(() => {
6154
+ const eventTypes = mockProcessTrigger.mock.calls.map((call: any[]) => call[1]);
6155
+ expect(eventTypes).toContain(HostEvent.UpdateEmbedParams);
6156
+ }, 300);
6157
+ });
6158
+
6159
+ test('should not reconcile runtime filters unless the view config opts in', async () => {
6160
+ await setupPreRenderTest('reconcile-flag-off', {
6161
+ liveboardId: 'original-lb',
6162
+ runtimeFilters: [
6163
+ {
6164
+ columnName: 'Color',
6165
+ operator: RuntimeFilterOp.IN,
6166
+ values: ['red', 'blue'],
6167
+ },
6168
+ ],
6169
+ });
6170
+
6171
+ // Same shape as the clear-filters case above, minus the flag: the
6172
+ // previous config left filters on the shared pre-render and this one
6173
+ // declares none. Without preRenderConfig.reconcileRuntimeParams the SDK
6174
+ // leaves that to the container, so no UpdateRuntimeFilters goes out.
6175
+ const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
6176
+ preRenderId: 'reconcile-flag-off',
6177
+ liveboardId: 'original-lb',
6178
+ });
6179
+
6180
+ embed2.showPreRender();
6181
+
6182
+ await executeAfterWait(() => {
6183
+ const eventTypes = mockProcessTrigger.mock.calls.map((call: any[]) => call[1]);
6184
+ expect(eventTypes).toContain(HostEvent.UpdateEmbedParams);
6185
+ expect(eventTypes).not.toContain(HostEvent.UpdateRuntimeFilters);
6186
+ });
6187
+ });
6188
+
5702
6189
  test('should handle error when getUpdateEmbedParamsObject fails during showPreRender', async () => {
5703
6190
  await setupPreRenderTest('error-test', { liveboardId: 'original-lb' });
5704
6191