@thoughtspot/visual-embed-sdk 1.49.1 → 1.49.2
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.
- package/cjs/package.json +1 -1
- package/cjs/src/css-variables.d.ts +17 -0
- package/cjs/src/css-variables.d.ts.map +1 -1
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +4 -1
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +97 -0
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/conversation.d.ts +8 -0
- package/cjs/src/embed/conversation.d.ts.map +1 -1
- package/cjs/src/embed/conversation.js +2 -1
- package/cjs/src/embed/conversation.js.map +1 -1
- package/cjs/src/embed/conversation.spec.js +12 -0
- package/cjs/src/embed/conversation.spec.js.map +1 -1
- package/cjs/src/embed/events.spec.js +5 -0
- package/cjs/src/embed/events.spec.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +4 -1
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +11 -0
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +38 -0
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +166 -9
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +237 -0
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/types.d.ts +87 -4
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +47 -3
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/processTrigger.d.ts.map +1 -1
- package/cjs/src/utils/processTrigger.js +6 -5
- package/cjs/src/utils/processTrigger.js.map +1 -1
- package/cjs/src/utils/processTrigger.spec.js +13 -0
- package/cjs/src/utils/processTrigger.spec.js.map +1 -1
- package/cjs/src/utils.d.ts +10 -0
- package/cjs/src/utils.d.ts.map +1 -1
- package/cjs/src/utils.js +23 -1
- package/cjs/src/utils.js.map +1 -1
- package/cjs/src/utils.spec.js +48 -0
- package/cjs/src/utils.spec.js.map +1 -1
- package/dist/{index-B6Rn561t.js → index-CS7yJ2Jj.js} +1 -1
- package/dist/src/css-variables.d.ts +17 -0
- package/dist/src/css-variables.d.ts.map +1 -1
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/conversation.d.ts +8 -0
- package/dist/src/embed/conversation.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +38 -0
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/types.d.ts +87 -4
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/processTrigger.d.ts.map +1 -1
- package/dist/src/utils.d.ts +10 -0
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +253 -23
- package/dist/tsembed-react.js +252 -22
- package/dist/tsembed.es.js +253 -23
- package/dist/tsembed.js +252 -22
- package/dist/visual-embed-sdk-react-full.d.ts +148 -3
- package/dist/visual-embed-sdk-react.d.ts +148 -3
- package/dist/visual-embed-sdk.d.ts +148 -3
- package/lib/package.json +1 -1
- package/lib/src/css-variables.d.ts +17 -0
- package/lib/src/css-variables.d.ts.map +1 -1
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +4 -1
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +97 -0
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/conversation.d.ts +8 -0
- package/lib/src/embed/conversation.d.ts.map +1 -1
- package/lib/src/embed/conversation.js +2 -1
- package/lib/src/embed/conversation.js.map +1 -1
- package/lib/src/embed/conversation.spec.js +12 -0
- package/lib/src/embed/conversation.spec.js.map +1 -1
- package/lib/src/embed/events.spec.js +5 -0
- package/lib/src/embed/events.spec.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +4 -1
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +11 -0
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +38 -0
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +167 -10
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +237 -0
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/types.d.ts +87 -4
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +47 -3
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/processTrigger.d.ts.map +1 -1
- package/lib/src/utils/processTrigger.js +6 -5
- package/lib/src/utils/processTrigger.js.map +1 -1
- package/lib/src/utils/processTrigger.spec.js +13 -0
- package/lib/src/utils/processTrigger.spec.js.map +1 -1
- package/lib/src/utils.d.ts +10 -0
- package/lib/src/utils.d.ts.map +1 -1
- package/lib/src/utils.js +21 -0
- package/lib/src/utils.js.map +1 -1
- package/lib/src/utils.spec.js +49 -1
- package/lib/src/utils.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +148 -3
- package/package.json +1 -1
- package/src/css-variables.ts +20 -0
- package/src/embed/app.spec.ts +109 -0
- package/src/embed/app.ts +4 -0
- package/src/embed/conversation.spec.ts +17 -0
- package/src/embed/conversation.ts +10 -0
- package/src/embed/events.spec.ts +7 -0
- package/src/embed/liveboard.spec.ts +15 -0
- package/src/embed/liveboard.ts +4 -0
- package/src/embed/ts-embed.spec.ts +294 -0
- package/src/embed/ts-embed.ts +180 -9
- package/src/types.ts +86 -3
- package/src/utils/processTrigger.spec.ts +23 -0
- package/src/utils/processTrigger.ts +8 -6
- package/src/utils.spec.ts +63 -0
- package/src/utils.ts +24 -0
package/src/embed/app.spec.ts
CHANGED
|
@@ -757,6 +757,20 @@ describe('App embed tests', () => {
|
|
|
757
757
|
});
|
|
758
758
|
});
|
|
759
759
|
|
|
760
|
+
test('should set enableStarterPrompts to true in url', async () => {
|
|
761
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
762
|
+
...defaultViewConfig,
|
|
763
|
+
spotterChatConfig: { enableStarterPrompts: true },
|
|
764
|
+
} as AppViewConfig);
|
|
765
|
+
appEmbed.render();
|
|
766
|
+
await executeAfterWait(() => {
|
|
767
|
+
expectUrlMatchesWithParams(
|
|
768
|
+
getIFrameSrc(),
|
|
769
|
+
`http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&enableStarterPrompts=true${defaultParamsPost}#/home`,
|
|
770
|
+
);
|
|
771
|
+
});
|
|
772
|
+
});
|
|
773
|
+
|
|
760
774
|
test('should set spotterFileUploadFileTypes in url', async () => {
|
|
761
775
|
const appEmbed = new AppEmbed(getRootEl(), {
|
|
762
776
|
...defaultViewConfig,
|
|
@@ -2120,6 +2134,101 @@ describe('App Embed Default Height and Minimum Height Handling', () => {
|
|
|
2120
2134
|
});
|
|
2121
2135
|
});
|
|
2122
2136
|
|
|
2137
|
+
describe('AppEmbed uncovered branch tests', () => {
|
|
2138
|
+
beforeEach(() => {
|
|
2139
|
+
document.body.innerHTML = getDocumentBody();
|
|
2140
|
+
});
|
|
2141
|
+
|
|
2142
|
+
test('should set enableStopAnswerGenerationEmbed param when provided', async () => {
|
|
2143
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
2144
|
+
...defaultViewConfig,
|
|
2145
|
+
enableStopAnswerGenerationEmbed: true,
|
|
2146
|
+
} as AppViewConfig);
|
|
2147
|
+
appEmbed.render();
|
|
2148
|
+
await executeAfterWait(() => {
|
|
2149
|
+
expectUrlToHaveParamsWithValues(getIFrameSrc(), {
|
|
2150
|
+
enableStopAnswerGenerationEmbed: 'true',
|
|
2151
|
+
});
|
|
2152
|
+
});
|
|
2153
|
+
});
|
|
2154
|
+
|
|
2155
|
+
test('should set enableStopAnswerGenerationEmbed=false when set to false', async () => {
|
|
2156
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
2157
|
+
...defaultViewConfig,
|
|
2158
|
+
enableStopAnswerGenerationEmbed: false,
|
|
2159
|
+
} as AppViewConfig);
|
|
2160
|
+
appEmbed.render();
|
|
2161
|
+
await executeAfterWait(() => {
|
|
2162
|
+
expectUrlToHaveParamsWithValues(getIFrameSrc(), {
|
|
2163
|
+
enableStopAnswerGenerationEmbed: 'false',
|
|
2164
|
+
});
|
|
2165
|
+
});
|
|
2166
|
+
});
|
|
2167
|
+
|
|
2168
|
+
test('should set hideObjects param when non-empty array is provided', async () => {
|
|
2169
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
2170
|
+
...defaultViewConfig,
|
|
2171
|
+
hideObjects: ['guid-123', 'guid-456'],
|
|
2172
|
+
} as AppViewConfig);
|
|
2173
|
+
appEmbed.render();
|
|
2174
|
+
await executeAfterWait(() => {
|
|
2175
|
+
expectUrlToHaveParamsWithValues(getIFrameSrc(), {
|
|
2176
|
+
hideObjects: JSON.stringify(['guid-123', 'guid-456']),
|
|
2177
|
+
});
|
|
2178
|
+
});
|
|
2179
|
+
});
|
|
2180
|
+
|
|
2181
|
+
test('should not set hideObjects param when array is empty', async () => {
|
|
2182
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
2183
|
+
...defaultViewConfig,
|
|
2184
|
+
hideObjects: [],
|
|
2185
|
+
} as AppViewConfig);
|
|
2186
|
+
appEmbed.render();
|
|
2187
|
+
await executeAfterWait(() => {
|
|
2188
|
+
const src = getIFrameSrc();
|
|
2189
|
+
expect(src).not.toContain('hideObjects');
|
|
2190
|
+
});
|
|
2191
|
+
});
|
|
2192
|
+
|
|
2193
|
+
test('should set liveboardV2 param when provided', async () => {
|
|
2194
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
2195
|
+
...defaultViewConfig,
|
|
2196
|
+
liveboardV2: true,
|
|
2197
|
+
} as AppViewConfig);
|
|
2198
|
+
appEmbed.render();
|
|
2199
|
+
await executeAfterWait(() => {
|
|
2200
|
+
expectUrlToHaveParamsWithValues(getIFrameSrc(), {
|
|
2201
|
+
isPinboardV2Enabled: 'true',
|
|
2202
|
+
});
|
|
2203
|
+
});
|
|
2204
|
+
});
|
|
2205
|
+
|
|
2206
|
+
test('should strip leading slash from path in getIFrameSrc', async () => {
|
|
2207
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
2208
|
+
...defaultViewConfig,
|
|
2209
|
+
path: '/pinboards',
|
|
2210
|
+
} as AppViewConfig);
|
|
2211
|
+
appEmbed.render();
|
|
2212
|
+
await executeAfterWait(() => {
|
|
2213
|
+
const src = getIFrameSrc();
|
|
2214
|
+
expect(src).toContain('#/pinboards');
|
|
2215
|
+
expect(src).not.toContain('#//pinboards');
|
|
2216
|
+
});
|
|
2217
|
+
});
|
|
2218
|
+
|
|
2219
|
+
test('registerLazyLoadEvents should return early when iFrame is not set', () => {
|
|
2220
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
2221
|
+
...defaultViewConfig,
|
|
2222
|
+
fullHeight: true,
|
|
2223
|
+
lazyLoadingForFullHeight: true,
|
|
2224
|
+
} as AppViewConfig);
|
|
2225
|
+
// iFrame is not set (render not called), should not throw
|
|
2226
|
+
expect(() => {
|
|
2227
|
+
(appEmbed as any).registerLazyLoadEvents();
|
|
2228
|
+
}).not.toThrow();
|
|
2229
|
+
});
|
|
2230
|
+
});
|
|
2231
|
+
|
|
2123
2232
|
describe('AppEmbed visualOverrides tests', () => {
|
|
2124
2233
|
test('should include visualOverridesParams in APP_INIT when visualOverrides config is provided', async () => {
|
|
2125
2234
|
const visualOverrides = {
|
package/src/embed/app.ts
CHANGED
|
@@ -1030,6 +1030,7 @@ export class AppEmbed extends V1Embed {
|
|
|
1030
1030
|
toolResponseCardBrandingLabel,
|
|
1031
1031
|
spotterFileUploadEnabled,
|
|
1032
1032
|
spotterFileUploadFileTypes,
|
|
1033
|
+
enableStarterPrompts,
|
|
1033
1034
|
} = spotterChatConfig;
|
|
1034
1035
|
|
|
1035
1036
|
setParamIfDefined(params, Param.HideToolResponseCardBranding, hideToolResponseCardBranding, true);
|
|
@@ -1037,6 +1038,9 @@ export class AppEmbed extends V1Embed {
|
|
|
1037
1038
|
if (spotterFileUploadEnabled !== undefined) {
|
|
1038
1039
|
params[Param.SpotterFileUploadEnabled] = spotterFileUploadEnabled;
|
|
1039
1040
|
}
|
|
1041
|
+
if (enableStarterPrompts !== undefined) {
|
|
1042
|
+
params[Param.IsStarterPromptsEnabled] = enableStarterPrompts;
|
|
1043
|
+
}
|
|
1040
1044
|
if (spotterFileUploadFileTypes !== undefined) {
|
|
1041
1045
|
params[Param.SpotterFileUploadFileTypes] = JSON.stringify(spotterFileUploadFileTypes);
|
|
1042
1046
|
}
|
|
@@ -369,6 +369,23 @@ describe('ConversationEmbed', () => {
|
|
|
369
369
|
);
|
|
370
370
|
});
|
|
371
371
|
|
|
372
|
+
it('should render the conversation embed with enableStarterPrompts', async () => {
|
|
373
|
+
const viewConfig: SpotterEmbedViewConfig = {
|
|
374
|
+
worksheetId: 'worksheetId',
|
|
375
|
+
searchOptions: {
|
|
376
|
+
searchQuery: 'searchQuery',
|
|
377
|
+
},
|
|
378
|
+
spotterChatConfig: { enableStarterPrompts: true },
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
|
|
382
|
+
await conversationEmbed.render();
|
|
383
|
+
expectUrlMatchesWithParams(
|
|
384
|
+
getIFrameSrc(),
|
|
385
|
+
`http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&enableStarterPrompts=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
|
|
386
|
+
);
|
|
387
|
+
});
|
|
388
|
+
|
|
372
389
|
it('should render the conversation embed with spotterFileUploadFileTypes', async () => {
|
|
373
390
|
const viewConfig: SpotterEmbedViewConfig = {
|
|
374
391
|
worksheetId: 'worksheetId',
|
|
@@ -128,6 +128,14 @@ export interface SpotterChatViewConfig {
|
|
|
128
128
|
* @version SDK: 1.49.0 | ThoughtSpot: 26.6.0.cl
|
|
129
129
|
*/
|
|
130
130
|
spotterFileUploadFileTypes?: SpotterFileUploadFileTypes;
|
|
131
|
+
/**
|
|
132
|
+
* Enables starter prompts in the Spotter chat interface.
|
|
133
|
+
*
|
|
134
|
+
* Supported embed types: SpotterEmbed, LiveboardEmbed, AppEmbed
|
|
135
|
+
* @version SDK: 1.51.0 | ThoughtSpot: 26.8.0.cl
|
|
136
|
+
* @default false
|
|
137
|
+
*/
|
|
138
|
+
enableStarterPrompts?: boolean;
|
|
131
139
|
}
|
|
132
140
|
|
|
133
141
|
/**
|
|
@@ -467,11 +475,13 @@ export class SpotterEmbed extends TsEmbed {
|
|
|
467
475
|
toolResponseCardBrandingLabel,
|
|
468
476
|
spotterFileUploadEnabled,
|
|
469
477
|
spotterFileUploadFileTypes,
|
|
478
|
+
enableStarterPrompts,
|
|
470
479
|
} = spotterChatConfig;
|
|
471
480
|
|
|
472
481
|
setParamIfDefined(queryParams, Param.HideToolResponseCardBranding, hideToolResponseCardBranding, true);
|
|
473
482
|
setParamIfDefined(queryParams, Param.ToolResponseCardBrandingLabel, toolResponseCardBrandingLabel);
|
|
474
483
|
setParamIfDefined(queryParams, Param.SpotterFileUploadEnabled, spotterFileUploadEnabled, true);
|
|
484
|
+
setParamIfDefined(queryParams, Param.IsStarterPromptsEnabled, enableStarterPrompts, true);
|
|
475
485
|
if (spotterFileUploadFileTypes !== undefined) {
|
|
476
486
|
queryParams[Param.SpotterFileUploadFileTypes] = JSON.stringify(spotterFileUploadFileTypes);
|
|
477
487
|
}
|
package/src/embed/events.spec.ts
CHANGED
|
@@ -374,3 +374,10 @@ describe('Americanized enum alias values', () => {
|
|
|
374
374
|
expect(Action.OrganizeFavorites).toBe(Action.OrganiseFavourites);
|
|
375
375
|
});
|
|
376
376
|
});
|
|
377
|
+
|
|
378
|
+
describe('Action enum values', () => {
|
|
379
|
+
|
|
380
|
+
test('RemoveFromFavorites should resolve to its string value', () => {
|
|
381
|
+
expect(Action.RemoveFromFavorites).toBe('removeFromFavorites');
|
|
382
|
+
});
|
|
383
|
+
});
|
|
@@ -1281,6 +1281,21 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
1281
1281
|
});
|
|
1282
1282
|
});
|
|
1283
1283
|
|
|
1284
|
+
test('should set enableStarterPrompts parameter in url params', async () => {
|
|
1285
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
1286
|
+
...defaultViewConfig,
|
|
1287
|
+
liveboardId,
|
|
1288
|
+
spotterChatConfig: { enableStarterPrompts: true },
|
|
1289
|
+
} as LiveboardViewConfig);
|
|
1290
|
+
await liveboardEmbed.render();
|
|
1291
|
+
await executeAfterWait(() => {
|
|
1292
|
+
expectUrlMatchesWithParams(
|
|
1293
|
+
getIFrameSrc(),
|
|
1294
|
+
`http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}&enableStarterPrompts=true#/embed/viz/${liveboardId}`,
|
|
1295
|
+
);
|
|
1296
|
+
});
|
|
1297
|
+
});
|
|
1298
|
+
|
|
1284
1299
|
test('should set spotterFileUploadFileTypes parameter in url params', async () => {
|
|
1285
1300
|
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
1286
1301
|
...defaultViewConfig,
|
package/src/embed/liveboard.ts
CHANGED
|
@@ -791,6 +791,7 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
791
791
|
toolResponseCardBrandingLabel,
|
|
792
792
|
spotterFileUploadEnabled,
|
|
793
793
|
spotterFileUploadFileTypes,
|
|
794
|
+
enableStarterPrompts,
|
|
794
795
|
} = spotterChatConfig;
|
|
795
796
|
|
|
796
797
|
setParamIfDefined(params, Param.HideToolResponseCardBranding, hideToolResponseCardBranding, true);
|
|
@@ -798,6 +799,9 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
798
799
|
if (spotterFileUploadEnabled !== undefined) {
|
|
799
800
|
params[Param.SpotterFileUploadEnabled] = spotterFileUploadEnabled;
|
|
800
801
|
}
|
|
802
|
+
if (enableStarterPrompts !== undefined) {
|
|
803
|
+
params[Param.IsStarterPromptsEnabled] = enableStarterPrompts;
|
|
804
|
+
}
|
|
801
805
|
if (spotterFileUploadFileTypes !== undefined) {
|
|
802
806
|
params[Param.SpotterFileUploadFileTypes] = JSON.stringify(spotterFileUploadFileTypes);
|
|
803
807
|
}
|
|
@@ -2479,6 +2479,10 @@ describe('Unit test case for ts embed', () => {
|
|
|
2479
2479
|
// The ResizeObserver now tracks the placeholder inside this.el,
|
|
2480
2480
|
// not this.el itself, so pass it as the target.
|
|
2481
2481
|
const preRenderPlaceholder = tsEmbedDiv.firstElementChild as HTMLElement;
|
|
2482
|
+
preRenderPlaceholder.getBoundingClientRect = jest.fn().mockReturnValue({
|
|
2483
|
+
x: 0, y: 0, width: 987, height: 297,
|
|
2484
|
+
top: 0, left: 0, bottom: 297, right: 987,
|
|
2485
|
+
});
|
|
2482
2486
|
resizeObserverCb([
|
|
2483
2487
|
{
|
|
2484
2488
|
target: preRenderPlaceholder,
|
|
@@ -2660,6 +2664,296 @@ describe('Unit test case for ts embed', () => {
|
|
|
2660
2664
|
);
|
|
2661
2665
|
(logger.error as any).mockClear();
|
|
2662
2666
|
});
|
|
2667
|
+
|
|
2668
|
+
describe('preRenderContainer', () => {
|
|
2669
|
+
it('should append preRenderWrapper to document.body when preRenderContainer is not set', async () => {
|
|
2670
|
+
createRootEleForEmbed();
|
|
2671
|
+
|
|
2672
|
+
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2673
|
+
preRenderId: 'container-default',
|
|
2674
|
+
liveboardId: 'myLiveboardId',
|
|
2675
|
+
});
|
|
2676
|
+
await libEmbed.preRender();
|
|
2677
|
+
|
|
2678
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2679
|
+
const preRenderWrapper = document.getElementById(preRenderIds.wrapper);
|
|
2680
|
+
expect(document.body.contains(preRenderWrapper)).toBe(true);
|
|
2681
|
+
});
|
|
2682
|
+
|
|
2683
|
+
it('should append preRenderWrapper to the element matching a CSS selector string', async () => {
|
|
2684
|
+
createRootEleForEmbed();
|
|
2685
|
+
const customContainer = document.createElement('div');
|
|
2686
|
+
customContainer.id = 'custom-pre-render-container';
|
|
2687
|
+
document.body.appendChild(customContainer);
|
|
2688
|
+
|
|
2689
|
+
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2690
|
+
preRenderId: 'container-selector',
|
|
2691
|
+
liveboardId: 'myLiveboardId',
|
|
2692
|
+
preRenderContainer: '#custom-pre-render-container',
|
|
2693
|
+
});
|
|
2694
|
+
await libEmbed.preRender();
|
|
2695
|
+
|
|
2696
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2697
|
+
const preRenderWrapper = document.getElementById(preRenderIds.wrapper);
|
|
2698
|
+
expect(customContainer.contains(preRenderWrapper)).toBe(true);
|
|
2699
|
+
|
|
2700
|
+
customContainer.remove();
|
|
2701
|
+
});
|
|
2702
|
+
|
|
2703
|
+
it('should fall back to document.body when the CSS selector string matches nothing', async () => {
|
|
2704
|
+
createRootEleForEmbed();
|
|
2705
|
+
|
|
2706
|
+
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2707
|
+
preRenderId: 'container-selector-miss',
|
|
2708
|
+
liveboardId: 'myLiveboardId',
|
|
2709
|
+
preRenderContainer: '#does-not-exist',
|
|
2710
|
+
});
|
|
2711
|
+
await libEmbed.preRender();
|
|
2712
|
+
|
|
2713
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2714
|
+
const preRenderWrapper = document.getElementById(preRenderIds.wrapper);
|
|
2715
|
+
expect(document.body.contains(preRenderWrapper)).toBe(true);
|
|
2716
|
+
});
|
|
2717
|
+
|
|
2718
|
+
it('should fall back to document.body and log an error when the CSS selector is invalid', async () => {
|
|
2719
|
+
createRootEleForEmbed();
|
|
2720
|
+
jest.spyOn(logger, 'error').mockImplementation(jest.fn());
|
|
2721
|
+
|
|
2722
|
+
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2723
|
+
preRenderId: 'container-selector-invalid',
|
|
2724
|
+
liveboardId: 'myLiveboardId',
|
|
2725
|
+
preRenderContainer: '###invalid###',
|
|
2726
|
+
});
|
|
2727
|
+
await libEmbed.preRender();
|
|
2728
|
+
|
|
2729
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2730
|
+
const preRenderWrapper = document.getElementById(preRenderIds.wrapper);
|
|
2731
|
+
expect(document.body.contains(preRenderWrapper)).toBe(true);
|
|
2732
|
+
expect(logger.error).toHaveBeenCalledWith(
|
|
2733
|
+
expect.stringContaining('Invalid CSS selector for preRenderContainer'),
|
|
2734
|
+
expect.any(Error),
|
|
2735
|
+
);
|
|
2736
|
+
(logger.error as any).mockClear();
|
|
2737
|
+
});
|
|
2738
|
+
|
|
2739
|
+
it('should append preRenderWrapper to an Element passed directly as preRenderContainer', async () => {
|
|
2740
|
+
createRootEleForEmbed();
|
|
2741
|
+
const customContainer = document.createElement('div');
|
|
2742
|
+
customContainer.id = 'custom-pre-render-element';
|
|
2743
|
+
document.body.appendChild(customContainer);
|
|
2744
|
+
|
|
2745
|
+
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2746
|
+
preRenderId: 'container-element',
|
|
2747
|
+
liveboardId: 'myLiveboardId',
|
|
2748
|
+
preRenderContainer: customContainer,
|
|
2749
|
+
});
|
|
2750
|
+
await libEmbed.preRender();
|
|
2751
|
+
|
|
2752
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2753
|
+
const preRenderWrapper = document.getElementById(preRenderIds.wrapper);
|
|
2754
|
+
expect(customContainer.contains(preRenderWrapper)).toBe(true);
|
|
2755
|
+
|
|
2756
|
+
customContainer.remove();
|
|
2757
|
+
});
|
|
2758
|
+
|
|
2759
|
+
it('should set the container position to relative when it is static', async () => {
|
|
2760
|
+
createRootEleForEmbed();
|
|
2761
|
+
const customContainer = document.createElement('div');
|
|
2762
|
+
customContainer.id = 'custom-pre-render-static';
|
|
2763
|
+
customContainer.style.position = 'static';
|
|
2764
|
+
document.body.appendChild(customContainer);
|
|
2765
|
+
|
|
2766
|
+
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2767
|
+
preRenderId: 'container-position-static',
|
|
2768
|
+
liveboardId: 'myLiveboardId',
|
|
2769
|
+
preRenderContainer: customContainer,
|
|
2770
|
+
});
|
|
2771
|
+
await libEmbed.preRender();
|
|
2772
|
+
|
|
2773
|
+
expect(customContainer.style.position).toBe('relative');
|
|
2774
|
+
|
|
2775
|
+
customContainer.remove();
|
|
2776
|
+
});
|
|
2777
|
+
|
|
2778
|
+
it('should restore the original container position on destroy', async () => {
|
|
2779
|
+
createRootEleForEmbed();
|
|
2780
|
+
const customContainer = document.createElement('div');
|
|
2781
|
+
customContainer.id = 'custom-pre-render-restore';
|
|
2782
|
+
customContainer.style.position = 'static';
|
|
2783
|
+
document.body.appendChild(customContainer);
|
|
2784
|
+
|
|
2785
|
+
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2786
|
+
preRenderId: 'container-position-restore',
|
|
2787
|
+
liveboardId: 'myLiveboardId',
|
|
2788
|
+
preRenderContainer: customContainer,
|
|
2789
|
+
});
|
|
2790
|
+
await libEmbed.preRender();
|
|
2791
|
+
expect(customContainer.style.position).toBe('relative');
|
|
2792
|
+
|
|
2793
|
+
libEmbed.destroy();
|
|
2794
|
+
|
|
2795
|
+
// Reverts to the exact value the container had before.
|
|
2796
|
+
expect(customContainer.style.position).toBe('static');
|
|
2797
|
+
// The container reference is dropped so a destroyed embed does
|
|
2798
|
+
// not pin the (possibly detached) element in memory.
|
|
2799
|
+
expect((libEmbed as any).preRenderContainerEl).toBeNull();
|
|
2800
|
+
|
|
2801
|
+
customContainer.remove();
|
|
2802
|
+
});
|
|
2803
|
+
|
|
2804
|
+
it('should not touch the container position when it is already positioned', async () => {
|
|
2805
|
+
createRootEleForEmbed();
|
|
2806
|
+
const customContainer = document.createElement('div');
|
|
2807
|
+
customContainer.id = 'custom-pre-render-positioned';
|
|
2808
|
+
customContainer.style.position = 'absolute';
|
|
2809
|
+
document.body.appendChild(customContainer);
|
|
2810
|
+
|
|
2811
|
+
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2812
|
+
preRenderId: 'container-position-positioned',
|
|
2813
|
+
liveboardId: 'myLiveboardId',
|
|
2814
|
+
preRenderContainer: customContainer,
|
|
2815
|
+
});
|
|
2816
|
+
await libEmbed.preRender();
|
|
2817
|
+
expect(customContainer.style.position).toBe('absolute');
|
|
2818
|
+
|
|
2819
|
+
libEmbed.destroy();
|
|
2820
|
+
expect(customContainer.style.position).toBe('absolute');
|
|
2821
|
+
|
|
2822
|
+
customContainer.remove();
|
|
2823
|
+
});
|
|
2824
|
+
|
|
2825
|
+
it('should keep the container positioned on destroy while another preRender wrapper remains', async () => {
|
|
2826
|
+
createRootEleForEmbed();
|
|
2827
|
+
const customContainer = document.createElement('div');
|
|
2828
|
+
customContainer.id = 'custom-pre-render-shared';
|
|
2829
|
+
customContainer.style.position = 'static';
|
|
2830
|
+
document.body.appendChild(customContainer);
|
|
2831
|
+
|
|
2832
|
+
const firstEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2833
|
+
preRenderId: 'container-shared-first',
|
|
2834
|
+
liveboardId: 'myLiveboardId',
|
|
2835
|
+
preRenderContainer: customContainer,
|
|
2836
|
+
});
|
|
2837
|
+
await firstEmbed.preRender();
|
|
2838
|
+
|
|
2839
|
+
const secondEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2840
|
+
preRenderId: 'container-shared-second',
|
|
2841
|
+
liveboardId: 'myLiveboardId',
|
|
2842
|
+
preRenderContainer: customContainer,
|
|
2843
|
+
});
|
|
2844
|
+
await secondEmbed.preRender();
|
|
2845
|
+
|
|
2846
|
+
expect(customContainer.style.position).toBe('relative');
|
|
2847
|
+
|
|
2848
|
+
// Destroying the first embed must not strip the positioning
|
|
2849
|
+
// context the second embed still relies on.
|
|
2850
|
+
firstEmbed.destroy();
|
|
2851
|
+
expect(customContainer.style.position).toBe('relative');
|
|
2852
|
+
|
|
2853
|
+
// Once the last embed is destroyed, the override is reverted.
|
|
2854
|
+
secondEmbed.destroy();
|
|
2855
|
+
expect(customContainer.style.position).toBe('static');
|
|
2856
|
+
|
|
2857
|
+
customContainer.remove();
|
|
2858
|
+
});
|
|
2859
|
+
|
|
2860
|
+
it('should resolve a selector container inside the host shadow root', async () => {
|
|
2861
|
+
const host = document.createElement('div');
|
|
2862
|
+
document.body.appendChild(host);
|
|
2863
|
+
const shadow = host.attachShadow({ mode: 'open' });
|
|
2864
|
+
const hostEl = document.createElement('div');
|
|
2865
|
+
const shadowContainer = document.createElement('div');
|
|
2866
|
+
shadowContainer.id = 'shadow-pre-render-container';
|
|
2867
|
+
shadow.appendChild(hostEl);
|
|
2868
|
+
shadow.appendChild(shadowContainer);
|
|
2869
|
+
|
|
2870
|
+
const libEmbed = new LiveboardEmbed(hostEl, {
|
|
2871
|
+
preRenderId: 'container-shadow',
|
|
2872
|
+
liveboardId: 'myLiveboardId',
|
|
2873
|
+
preRenderContainer: '#shadow-pre-render-container',
|
|
2874
|
+
});
|
|
2875
|
+
await libEmbed.preRender();
|
|
2876
|
+
|
|
2877
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2878
|
+
const preRenderWrapper = shadow.querySelector(`#${preRenderIds.wrapper}`);
|
|
2879
|
+
// The wrapper lands in the shadow container, not the body.
|
|
2880
|
+
expect(shadowContainer.contains(preRenderWrapper)).toBe(true);
|
|
2881
|
+
expect(document.getElementById(preRenderIds.wrapper)).toBeNull();
|
|
2882
|
+
|
|
2883
|
+
host.remove();
|
|
2884
|
+
});
|
|
2885
|
+
|
|
2886
|
+
it('should re-attach the wrapper when a selector container is remounted', async () => {
|
|
2887
|
+
createRootEleForEmbed();
|
|
2888
|
+
const oldContainer = document.createElement('div');
|
|
2889
|
+
oldContainer.id = 'remount-container';
|
|
2890
|
+
document.body.appendChild(oldContainer);
|
|
2891
|
+
|
|
2892
|
+
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2893
|
+
preRenderId: 'container-remount',
|
|
2894
|
+
liveboardId: 'myLiveboardId',
|
|
2895
|
+
preRenderContainer: '#remount-container',
|
|
2896
|
+
doNotTrackPreRenderSize: true,
|
|
2897
|
+
});
|
|
2898
|
+
libEmbed.preRender();
|
|
2899
|
+
await waitFor(() => !!getIFrameEl());
|
|
2900
|
+
await libEmbed.showPreRender();
|
|
2901
|
+
|
|
2902
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2903
|
+
const wrapper = document.getElementById(preRenderIds.wrapper);
|
|
2904
|
+
expect(oldContainer.contains(wrapper)).toBe(true);
|
|
2905
|
+
|
|
2906
|
+
// Simulate React remounting the container: the old node (with
|
|
2907
|
+
// our wrapper) is detached and a fresh node takes its place.
|
|
2908
|
+
const removeSpy = jest.spyOn(oldContainer, 'removeEventListener');
|
|
2909
|
+
oldContainer.remove();
|
|
2910
|
+
const newContainer = document.createElement('div');
|
|
2911
|
+
newContainer.id = 'remount-container';
|
|
2912
|
+
document.body.appendChild(newContainer);
|
|
2913
|
+
const addSpy = jest.spyOn(newContainer, 'addEventListener');
|
|
2914
|
+
|
|
2915
|
+
// A reposition (scroll/resize/re-show) heals the stale ref.
|
|
2916
|
+
libEmbed.syncPreRenderStyle();
|
|
2917
|
+
|
|
2918
|
+
expect(newContainer.contains(wrapper)).toBe(true);
|
|
2919
|
+
expect(oldContainer.contains(wrapper)).toBe(false);
|
|
2920
|
+
// The scroll listener is migrated to the live container.
|
|
2921
|
+
expect(removeSpy).toHaveBeenCalledWith('scroll', expect.any(Function));
|
|
2922
|
+
expect(addSpy).toHaveBeenCalledWith('scroll', expect.any(Function));
|
|
2923
|
+
|
|
2924
|
+
libEmbed.destroy();
|
|
2925
|
+
newContainer.remove();
|
|
2926
|
+
});
|
|
2927
|
+
|
|
2928
|
+
it('should leave an element-passed container untouched when it is detached', async () => {
|
|
2929
|
+
createRootEleForEmbed();
|
|
2930
|
+
const container = document.createElement('div');
|
|
2931
|
+
document.body.appendChild(container);
|
|
2932
|
+
|
|
2933
|
+
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2934
|
+
preRenderId: 'container-element-remount',
|
|
2935
|
+
liveboardId: 'myLiveboardId',
|
|
2936
|
+
preRenderContainer: container,
|
|
2937
|
+
doNotTrackPreRenderSize: true,
|
|
2938
|
+
});
|
|
2939
|
+
libEmbed.preRender();
|
|
2940
|
+
await waitFor(() => !!getIFrameEl());
|
|
2941
|
+
await libEmbed.showPreRender();
|
|
2942
|
+
|
|
2943
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2944
|
+
const wrapper = document.getElementById(preRenderIds.wrapper);
|
|
2945
|
+
expect(container.contains(wrapper)).toBe(true);
|
|
2946
|
+
|
|
2947
|
+
// Detach the element container; it cannot be re-resolved, so
|
|
2948
|
+
// the wrapper stays with it (no crash, no body fallback).
|
|
2949
|
+
container.remove();
|
|
2950
|
+
libEmbed.syncPreRenderStyle();
|
|
2951
|
+
|
|
2952
|
+
expect(container.contains(wrapper)).toBe(true);
|
|
2953
|
+
|
|
2954
|
+
libEmbed.destroy();
|
|
2955
|
+
});
|
|
2956
|
+
});
|
|
2663
2957
|
});
|
|
2664
2958
|
|
|
2665
2959
|
describe('IdleSessionTimeout embedEvent for TrustedAuthTokenCookieless authType with autoLogin true', () => {
|