@thoughtspot/visual-embed-sdk 1.50.0 → 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.
- package/cjs/package.json +1 -1
- package/cjs/src/config.d.ts +1 -0
- package/cjs/src/config.d.ts.map +1 -1
- package/cjs/src/config.js +2 -1
- package/cjs/src/config.js.map +1 -1
- package/cjs/src/css-variables.d.ts +122 -0
- package/cjs/src/css-variables.d.ts.map +1 -1
- package/cjs/src/embed/app.d.ts +176 -24
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +86 -38
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +672 -150
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/base.d.ts +1 -1
- package/cjs/src/embed/base.js +1 -1
- package/cjs/src/embed/conversation.d.ts +401 -2
- package/cjs/src/embed/conversation.d.ts.map +1 -1
- package/cjs/src/embed/conversation.js +32 -16
- package/cjs/src/embed/conversation.js.map +1 -1
- package/cjs/src/embed/conversation.spec.js +346 -17
- package/cjs/src/embed/conversation.spec.js.map +1 -1
- package/cjs/src/embed/events.spec.js +638 -0
- package/cjs/src/embed/events.spec.js.map +1 -1
- package/cjs/src/embed/host-events.spec.js +187 -0
- package/cjs/src/embed/host-events.spec.js.map +1 -1
- package/cjs/src/embed/hostEventClient/contracts.d.ts +51 -14
- package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/cjs/src/embed/hostEventClient/contracts.js +11 -1
- package/cjs/src/embed/hostEventClient/contracts.js.map +1 -1
- package/cjs/src/embed/hostEventClient/host-event-client.d.ts +2 -1
- package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
- package/cjs/src/embed/hostEventClient/host-event-client.js +9 -0
- package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -1
- package/cjs/src/embed/hostEventClient/host-event-client.spec.js +236 -0
- package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
- package/cjs/src/embed/hostEventClient/utils.d.ts +2 -0
- package/cjs/src/embed/hostEventClient/utils.d.ts.map +1 -1
- package/cjs/src/embed/hostEventClient/utils.js +32 -2
- package/cjs/src/embed/hostEventClient/utils.js.map +1 -1
- package/cjs/src/embed/hostEventClient/utils.spec.js +178 -0
- package/cjs/src/embed/hostEventClient/utils.spec.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +81 -13
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +50 -9
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +432 -4
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/spotter-utils.d.ts +15 -1
- package/cjs/src/embed/spotter-utils.d.ts.map +1 -1
- package/cjs/src/embed/spotter-utils.js +28 -1
- package/cjs/src/embed/spotter-utils.js.map +1 -1
- package/cjs/src/embed/spotter-utils.spec.js +129 -0
- package/cjs/src/embed/spotter-utils.spec.js.map +1 -1
- package/cjs/src/embed/spotter-viz-utils.d.ts +37 -4
- package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -1
- package/cjs/src/embed/spotter-viz-utils.js.map +1 -1
- package/cjs/src/embed/spotter-viz-utils.spec.js +17 -0
- package/cjs/src/embed/spotter-viz-utils.spec.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +16 -8
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +96 -37
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +683 -3
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/errors.d.ts +1 -0
- package/cjs/src/errors.d.ts.map +1 -1
- package/cjs/src/errors.js +1 -0
- package/cjs/src/errors.js.map +1 -1
- package/cjs/src/index.d.ts +3 -3
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +4 -2
- package/cjs/src/index.js.map +1 -1
- package/cjs/src/mixpanel-service.d.ts +4 -0
- package/cjs/src/mixpanel-service.d.ts.map +1 -1
- package/cjs/src/mixpanel-service.js +4 -0
- package/cjs/src/mixpanel-service.js.map +1 -1
- package/cjs/src/react/all-types-export.d.ts +1 -1
- package/cjs/src/react/all-types-export.d.ts.map +1 -1
- package/cjs/src/react/all-types-export.js +2 -1
- package/cjs/src/react/all-types-export.js.map +1 -1
- package/cjs/src/react/all-types-export.parity.spec.d.ts +2 -0
- package/cjs/src/react/all-types-export.parity.spec.d.ts.map +1 -0
- package/cjs/src/react/all-types-export.parity.spec.js +194 -0
- package/cjs/src/react/all-types-export.parity.spec.js.map +1 -0
- package/cjs/src/react/index.d.ts +66 -32
- package/cjs/src/react/index.d.ts.map +1 -1
- package/cjs/src/react/index.js +5 -3
- package/cjs/src/react/index.js.map +1 -1
- package/cjs/src/react/index.spec.js +101 -0
- package/cjs/src/react/index.spec.js.map +1 -1
- package/cjs/src/react/util.spec.js +251 -0
- package/cjs/src/react/util.spec.js.map +1 -1
- package/cjs/src/types.d.ts +902 -28
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +701 -14
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/processData.spec.js +93 -0
- package/cjs/src/utils/processData.spec.js.map +1 -1
- package/cjs/src/utils/processTrigger.spec.js +61 -0
- package/cjs/src/utils/processTrigger.spec.js.map +1 -1
- package/cjs/src/utils.spec.js +4 -0
- package/cjs/src/utils.spec.js.map +1 -1
- package/dist/{index-B5xoN6Cp.js → index-Bivg-mDx.js} +1 -1
- package/dist/src/config.d.ts +1 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/css-variables.d.ts +122 -0
- package/dist/src/css-variables.d.ts.map +1 -1
- package/dist/src/embed/app.d.ts +176 -24
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/base.d.ts +1 -1
- package/dist/src/embed/conversation.d.ts +401 -2
- package/dist/src/embed/conversation.d.ts.map +1 -1
- package/dist/src/embed/hostEventClient/contracts.d.ts +51 -14
- package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/dist/src/embed/hostEventClient/host-event-client.d.ts +2 -1
- package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
- package/dist/src/embed/hostEventClient/utils.d.ts +2 -0
- package/dist/src/embed/hostEventClient/utils.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +81 -13
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/spotter-utils.d.ts +15 -1
- package/dist/src/embed/spotter-utils.d.ts.map +1 -1
- package/dist/src/embed/spotter-viz-utils.d.ts +37 -4
- package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +16 -8
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/errors.d.ts +1 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/mixpanel-service.d.ts +4 -0
- package/dist/src/mixpanel-service.d.ts.map +1 -1
- package/dist/src/react/all-types-export.d.ts +1 -1
- package/dist/src/react/all-types-export.d.ts.map +1 -1
- package/dist/src/react/all-types-export.parity.spec.d.ts +2 -0
- package/dist/src/react/all-types-export.parity.spec.d.ts.map +1 -0
- package/dist/src/react/index.d.ts +66 -32
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/types.d.ts +902 -28
- package/dist/src/types.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +1269 -206
- package/dist/tsembed-react.js +1268 -205
- package/dist/tsembed.es.js +1364 -304
- package/dist/tsembed.js +1362 -302
- package/dist/visual-embed-sdk-react-full.d.ts +1867 -157
- package/dist/visual-embed-sdk-react.d.ts +1872 -161
- package/dist/visual-embed-sdk.d.ts +1815 -127
- package/lib/package.json +1 -1
- package/lib/src/config.d.ts +1 -0
- package/lib/src/config.d.ts.map +1 -1
- package/lib/src/config.js +1 -0
- package/lib/src/config.js.map +1 -1
- package/lib/src/css-variables.d.ts +122 -0
- package/lib/src/css-variables.d.ts.map +1 -1
- package/lib/src/embed/app.d.ts +176 -24
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +87 -39
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +673 -151
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/base.d.ts +1 -1
- package/lib/src/embed/base.js +1 -1
- package/lib/src/embed/conversation.d.ts +401 -2
- package/lib/src/embed/conversation.d.ts.map +1 -1
- package/lib/src/embed/conversation.js +33 -17
- package/lib/src/embed/conversation.js.map +1 -1
- package/lib/src/embed/conversation.spec.js +347 -18
- package/lib/src/embed/conversation.spec.js.map +1 -1
- package/lib/src/embed/events.spec.js +638 -0
- package/lib/src/embed/events.spec.js.map +1 -1
- package/lib/src/embed/host-events.spec.js +188 -1
- package/lib/src/embed/host-events.spec.js.map +1 -1
- package/lib/src/embed/hostEventClient/contracts.d.ts +51 -14
- package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/lib/src/embed/hostEventClient/contracts.js +10 -0
- package/lib/src/embed/hostEventClient/contracts.js.map +1 -1
- package/lib/src/embed/hostEventClient/host-event-client.d.ts +2 -1
- package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
- package/lib/src/embed/hostEventClient/host-event-client.js +10 -1
- package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -1
- package/lib/src/embed/hostEventClient/host-event-client.spec.js +236 -0
- package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
- package/lib/src/embed/hostEventClient/utils.d.ts +2 -0
- package/lib/src/embed/hostEventClient/utils.d.ts.map +1 -1
- package/lib/src/embed/hostEventClient/utils.js +28 -1
- package/lib/src/embed/hostEventClient/utils.js.map +1 -1
- package/lib/src/embed/hostEventClient/utils.spec.js +179 -1
- package/lib/src/embed/hostEventClient/utils.spec.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +81 -13
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +50 -9
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +432 -4
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/spotter-utils.d.ts +15 -1
- package/lib/src/embed/spotter-utils.d.ts.map +1 -1
- package/lib/src/embed/spotter-utils.js +25 -0
- package/lib/src/embed/spotter-utils.js.map +1 -1
- package/lib/src/embed/spotter-utils.spec.js +130 -1
- package/lib/src/embed/spotter-utils.spec.js.map +1 -1
- package/lib/src/embed/spotter-viz-utils.d.ts +37 -4
- package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
- package/lib/src/embed/spotter-viz-utils.js.map +1 -1
- package/lib/src/embed/spotter-viz-utils.spec.js +17 -0
- package/lib/src/embed/spotter-viz-utils.spec.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +16 -8
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +96 -37
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +683 -3
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/errors.d.ts +1 -0
- package/lib/src/errors.d.ts.map +1 -1
- package/lib/src/errors.js +1 -0
- package/lib/src/errors.js.map +1 -1
- package/lib/src/index.d.ts +3 -3
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +3 -3
- package/lib/src/index.js.map +1 -1
- package/lib/src/mixpanel-service.d.ts +4 -0
- package/lib/src/mixpanel-service.d.ts.map +1 -1
- package/lib/src/mixpanel-service.js +4 -0
- package/lib/src/mixpanel-service.js.map +1 -1
- package/lib/src/react/all-types-export.d.ts +1 -1
- package/lib/src/react/all-types-export.d.ts.map +1 -1
- package/lib/src/react/all-types-export.js +1 -1
- package/lib/src/react/all-types-export.js.map +1 -1
- package/lib/src/react/all-types-export.parity.spec.d.ts +2 -0
- package/lib/src/react/all-types-export.parity.spec.d.ts.map +1 -0
- package/lib/src/react/all-types-export.parity.spec.js +191 -0
- package/lib/src/react/all-types-export.parity.spec.js.map +1 -0
- package/lib/src/react/index.d.ts +66 -32
- package/lib/src/react/index.d.ts.map +1 -1
- package/lib/src/react/index.js +5 -3
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/react/index.spec.js +102 -1
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/react/util.spec.js +251 -0
- package/lib/src/react/util.spec.js.map +1 -1
- package/lib/src/types.d.ts +902 -28
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +701 -14
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/processData.spec.js +93 -0
- package/lib/src/utils/processData.spec.js.map +1 -1
- package/lib/src/utils/processTrigger.spec.js +61 -0
- package/lib/src/utils/processTrigger.spec.js.map +1 -1
- package/lib/src/utils.spec.js +4 -0
- package/lib/src/utils.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +1815 -127
- package/package.json +1 -1
- package/src/config.ts +1 -0
- package/src/css-variables.ts +150 -0
- package/src/embed/app.spec.ts +877 -196
- package/src/embed/app.ts +276 -75
- package/src/embed/base.ts +1 -1
- package/src/embed/conversation.spec.ts +411 -21
- package/src/embed/conversation.ts +441 -18
- package/src/embed/events.spec.ts +761 -1
- package/src/embed/host-events.spec.ts +242 -0
- package/src/embed/hostEventClient/contracts.ts +57 -14
- package/src/embed/hostEventClient/host-event-client.spec.ts +372 -0
- package/src/embed/hostEventClient/host-event-client.ts +18 -2
- package/src/embed/hostEventClient/utils.spec.ts +204 -0
- package/src/embed/hostEventClient/utils.ts +37 -10
- package/src/embed/liveboard.spec.ts +565 -4
- package/src/embed/liveboard.ts +155 -28
- package/src/embed/spotter-utils.spec.ts +140 -1
- package/src/embed/spotter-utils.ts +36 -1
- package/src/embed/spotter-viz-utils.spec.ts +17 -0
- package/src/embed/spotter-viz-utils.ts +37 -4
- package/src/embed/ts-embed.spec.ts +885 -3
- package/src/embed/ts-embed.ts +111 -39
- package/src/errors.ts +1 -0
- package/src/index.ts +45 -2
- package/src/mixpanel-service.ts +4 -0
- package/src/react/all-types-export.parity.spec.ts +208 -0
- package/src/react/all-types-export.ts +22 -0
- package/src/react/index.spec.tsx +158 -0
- package/src/react/index.tsx +70 -33
- package/src/react/util.spec.tsx +255 -0
- package/src/types.ts +904 -24
- package/src/utils/processData.spec.ts +97 -0
- package/src/utils/processTrigger.spec.ts +91 -0
- package/src/utils.spec.ts +5 -0
|
@@ -1174,6 +1174,32 @@ describe('Unit test case for ts embed', () => {
|
|
|
1174
1174
|
const { mockGetPreauthInfo } = await setup(true, 123);
|
|
1175
1175
|
expect(mockGetPreauthInfo).toHaveBeenCalledTimes(0);
|
|
1176
1176
|
});
|
|
1177
|
+
test('should NOT trigger InfoSuccess when getPreauthInfo resolves with no .info field', async () => {
|
|
1178
|
+
jest.spyOn(window, 'addEventListener').mockImplementationOnce((event, handler) => {
|
|
1179
|
+
handler({
|
|
1180
|
+
data: { type: 'xyz' },
|
|
1181
|
+
ports: [3000],
|
|
1182
|
+
source: null,
|
|
1183
|
+
});
|
|
1184
|
+
});
|
|
1185
|
+
mockProcessTrigger.mockResolvedValueOnce({ session: 'test' });
|
|
1186
|
+
jest.spyOn(authService, 'fetchPreauthInfoService').mockResolvedValueOnce({
|
|
1187
|
+
ok: true,
|
|
1188
|
+
headers: new Headers({ 'content-type': 'application/json' }),
|
|
1189
|
+
json: async () => ({}), // no .info field
|
|
1190
|
+
});
|
|
1191
|
+
const iFrame = document.createElement('div');
|
|
1192
|
+
jest.spyOn(baseInstance, 'getAuthPromise').mockResolvedValueOnce(true);
|
|
1193
|
+
const tsEmbed = new index_1.SearchEmbed((0, test_utils_1.getRootEl)(), {});
|
|
1194
|
+
iFrame.contentWindow = { postMessage: jest.fn() };
|
|
1195
|
+
jest.spyOn(iFrame, 'addEventListener').mockImplementationOnce((event, handler) => { handler({}); });
|
|
1196
|
+
jest.spyOn(document, 'createElement').mockReturnValueOnce(iFrame);
|
|
1197
|
+
await tsEmbed.render();
|
|
1198
|
+
await (0, test_utils_1.executeAfterWait)(() => {
|
|
1199
|
+
const infoSuccessCall = mockProcessTrigger.mock.calls.find((call) => call[1] === types_1.HostEvent.InfoSuccess);
|
|
1200
|
+
expect(infoSuccessCall).toBeUndefined();
|
|
1201
|
+
});
|
|
1202
|
+
});
|
|
1177
1203
|
});
|
|
1178
1204
|
describe('Preauth Cache for FullAppEmbed with PrimaryNavBar', () => {
|
|
1179
1205
|
beforeAll(() => {
|
|
@@ -1897,6 +1923,43 @@ describe('Unit test case for ts embed', () => {
|
|
|
1897
1923
|
orgId: overrideOrgId,
|
|
1898
1924
|
});
|
|
1899
1925
|
});
|
|
1926
|
+
it('Sets the overrideHistoryState param', async () => {
|
|
1927
|
+
const appEmbed = new index_1.AppEmbed((0, test_utils_1.getRootEl)(), {
|
|
1928
|
+
frameParams: {
|
|
1929
|
+
width: '100%',
|
|
1930
|
+
height: '100%',
|
|
1931
|
+
},
|
|
1932
|
+
overrideHistoryState: true,
|
|
1933
|
+
});
|
|
1934
|
+
await appEmbed.render();
|
|
1935
|
+
(0, test_utils_1.expectUrlToHaveParamsWithValues)((0, test_utils_1.getIFrameSrc)(), {
|
|
1936
|
+
overrideHistoryState: true,
|
|
1937
|
+
});
|
|
1938
|
+
});
|
|
1939
|
+
it('Sets the overrideHistoryState param to false', async () => {
|
|
1940
|
+
const appEmbed = new index_1.AppEmbed((0, test_utils_1.getRootEl)(), {
|
|
1941
|
+
frameParams: {
|
|
1942
|
+
width: '100%',
|
|
1943
|
+
height: '100%',
|
|
1944
|
+
},
|
|
1945
|
+
overrideHistoryState: false,
|
|
1946
|
+
});
|
|
1947
|
+
await appEmbed.render();
|
|
1948
|
+
(0, test_utils_1.expectUrlToHaveParamsWithValues)((0, test_utils_1.getIFrameSrc)(), {
|
|
1949
|
+
overrideHistoryState: false,
|
|
1950
|
+
});
|
|
1951
|
+
});
|
|
1952
|
+
it('Should not add overrideHistoryState param when it is undefined', async () => {
|
|
1953
|
+
const appEmbed = new index_1.AppEmbed((0, test_utils_1.getRootEl)(), {
|
|
1954
|
+
frameParams: {
|
|
1955
|
+
width: '100%',
|
|
1956
|
+
height: '100%',
|
|
1957
|
+
},
|
|
1958
|
+
});
|
|
1959
|
+
await appEmbed.render();
|
|
1960
|
+
const url = (0, test_utils_1.getIFrameSrc)();
|
|
1961
|
+
expect(url).not.toContain('overrideHistoryState');
|
|
1962
|
+
});
|
|
1900
1963
|
it('Should not add contextMenuEnabledOnWhichClick flag to the iframe src when it is not passed', async () => {
|
|
1901
1964
|
const liveboardEmbed = new index_1.LiveboardEmbed((0, test_utils_1.getRootEl)(), {
|
|
1902
1965
|
...defaultViewConfig,
|
|
@@ -2208,6 +2271,37 @@ describe('Unit test case for ts embed', () => {
|
|
|
2208
2271
|
expect(logger_1.logger.error).toHaveBeenCalledWith('PreRender should be called before using syncPreRenderStyle');
|
|
2209
2272
|
logger_1.logger.error.mockClear();
|
|
2210
2273
|
});
|
|
2274
|
+
it('should skip syncing styles when the placeholder is detached', async () => {
|
|
2275
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2276
|
+
jest.spyOn(logger_1.logger, 'debug').mockImplementation(jest.fn());
|
|
2277
|
+
const libEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2278
|
+
liveboardId: 'myLiveboardId',
|
|
2279
|
+
preRenderId: 'placeholder-detached',
|
|
2280
|
+
doNotTrackPreRenderSize: true,
|
|
2281
|
+
});
|
|
2282
|
+
libEmbed.preRender();
|
|
2283
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2284
|
+
await libEmbed.showPreRender();
|
|
2285
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2286
|
+
const wrapper = document.getElementById(preRenderIds.wrapper);
|
|
2287
|
+
const placeholder = document.getElementById(preRenderIds.placeHolder);
|
|
2288
|
+
const rectSpy = jest.spyOn(placeholder, 'getBoundingClientRect');
|
|
2289
|
+
wrapper.style.top = '42px';
|
|
2290
|
+
wrapper.style.height = '111px';
|
|
2291
|
+
logger_1.logger.debug.mockClear();
|
|
2292
|
+
// Simulate the host subtree being unmounted: the placeholder is no
|
|
2293
|
+
// longer connected to the document.
|
|
2294
|
+
placeholder.remove();
|
|
2295
|
+
libEmbed.syncPreRenderStyle();
|
|
2296
|
+
expect(logger_1.logger.debug).toHaveBeenCalledWith('syncPreRenderStyle skipped: placeholder is detached');
|
|
2297
|
+
// The detached node is never measured, so the wrapper keeps its
|
|
2298
|
+
// last known geometry instead of collapsing to a stale rect.
|
|
2299
|
+
expect(rectSpy).not.toHaveBeenCalled();
|
|
2300
|
+
expect(wrapper.style.top).toBe('42px');
|
|
2301
|
+
expect(wrapper.style.height).toBe('111px');
|
|
2302
|
+
libEmbed.destroy();
|
|
2303
|
+
logger_1.logger.debug.mockRestore();
|
|
2304
|
+
});
|
|
2211
2305
|
describe('preRenderContainer', () => {
|
|
2212
2306
|
it('should append preRenderWrapper to document.body when preRenderContainer is not set', async () => {
|
|
2213
2307
|
(0, test_utils_1.createRootEleForEmbed)();
|
|
@@ -2310,9 +2404,10 @@ describe('Unit test case for ts embed', () => {
|
|
|
2310
2404
|
libEmbed.destroy();
|
|
2311
2405
|
// Reverts to the exact value the container had before.
|
|
2312
2406
|
expect(customContainer.style.position).toBe('static');
|
|
2313
|
-
// The container reference is dropped
|
|
2314
|
-
// not pin the (possibly
|
|
2315
|
-
|
|
2407
|
+
// The custom container reference is dropped (back to the default
|
|
2408
|
+
// body) so a destroyed embed does not pin the (possibly
|
|
2409
|
+
// detached) element in memory.
|
|
2410
|
+
expect(libEmbed.preRenderContainerEl).toBe(document.body);
|
|
2316
2411
|
customContainer.remove();
|
|
2317
2412
|
});
|
|
2318
2413
|
it('should not touch the container position when it is already positioned', async () => {
|
|
@@ -2332,6 +2427,30 @@ describe('Unit test case for ts embed', () => {
|
|
|
2332
2427
|
expect(customContainer.style.position).toBe('absolute');
|
|
2333
2428
|
customContainer.remove();
|
|
2334
2429
|
});
|
|
2430
|
+
it('should default preRenderContainerEl to document.body before rendering', () => {
|
|
2431
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2432
|
+
const libEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2433
|
+
liveboardId: 'myLiveboardId',
|
|
2434
|
+
});
|
|
2435
|
+
// document.body is the "no custom container" sentinel, so the
|
|
2436
|
+
// field is never null and needs no null-guarding downstream.
|
|
2437
|
+
expect(libEmbed.preRenderContainerEl).toBe(document.body);
|
|
2438
|
+
});
|
|
2439
|
+
it('should leave document.body untouched on destroy when no custom container is set', async () => {
|
|
2440
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2441
|
+
const originalBodyPosition = document.body.style.position;
|
|
2442
|
+
const libEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2443
|
+
preRenderId: 'container-body-destroy',
|
|
2444
|
+
liveboardId: 'myLiveboardId',
|
|
2445
|
+
});
|
|
2446
|
+
await libEmbed.preRender();
|
|
2447
|
+
expect(libEmbed.preRenderContainerEl).toBe(document.body);
|
|
2448
|
+
libEmbed.destroy();
|
|
2449
|
+
// The body sentinel must never be treated as a custom container:
|
|
2450
|
+
// no position override to apply and none to restore.
|
|
2451
|
+
expect(document.body.style.position).toBe(originalBodyPosition);
|
|
2452
|
+
expect(document.body.dataset.tsEmbedOriginalPosition).toBeUndefined();
|
|
2453
|
+
});
|
|
2335
2454
|
it('should keep the container positioned on destroy while another preRender wrapper remains', async () => {
|
|
2336
2455
|
(0, test_utils_1.createRootEleForEmbed)();
|
|
2337
2456
|
const customContainer = document.createElement('div');
|
|
@@ -2417,6 +2536,38 @@ describe('Unit test case for ts embed', () => {
|
|
|
2417
2536
|
libEmbed.destroy();
|
|
2418
2537
|
newContainer.remove();
|
|
2419
2538
|
});
|
|
2539
|
+
it('should position the newly resolved container after a remount, not the stale one', async () => {
|
|
2540
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2541
|
+
const oldContainer = document.createElement('div');
|
|
2542
|
+
oldContainer.id = 'reposition-remount-container';
|
|
2543
|
+
oldContainer.style.position = 'static';
|
|
2544
|
+
document.body.appendChild(oldContainer);
|
|
2545
|
+
const libEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2546
|
+
preRenderId: 'container-remount-position',
|
|
2547
|
+
liveboardId: 'myLiveboardId',
|
|
2548
|
+
preRenderContainer: '#reposition-remount-container',
|
|
2549
|
+
doNotTrackPreRenderSize: true,
|
|
2550
|
+
});
|
|
2551
|
+
libEmbed.preRender();
|
|
2552
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2553
|
+
await libEmbed.showPreRender();
|
|
2554
|
+
expect(oldContainer.style.position).toBe('relative');
|
|
2555
|
+
oldContainer.remove();
|
|
2556
|
+
const newContainer = document.createElement('div');
|
|
2557
|
+
newContainer.id = 'reposition-remount-container';
|
|
2558
|
+
newContainer.style.position = 'static';
|
|
2559
|
+
document.body.appendChild(newContainer);
|
|
2560
|
+
libEmbed.syncPreRenderStyle();
|
|
2561
|
+
// applyPreRenderContainerPositioning() reads preRenderContainerEl
|
|
2562
|
+
// instead of taking the container as an argument, so reconcile has
|
|
2563
|
+
// to assign the field before calling it — otherwise the override
|
|
2564
|
+
// lands on the detached node and the fresh one stays static.
|
|
2565
|
+
expect(libEmbed.preRenderContainerEl).toBe(newContainer);
|
|
2566
|
+
expect(newContainer.style.position).toBe('relative');
|
|
2567
|
+
expect(newContainer.dataset.tsEmbedOriginalPosition).toBe('static');
|
|
2568
|
+
libEmbed.destroy();
|
|
2569
|
+
newContainer.remove();
|
|
2570
|
+
});
|
|
2420
2571
|
it('should leave an element-passed container untouched when it is detached', async () => {
|
|
2421
2572
|
(0, test_utils_1.createRootEleForEmbed)();
|
|
2422
2573
|
const container = document.createElement('div');
|
|
@@ -2440,6 +2591,436 @@ describe('Unit test case for ts embed', () => {
|
|
|
2440
2591
|
expect(container.contains(wrapper)).toBe(true);
|
|
2441
2592
|
libEmbed.destroy();
|
|
2442
2593
|
});
|
|
2594
|
+
describe('connectPreRendered container init', () => {
|
|
2595
|
+
beforeEach(() => {
|
|
2596
|
+
window.ResizeObserver = jest.fn().mockImplementation(() => ({
|
|
2597
|
+
disconnect: jest.fn(),
|
|
2598
|
+
observe: jest.fn(),
|
|
2599
|
+
unobserve: jest.fn(),
|
|
2600
|
+
}));
|
|
2601
|
+
});
|
|
2602
|
+
it('should resolve preRenderContainerEl when connecting to an existing pre-render', async () => {
|
|
2603
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2604
|
+
const firstEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2605
|
+
preRenderId: 'connect-init-default',
|
|
2606
|
+
liveboardId: 'myLiveboardId',
|
|
2607
|
+
});
|
|
2608
|
+
await firstEmbed.preRender();
|
|
2609
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2610
|
+
const connectingEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2611
|
+
preRenderId: 'connect-init-default',
|
|
2612
|
+
liveboardId: 'myLiveboardId',
|
|
2613
|
+
});
|
|
2614
|
+
await connectingEmbed.showPreRender();
|
|
2615
|
+
expect(connectingEmbed.preRenderContainerEl).not.toBeNull();
|
|
2616
|
+
firstEmbed.destroy();
|
|
2617
|
+
});
|
|
2618
|
+
it('should fall back to document.body when no preRenderContainer is configured on the connecting embed', async () => {
|
|
2619
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2620
|
+
const firstEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2621
|
+
preRenderId: 'connect-init-body',
|
|
2622
|
+
liveboardId: 'myLiveboardId',
|
|
2623
|
+
});
|
|
2624
|
+
await firstEmbed.preRender();
|
|
2625
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2626
|
+
const connectingEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2627
|
+
preRenderId: 'connect-init-body',
|
|
2628
|
+
liveboardId: 'myLiveboardId',
|
|
2629
|
+
});
|
|
2630
|
+
await connectingEmbed.showPreRender();
|
|
2631
|
+
expect(connectingEmbed.preRenderContainerEl).toBe(document.body);
|
|
2632
|
+
firstEmbed.destroy();
|
|
2633
|
+
});
|
|
2634
|
+
it('should resolve a custom preRenderContainer on the connecting embed', async () => {
|
|
2635
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2636
|
+
const customContainer = document.createElement('div');
|
|
2637
|
+
customContainer.id = 'connect-custom-container';
|
|
2638
|
+
document.body.appendChild(customContainer);
|
|
2639
|
+
const firstEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2640
|
+
preRenderId: 'connect-init-custom',
|
|
2641
|
+
liveboardId: 'myLiveboardId',
|
|
2642
|
+
preRenderContainer: customContainer,
|
|
2643
|
+
});
|
|
2644
|
+
await firstEmbed.preRender();
|
|
2645
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2646
|
+
const connectingEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2647
|
+
preRenderId: 'connect-init-custom',
|
|
2648
|
+
liveboardId: 'myLiveboardId',
|
|
2649
|
+
preRenderContainer: customContainer,
|
|
2650
|
+
});
|
|
2651
|
+
await connectingEmbed.showPreRender();
|
|
2652
|
+
expect(connectingEmbed.preRenderContainerEl).toBe(customContainer);
|
|
2653
|
+
firstEmbed.destroy();
|
|
2654
|
+
customContainer.remove();
|
|
2655
|
+
});
|
|
2656
|
+
it('should apply container positioning when the connecting embed resolves a static container', async () => {
|
|
2657
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2658
|
+
const customContainer = document.createElement('div');
|
|
2659
|
+
customContainer.id = 'connect-static-container';
|
|
2660
|
+
customContainer.style.position = 'static';
|
|
2661
|
+
document.body.appendChild(customContainer);
|
|
2662
|
+
const firstEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2663
|
+
preRenderId: 'connect-init-static',
|
|
2664
|
+
liveboardId: 'myLiveboardId',
|
|
2665
|
+
preRenderContainer: customContainer,
|
|
2666
|
+
});
|
|
2667
|
+
await firstEmbed.preRender();
|
|
2668
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2669
|
+
// Reset position to static so the connecting embed also triggers the guard.
|
|
2670
|
+
customContainer.style.position = 'static';
|
|
2671
|
+
delete customContainer.dataset['preRenderContainerOriginalPosition'];
|
|
2672
|
+
const connectingEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2673
|
+
preRenderId: 'connect-init-static',
|
|
2674
|
+
liveboardId: 'myLiveboardId',
|
|
2675
|
+
preRenderContainer: customContainer,
|
|
2676
|
+
});
|
|
2677
|
+
await connectingEmbed.showPreRender();
|
|
2678
|
+
expect(customContainer.style.position).toBe('relative');
|
|
2679
|
+
firstEmbed.destroy();
|
|
2680
|
+
connectingEmbed.destroy();
|
|
2681
|
+
customContainer.remove();
|
|
2682
|
+
});
|
|
2683
|
+
it('should inherit the container from the pre-rendering embed instead of re-resolving it', async () => {
|
|
2684
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2685
|
+
const customContainer = document.createElement('div');
|
|
2686
|
+
customContainer.id = 'connect-inherit-container';
|
|
2687
|
+
document.body.appendChild(customContainer);
|
|
2688
|
+
const firstEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2689
|
+
preRenderId: 'connect-no-re-resolve',
|
|
2690
|
+
liveboardId: 'myLiveboardId',
|
|
2691
|
+
preRenderContainer: customContainer,
|
|
2692
|
+
});
|
|
2693
|
+
await firstEmbed.preRender();
|
|
2694
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2695
|
+
// No preRenderContainer here: the container belongs to the
|
|
2696
|
+
// PreRender component and is adopted as-is.
|
|
2697
|
+
const connectingEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2698
|
+
preRenderId: 'connect-no-re-resolve',
|
|
2699
|
+
liveboardId: 'myLiveboardId',
|
|
2700
|
+
});
|
|
2701
|
+
const resolveSpy = jest.spyOn(connectingEmbed, 'resolvePreRenderContainerTarget');
|
|
2702
|
+
connectingEmbed.connectPreRendered();
|
|
2703
|
+
expect(connectingEmbed.preRenderContainerEl).toBe(customContainer);
|
|
2704
|
+
expect(resolveSpy).not.toHaveBeenCalled();
|
|
2705
|
+
firstEmbed.destroy();
|
|
2706
|
+
customContainer.remove();
|
|
2707
|
+
});
|
|
2708
|
+
it('should warn and ignore a preRenderContainer passed on the connecting embed', async () => {
|
|
2709
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2710
|
+
const ownerContainer = document.createElement('div');
|
|
2711
|
+
ownerContainer.id = 'connect-owner-container';
|
|
2712
|
+
const otherContainer = document.createElement('div');
|
|
2713
|
+
otherContainer.id = 'connect-other-container';
|
|
2714
|
+
document.body.appendChild(ownerContainer);
|
|
2715
|
+
document.body.appendChild(otherContainer);
|
|
2716
|
+
const warnSpy = jest.spyOn(logger_1.logger, 'warn').mockImplementation(() => undefined);
|
|
2717
|
+
const firstEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2718
|
+
preRenderId: 'connect-container-warn',
|
|
2719
|
+
liveboardId: 'myLiveboardId',
|
|
2720
|
+
preRenderContainer: ownerContainer,
|
|
2721
|
+
});
|
|
2722
|
+
await firstEmbed.preRender();
|
|
2723
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2724
|
+
const connectingEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2725
|
+
preRenderId: 'connect-container-warn',
|
|
2726
|
+
liveboardId: 'myLiveboardId',
|
|
2727
|
+
preRenderContainer: otherContainer,
|
|
2728
|
+
});
|
|
2729
|
+
connectingEmbed.connectPreRendered();
|
|
2730
|
+
expect(connectingEmbed.preRenderContainerEl).toBe(ownerContainer);
|
|
2731
|
+
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('preRenderContainer is applied only by'));
|
|
2732
|
+
warnSpy.mockRestore();
|
|
2733
|
+
firstEmbed.destroy();
|
|
2734
|
+
ownerContainer.remove();
|
|
2735
|
+
otherContainer.remove();
|
|
2736
|
+
});
|
|
2737
|
+
it('should not warn when the connecting embed passes the same container element', async () => {
|
|
2738
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2739
|
+
const customContainer = document.createElement('div');
|
|
2740
|
+
customContainer.id = 'connect-same-element-container';
|
|
2741
|
+
document.body.appendChild(customContainer);
|
|
2742
|
+
const warnSpy = jest.spyOn(logger_1.logger, 'warn').mockImplementation(() => undefined);
|
|
2743
|
+
const firstEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2744
|
+
preRenderId: 'connect-same-element',
|
|
2745
|
+
liveboardId: 'myLiveboardId',
|
|
2746
|
+
preRenderContainer: customContainer,
|
|
2747
|
+
});
|
|
2748
|
+
await firstEmbed.preRender();
|
|
2749
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2750
|
+
// Same config on both components — the value is redundant but
|
|
2751
|
+
// not wrong, so nagging about it would be noise.
|
|
2752
|
+
const connectingEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2753
|
+
preRenderId: 'connect-same-element',
|
|
2754
|
+
liveboardId: 'myLiveboardId',
|
|
2755
|
+
preRenderContainer: customContainer,
|
|
2756
|
+
});
|
|
2757
|
+
connectingEmbed.connectPreRendered();
|
|
2758
|
+
expect(connectingEmbed.preRenderContainerEl).toBe(customContainer);
|
|
2759
|
+
expect(warnSpy).not.toHaveBeenCalledWith(expect.stringContaining('preRenderContainer is applied only by'));
|
|
2760
|
+
warnSpy.mockRestore();
|
|
2761
|
+
firstEmbed.destroy();
|
|
2762
|
+
customContainer.remove();
|
|
2763
|
+
});
|
|
2764
|
+
it('should not warn when the connecting embed passes a selector for the same container', async () => {
|
|
2765
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2766
|
+
const customContainer = document.createElement('div');
|
|
2767
|
+
customContainer.id = 'connect-same-selector-container';
|
|
2768
|
+
document.body.appendChild(customContainer);
|
|
2769
|
+
const warnSpy = jest.spyOn(logger_1.logger, 'warn').mockImplementation(() => undefined);
|
|
2770
|
+
const firstEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2771
|
+
preRenderId: 'connect-same-selector',
|
|
2772
|
+
liveboardId: 'myLiveboardId',
|
|
2773
|
+
preRenderContainer: customContainer,
|
|
2774
|
+
});
|
|
2775
|
+
await firstEmbed.preRender();
|
|
2776
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2777
|
+
// A selector that resolves to the owner's element is the same
|
|
2778
|
+
// container, so the comparison must be by resolved node.
|
|
2779
|
+
const connectingEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2780
|
+
preRenderId: 'connect-same-selector',
|
|
2781
|
+
liveboardId: 'myLiveboardId',
|
|
2782
|
+
preRenderContainer: '#connect-same-selector-container',
|
|
2783
|
+
});
|
|
2784
|
+
connectingEmbed.connectPreRendered();
|
|
2785
|
+
expect(connectingEmbed.preRenderContainerEl).toBe(customContainer);
|
|
2786
|
+
expect(warnSpy).not.toHaveBeenCalledWith(expect.stringContaining('preRenderContainer is applied only by'));
|
|
2787
|
+
warnSpy.mockRestore();
|
|
2788
|
+
firstEmbed.destroy();
|
|
2789
|
+
customContainer.remove();
|
|
2790
|
+
});
|
|
2791
|
+
it('should keep its own container when the same instance owns the pre-render', async () => {
|
|
2792
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2793
|
+
const customContainer = document.createElement('div');
|
|
2794
|
+
customContainer.id = 'connect-self-container';
|
|
2795
|
+
document.body.appendChild(customContainer);
|
|
2796
|
+
const warnSpy = jest.spyOn(logger_1.logger, 'warn').mockImplementation(() => undefined);
|
|
2797
|
+
const libEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2798
|
+
preRenderId: 'connect-self',
|
|
2799
|
+
liveboardId: 'myLiveboardId',
|
|
2800
|
+
preRenderContainer: customContainer,
|
|
2801
|
+
});
|
|
2802
|
+
await libEmbed.preRender();
|
|
2803
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2804
|
+
// preRender() then render() on one instance: it owns the
|
|
2805
|
+
// wrapper, so there is nothing to inherit and its own
|
|
2806
|
+
// preRenderContainer is entirely legitimate.
|
|
2807
|
+
libEmbed.connectPreRendered();
|
|
2808
|
+
expect(libEmbed.preRenderContainerEl).toBe(customContainer);
|
|
2809
|
+
expect(warnSpy).not.toHaveBeenCalledWith(expect.stringContaining('preRenderContainer is applied only by'));
|
|
2810
|
+
warnSpy.mockRestore();
|
|
2811
|
+
libEmbed.destroy();
|
|
2812
|
+
customContainer.remove();
|
|
2813
|
+
});
|
|
2814
|
+
it('should stay on document.body when the wrapper has no owning embed', async () => {
|
|
2815
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2816
|
+
const customContainer = document.createElement('div');
|
|
2817
|
+
customContainer.id = 'connect-unstamped-container';
|
|
2818
|
+
document.body.appendChild(customContainer);
|
|
2819
|
+
const warnSpy = jest.spyOn(logger_1.logger, 'warn').mockImplementation(() => undefined);
|
|
2820
|
+
const firstEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2821
|
+
preRenderId: 'connect-unstamped',
|
|
2822
|
+
liveboardId: 'myLiveboardId',
|
|
2823
|
+
preRenderContainer: customContainer,
|
|
2824
|
+
});
|
|
2825
|
+
await firstEmbed.preRender();
|
|
2826
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2827
|
+
// Simulate a wrapper with no live embed behind it: the
|
|
2828
|
+
// __tsEmbed stamp used to locate the owner is gone, so there
|
|
2829
|
+
// is no container to inherit.
|
|
2830
|
+
const wrapper = document.getElementById(firstEmbed.getPreRenderIds().wrapper);
|
|
2831
|
+
delete wrapper.__tsEmbed;
|
|
2832
|
+
const connectingEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2833
|
+
preRenderId: 'connect-unstamped',
|
|
2834
|
+
liveboardId: 'myLiveboardId',
|
|
2835
|
+
});
|
|
2836
|
+
connectingEmbed.connectPreRendered();
|
|
2837
|
+
// Falls back to the sentinel rather than crashing on the
|
|
2838
|
+
// missing owner, and warns about nothing.
|
|
2839
|
+
expect(connectingEmbed.preRenderContainerEl).toBe(document.body);
|
|
2840
|
+
expect(warnSpy).not.toHaveBeenCalledWith(expect.stringContaining('preRenderContainer is applied only by'));
|
|
2841
|
+
warnSpy.mockRestore();
|
|
2842
|
+
firstEmbed.destroy();
|
|
2843
|
+
customContainer.remove();
|
|
2844
|
+
});
|
|
2845
|
+
});
|
|
2846
|
+
});
|
|
2847
|
+
describe('preRenderConfig', () => {
|
|
2848
|
+
beforeEach(() => {
|
|
2849
|
+
window.ResizeObserver = jest.fn().mockImplementation(() => ({
|
|
2850
|
+
disconnect: jest.fn(),
|
|
2851
|
+
observe: jest.fn(),
|
|
2852
|
+
unobserve: jest.fn(),
|
|
2853
|
+
}));
|
|
2854
|
+
});
|
|
2855
|
+
it('should use default z-index of -1000 when preRenderConfig is not set', async () => {
|
|
2856
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2857
|
+
const libEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2858
|
+
preRenderId: 'pre-render-config-defaults',
|
|
2859
|
+
liveboardId: 'myLiveboardId',
|
|
2860
|
+
});
|
|
2861
|
+
await libEmbed.preRender();
|
|
2862
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2863
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2864
|
+
const preRenderWrapper = document.getElementById(preRenderIds.wrapper);
|
|
2865
|
+
expect(preRenderWrapper.style.zIndex).toBe('-1000');
|
|
2866
|
+
libEmbed.destroy();
|
|
2867
|
+
});
|
|
2868
|
+
it('should apply custom zIndex from preRenderConfig when hidden', async () => {
|
|
2869
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2870
|
+
const libEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2871
|
+
preRenderId: 'pre-render-config-custom-z-index',
|
|
2872
|
+
liveboardId: 'myLiveboardId',
|
|
2873
|
+
preRenderConfig: {
|
|
2874
|
+
zIndex: -10,
|
|
2875
|
+
},
|
|
2876
|
+
});
|
|
2877
|
+
await libEmbed.preRender();
|
|
2878
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2879
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2880
|
+
const preRenderWrapper = document.getElementById(preRenderIds.wrapper);
|
|
2881
|
+
expect(preRenderWrapper.style.zIndex).toBe('-10');
|
|
2882
|
+
libEmbed.destroy();
|
|
2883
|
+
});
|
|
2884
|
+
it('should clear z-index on showPreRender and restore custom zIndex on hidePreRender', async () => {
|
|
2885
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2886
|
+
const libEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2887
|
+
preRenderId: 'pre-render-config-cycle',
|
|
2888
|
+
liveboardId: 'myLiveboardId',
|
|
2889
|
+
preRenderConfig: {
|
|
2890
|
+
zIndex: -5,
|
|
2891
|
+
},
|
|
2892
|
+
});
|
|
2893
|
+
await libEmbed.preRender();
|
|
2894
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2895
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2896
|
+
const preRenderWrapper = document.getElementById(preRenderIds.wrapper);
|
|
2897
|
+
expect(preRenderWrapper.style.zIndex).toBe('-5');
|
|
2898
|
+
libEmbed.showPreRender();
|
|
2899
|
+
expect(preRenderWrapper.style.zIndex).toBe('');
|
|
2900
|
+
libEmbed.hidePreRender();
|
|
2901
|
+
expect(preRenderWrapper.style.zIndex).toBe('-5');
|
|
2902
|
+
libEmbed.destroy();
|
|
2903
|
+
});
|
|
2904
|
+
it('should use preRenderConfig.preRenderId to identify the pre-render instance', async () => {
|
|
2905
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2906
|
+
const libEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2907
|
+
liveboardId: 'myLiveboardId',
|
|
2908
|
+
preRenderConfig: {
|
|
2909
|
+
preRenderId: 'config-level-id',
|
|
2910
|
+
},
|
|
2911
|
+
});
|
|
2912
|
+
await libEmbed.preRender();
|
|
2913
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2914
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2915
|
+
expect(preRenderIds.wrapper).toContain('config-level-id');
|
|
2916
|
+
expect(document.getElementById(preRenderIds.wrapper)).not.toBeNull();
|
|
2917
|
+
libEmbed.destroy();
|
|
2918
|
+
});
|
|
2919
|
+
it('should prefer preRenderConfig.preRenderId over top-level preRenderId', async () => {
|
|
2920
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2921
|
+
const libEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2922
|
+
liveboardId: 'myLiveboardId',
|
|
2923
|
+
preRenderId: 'top-level-id',
|
|
2924
|
+
preRenderConfig: {
|
|
2925
|
+
preRenderId: 'config-level-id',
|
|
2926
|
+
},
|
|
2927
|
+
});
|
|
2928
|
+
await libEmbed.preRender();
|
|
2929
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2930
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2931
|
+
expect(preRenderIds.wrapper).toContain('config-level-id');
|
|
2932
|
+
expect(preRenderIds.wrapper).not.toContain('top-level-id');
|
|
2933
|
+
libEmbed.destroy();
|
|
2934
|
+
});
|
|
2935
|
+
it('should mount the wrapper into preRenderConfig.preRenderContainer', async () => {
|
|
2936
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2937
|
+
const customContainer = document.createElement('div');
|
|
2938
|
+
customContainer.id = 'config-level-container';
|
|
2939
|
+
document.body.appendChild(customContainer);
|
|
2940
|
+
const libEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2941
|
+
liveboardId: 'myLiveboardId',
|
|
2942
|
+
preRenderConfig: {
|
|
2943
|
+
preRenderId: 'container-via-config',
|
|
2944
|
+
preRenderContainer: '#config-level-container',
|
|
2945
|
+
},
|
|
2946
|
+
});
|
|
2947
|
+
await libEmbed.preRender();
|
|
2948
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2949
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2950
|
+
const preRenderWrapper = document.getElementById(preRenderIds.wrapper);
|
|
2951
|
+
expect(customContainer.contains(preRenderWrapper)).toBe(true);
|
|
2952
|
+
libEmbed.destroy();
|
|
2953
|
+
customContainer.remove();
|
|
2954
|
+
});
|
|
2955
|
+
it('should prefer preRenderConfig.preRenderContainer over top-level preRenderContainer', async () => {
|
|
2956
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2957
|
+
const topContainer = document.createElement('div');
|
|
2958
|
+
topContainer.id = 'top-level-container';
|
|
2959
|
+
document.body.appendChild(topContainer);
|
|
2960
|
+
const configContainer = document.createElement('div');
|
|
2961
|
+
configContainer.id = 'config-level-container-2';
|
|
2962
|
+
document.body.appendChild(configContainer);
|
|
2963
|
+
const libEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2964
|
+
liveboardId: 'myLiveboardId',
|
|
2965
|
+
preRenderContainer: '#top-level-container',
|
|
2966
|
+
preRenderConfig: {
|
|
2967
|
+
preRenderId: 'container-precedence',
|
|
2968
|
+
preRenderContainer: '#config-level-container-2',
|
|
2969
|
+
},
|
|
2970
|
+
});
|
|
2971
|
+
await libEmbed.preRender();
|
|
2972
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2973
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
2974
|
+
const preRenderWrapper = document.getElementById(preRenderIds.wrapper);
|
|
2975
|
+
expect(configContainer.contains(preRenderWrapper)).toBe(true);
|
|
2976
|
+
expect(topContainer.contains(preRenderWrapper)).toBe(false);
|
|
2977
|
+
libEmbed.destroy();
|
|
2978
|
+
topContainer.remove();
|
|
2979
|
+
configContainer.remove();
|
|
2980
|
+
});
|
|
2981
|
+
it('should not attach ResizeObserver when preRenderConfig.doNotTrackPreRenderSize is true', async () => {
|
|
2982
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
2983
|
+
const observeMock = jest.fn();
|
|
2984
|
+
window.ResizeObserver = jest.fn().mockImplementation(() => ({
|
|
2985
|
+
disconnect: jest.fn(),
|
|
2986
|
+
observe: observeMock,
|
|
2987
|
+
unobserve: jest.fn(),
|
|
2988
|
+
}));
|
|
2989
|
+
const libEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
2990
|
+
liveboardId: 'myLiveboardId',
|
|
2991
|
+
preRenderConfig: {
|
|
2992
|
+
preRenderId: 'no-track-via-config',
|
|
2993
|
+
doNotTrackPreRenderSize: true,
|
|
2994
|
+
},
|
|
2995
|
+
});
|
|
2996
|
+
await libEmbed.preRender();
|
|
2997
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
2998
|
+
libEmbed.showPreRender();
|
|
2999
|
+
expect(observeMock).not.toHaveBeenCalled();
|
|
3000
|
+
libEmbed.destroy();
|
|
3001
|
+
});
|
|
3002
|
+
it('should prefer preRenderConfig.doNotTrackPreRenderSize over top-level doNotTrackPreRenderSize', async () => {
|
|
3003
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
3004
|
+
const observeMock = jest.fn();
|
|
3005
|
+
window.ResizeObserver = jest.fn().mockImplementation(() => ({
|
|
3006
|
+
disconnect: jest.fn(),
|
|
3007
|
+
observe: observeMock,
|
|
3008
|
+
unobserve: jest.fn(),
|
|
3009
|
+
}));
|
|
3010
|
+
const libEmbed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
3011
|
+
liveboardId: 'myLiveboardId',
|
|
3012
|
+
doNotTrackPreRenderSize: false,
|
|
3013
|
+
preRenderConfig: {
|
|
3014
|
+
preRenderId: 'no-track-precedence',
|
|
3015
|
+
doNotTrackPreRenderSize: true,
|
|
3016
|
+
},
|
|
3017
|
+
});
|
|
3018
|
+
await libEmbed.preRender();
|
|
3019
|
+
await (0, test_utils_1.waitFor)(() => !!(0, test_utils_1.getIFrameEl)());
|
|
3020
|
+
libEmbed.showPreRender();
|
|
3021
|
+
expect(observeMock).not.toHaveBeenCalled();
|
|
3022
|
+
libEmbed.destroy();
|
|
3023
|
+
});
|
|
2443
3024
|
});
|
|
2444
3025
|
});
|
|
2445
3026
|
describe('IdleSessionTimeout embedEvent for TrustedAuthTokenCookieless authType with autoLogin true', () => {
|
|
@@ -3727,6 +4308,20 @@ describe('Trigger method edge cases', () => {
|
|
|
3727
4308
|
expect(result).toBeNull();
|
|
3728
4309
|
});
|
|
3729
4310
|
});
|
|
4311
|
+
test('isValidationError catch: handleError called with embedErrorDetails and error is rethrown', async () => {
|
|
4312
|
+
const searchEmbed = new index_1.SearchEmbed((0, test_utils_1.getRootEl)(), defaultViewConfig);
|
|
4313
|
+
const handleErrorSpy = jest.spyOn(searchEmbed, 'handleError').mockImplementation(() => { });
|
|
4314
|
+
await searchEmbed.render();
|
|
4315
|
+
// First processTrigger call is getAvailableUIPassthroughKeys for DrillDown
|
|
4316
|
+
mockProcessTrigger.mockResolvedValueOnce([
|
|
4317
|
+
{ value: { keys: Object.values(contracts_1.UIPassthroughEvent) } },
|
|
4318
|
+
]);
|
|
4319
|
+
// DrillDown with no points → throwDrillDownValidationError → isValidationError=true
|
|
4320
|
+
await expect(searchEmbed.trigger(types_1.HostEvent.DrillDown, {})).rejects.toThrow('DrillDown requires a valid points object');
|
|
4321
|
+
expect(handleErrorSpy).toHaveBeenCalledWith(expect.objectContaining({
|
|
4322
|
+
data: expect.objectContaining({ code: types_1.EmbedErrorCodes.HOST_EVENT_VALIDATION }),
|
|
4323
|
+
}));
|
|
4324
|
+
});
|
|
3730
4325
|
});
|
|
3731
4326
|
describe('PreRender replaceExistingPreRender scenarios', () => {
|
|
3732
4327
|
beforeAll(() => {
|
|
@@ -3735,6 +4330,9 @@ describe('PreRender replaceExistingPreRender scenarios', () => {
|
|
|
3735
4330
|
authType: index_1.AuthType.None,
|
|
3736
4331
|
});
|
|
3737
4332
|
});
|
|
4333
|
+
beforeEach(() => {
|
|
4334
|
+
document.body.innerHTML = (0, test_utils_1.getDocumentBody)();
|
|
4335
|
+
});
|
|
3738
4336
|
afterEach(() => {
|
|
3739
4337
|
const rootEle = document.getElementById('myRoot');
|
|
3740
4338
|
rootEle === null || rootEle === void 0 ? void 0 : rootEle.remove();
|
|
@@ -3842,6 +4440,40 @@ describe('Fullscreen change handler behavior', () => {
|
|
|
3842
4440
|
expect(mockProcessTrigger).not.toHaveBeenCalledWith(expect.any(Object), types_1.HostEvent.ExitPresentMode, expect.any(String), expect.any(Object));
|
|
3843
4441
|
});
|
|
3844
4442
|
});
|
|
4443
|
+
test('disableFullscreenPresentation undefined defaults to true — no fullscreenchange listener registered', () => {
|
|
4444
|
+
(0, index_1.init)({
|
|
4445
|
+
thoughtSpotHost: 'tshost',
|
|
4446
|
+
authType: index_1.AuthType.None,
|
|
4447
|
+
// disableFullscreenPresentation not set → defaults to true via ?? true
|
|
4448
|
+
});
|
|
4449
|
+
const embed = new index_1.SearchEmbed((0, test_utils_1.getRootEl)(), defaultViewConfig);
|
|
4450
|
+
const addEventListenerSpy = jest.spyOn(document, 'addEventListener');
|
|
4451
|
+
embed['setupFullscreenChangeHandler']();
|
|
4452
|
+
expect(addEventListenerSpy).not.toHaveBeenCalledWith('fullscreenchange', expect.any(Function));
|
|
4453
|
+
addEventListenerSpy.mockRestore();
|
|
4454
|
+
// Restore for other tests in this describe
|
|
4455
|
+
(0, index_1.init)({ thoughtSpotHost: 'tshost', authType: index_1.AuthType.None, disableFullscreenPresentation: false });
|
|
4456
|
+
});
|
|
4457
|
+
test('fullscreenchange fires but iFrame.contentWindow is null — trigger NOT called, debug log emitted', () => {
|
|
4458
|
+
const embed = new index_1.SearchEmbed((0, test_utils_1.getRootEl)(), defaultViewConfig);
|
|
4459
|
+
// Give the embed a fake iFrame with null contentWindow
|
|
4460
|
+
embed.iFrame = { contentWindow: null };
|
|
4461
|
+
const addEventListenerSpy = jest.spyOn(document, 'addEventListener');
|
|
4462
|
+
const loggerDebugSpy = jest.spyOn(logger_1.logger, 'debug').mockImplementation(() => { });
|
|
4463
|
+
const triggerSpy = jest.spyOn(embed, 'trigger').mockImplementation(() => Promise.resolve(null));
|
|
4464
|
+
embed['setupFullscreenChangeHandler']();
|
|
4465
|
+
// Capture the registered handler directly instead of dispatching to document
|
|
4466
|
+
const fullscreenCall = addEventListenerSpy.mock.calls.find((c) => c[0] === 'fullscreenchange');
|
|
4467
|
+
expect(fullscreenCall).toBeTruthy();
|
|
4468
|
+
const handler = fullscreenCall[1];
|
|
4469
|
+
Object.defineProperty(document, 'fullscreenElement', { value: null, writable: true, configurable: true });
|
|
4470
|
+
handler(new Event('fullscreenchange'));
|
|
4471
|
+
expect(triggerSpy).not.toHaveBeenCalled();
|
|
4472
|
+
expect(loggerDebugSpy).toHaveBeenCalledWith(expect.stringContaining('Skipping ExitPresentMode'));
|
|
4473
|
+
addEventListenerSpy.mockRestore();
|
|
4474
|
+
loggerDebugSpy.mockRestore();
|
|
4475
|
+
triggerSpy.mockRestore();
|
|
4476
|
+
});
|
|
3845
4477
|
});
|
|
3846
4478
|
describe('ShowPreRender with UpdateEmbedParams', () => {
|
|
3847
4479
|
const setupPreRenderTest = async (preRenderId, initialConfig) => {
|
|
@@ -4298,6 +4930,54 @@ describe('ShowPreRender with UpdateEmbedParams', () => {
|
|
|
4298
4930
|
expect(placeholderEle.parentElement).not.toBeNull();
|
|
4299
4931
|
embed.destroy();
|
|
4300
4932
|
});
|
|
4933
|
+
// showPreRender located the stale placeholder with a subtree-wide
|
|
4934
|
+
// querySelector but removed it with hostElement.removeChild(), which
|
|
4935
|
+
// only accepts direct children. With fullHeight the placeholder can be
|
|
4936
|
+
// nested deeper than a direct child, so removeChild threw
|
|
4937
|
+
// "NotFoundError: Failed to execute 'removeChild' on 'Node'".
|
|
4938
|
+
it('showPreRender removes a placeholder nested below a direct child without throwing', async () => {
|
|
4939
|
+
(0, test_utils_1.createRootEleForEmbed)();
|
|
4940
|
+
const embed = new index_1.LiveboardEmbed('#tsEmbedDiv', {
|
|
4941
|
+
preRenderId: 'ph-nested-test',
|
|
4942
|
+
liveboardId: 'lb-id',
|
|
4943
|
+
fullHeight: true,
|
|
4944
|
+
});
|
|
4945
|
+
await embed.preRender();
|
|
4946
|
+
await (0, test_utils_1.waitFor)(() => !!document.querySelector('#tsEmbed-pre-render-child-ph-nested-test'));
|
|
4947
|
+
const hostElement = document.querySelector('#tsEmbedDiv');
|
|
4948
|
+
const placeHolderId = 'tsEmbed-pre-render-placeholder-ph-nested-test';
|
|
4949
|
+
// Simulate the fullHeight layout where the placeholder ends up as
|
|
4950
|
+
// a grandchild of the host element rather than a direct child.
|
|
4951
|
+
const intermediateWrapper = document.createElement('div');
|
|
4952
|
+
const staleNestedPlaceholder = document.createElement('div');
|
|
4953
|
+
staleNestedPlaceholder.id = placeHolderId;
|
|
4954
|
+
intermediateWrapper.appendChild(staleNestedPlaceholder);
|
|
4955
|
+
hostElement.appendChild(intermediateWrapper);
|
|
4956
|
+
expect(hostElement.querySelector(`#${placeHolderId}`)).toBe(staleNestedPlaceholder);
|
|
4957
|
+
// Before the fix this threw NotFoundError.
|
|
4958
|
+
await expect(embed.showPreRender()).resolves.toBeDefined();
|
|
4959
|
+
// The stale nested placeholder is gone; the fresh one is a direct child.
|
|
4960
|
+
expect(staleNestedPlaceholder.isConnected).toBe(false);
|
|
4961
|
+
const currentPlaceholder = embed.getPreRenderPlaceHolderElement();
|
|
4962
|
+
expect(currentPlaceholder.parentElement).toBe(hostElement);
|
|
4963
|
+
embed.destroy();
|
|
4964
|
+
});
|
|
4965
|
+
});
|
|
4966
|
+
describe('trigger typing contracts (compile-time)', () => {
|
|
4967
|
+
it('infers typed response for no-payload calls on the base trigger', () => {
|
|
4968
|
+
const searchEmbed = new index_1.SearchEmbed((0, test_utils_1.getRootEl)(), defaultViewConfig);
|
|
4969
|
+
const getTabs = () => searchEmbed.trigger(types_1.HostEvent.GetTabs);
|
|
4970
|
+
const tabsIsTyped = false;
|
|
4971
|
+
const tabsHasContractFields = true;
|
|
4972
|
+
const probeUnknownField = (r) =>
|
|
4973
|
+
// @ts-expect-error — field not on the GetTabs contract (was silent when `any`)
|
|
4974
|
+
r.tabCount;
|
|
4975
|
+
void probeUnknownField;
|
|
4976
|
+
const reload = () => searchEmbed.trigger(types_1.HostEvent.Reload);
|
|
4977
|
+
const reloadStaysAny = true;
|
|
4978
|
+
expect([tabsIsTyped, tabsHasContractFields, reloadStaysAny])
|
|
4979
|
+
.toEqual([false, true, true]);
|
|
4980
|
+
});
|
|
4301
4981
|
});
|
|
4302
4982
|
});
|
|
4303
4983
|
//# sourceMappingURL=ts-embed.spec.js.map
|