@thoughtspot/visual-embed-sdk 1.35.3 → 1.35.4
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/auth.spec.js +12 -0
- package/cjs/src/auth.spec.js.map +1 -1
- package/cjs/src/authToken.spec.js +1 -1
- package/cjs/src/authToken.spec.js.map +1 -1
- package/cjs/src/embed/app.d.ts +1 -1
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +4 -3
- package/cjs/src/embed/app.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/bodyless-conversation.spec.js +0 -1
- package/cjs/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/cjs/src/embed/hostEventClient/contracts.d.ts +79 -0
- package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -0
- package/cjs/src/embed/hostEventClient/contracts.js +14 -0
- package/cjs/src/embed/hostEventClient/contracts.js.map +1 -0
- package/cjs/src/embed/hostEventClient/host-event-client.d.ts +25 -0
- package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -0
- package/cjs/src/embed/hostEventClient/host-event-client.js +89 -0
- package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -0
- package/cjs/src/embed/hostEventClient/host-event-client.spec.d.ts +2 -0
- package/cjs/src/embed/hostEventClient/host-event-client.spec.d.ts.map +1 -0
- package/cjs/src/embed/hostEventClient/host-event-client.spec.js +191 -0
- package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -0
- package/cjs/src/embed/liveboard.d.ts +10 -8
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +3 -3
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +34 -2
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/search.spec.js +11 -0
- package/cjs/src/embed/search.spec.js.map +1 -1
- package/cjs/src/embed/searchEmbed-basic-auth.spec.d.ts +2 -0
- package/cjs/src/embed/searchEmbed-basic-auth.spec.d.ts.map +1 -0
- package/cjs/src/embed/searchEmbed-basic-auth.spec.js +104 -0
- package/cjs/src/embed/searchEmbed-basic-auth.spec.js.map +1 -0
- package/cjs/src/embed/ts-embed.d.ts +21 -4
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +30 -9
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +26 -1
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/hostEventsTypeMapping.d.ts +2 -0
- package/cjs/src/hostEventsTypeMapping.d.ts.map +1 -0
- package/cjs/src/hostEventsTypeMapping.js +4 -0
- package/cjs/src/hostEventsTypeMapping.js.map +1 -0
- package/cjs/src/index.d.ts +2 -1
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +3 -1
- package/cjs/src/index.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/types.d.ts +38 -23
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +31 -20
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/embedApi/contracts.d.ts +101 -0
- package/cjs/src/utils/embedApi/contracts.d.ts.map +1 -0
- package/cjs/src/utils/embedApi/contracts.js +17 -0
- package/cjs/src/utils/embedApi/contracts.js.map +1 -0
- package/cjs/src/utils/embedApi/embedApiClient.d.ts +12 -0
- package/cjs/src/utils/embedApi/embedApiClient.d.ts.map +1 -0
- package/cjs/src/utils/embedApi/embedApiClient.js +46 -0
- package/cjs/src/utils/embedApi/embedApiClient.js.map +1 -0
- package/cjs/src/utils/embedApi/processEmbedApi.d.ts +9 -0
- package/cjs/src/utils/embedApi/processEmbedApi.d.ts.map +1 -0
- package/cjs/src/utils/embedApi/processEmbedApi.js +18 -0
- package/cjs/src/utils/embedApi/processEmbedApi.js.map +1 -0
- package/dist/{index-BaGHDCpW.js → index-BBBimG1x.js} +1 -1
- package/dist/index-CENLvayL.js +7370 -0
- package/dist/index-CbltIawo.js +7370 -0
- package/dist/index-CoQfqaHj.js +7370 -0
- package/dist/index-CzwzS0P4.js +7370 -0
- package/dist/index-DFwi_pV_.js +7370 -0
- package/dist/index-DOIjN0N_.js +7370 -0
- package/dist/index-DYBx8SuE.js +7370 -0
- package/dist/index-DaLHJaLd.js +7370 -0
- package/dist/index-nWevLycs.js +7370 -0
- package/dist/src/embed/app.d.ts +1 -1
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/base.d.ts +1 -1
- package/dist/src/embed/hostEventClient/contracts.d.ts +79 -0
- package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -0
- package/dist/src/embed/hostEventClient/host-event-client.d.ts +25 -0
- package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -0
- package/dist/src/embed/hostEventClient/host-event-client.spec.d.ts +2 -0
- package/dist/src/embed/hostEventClient/host-event-client.spec.d.ts.map +1 -0
- package/dist/src/embed/liveboard.d.ts +10 -8
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/searchEmbed-basic-auth.spec.d.ts +2 -0
- package/dist/src/embed/searchEmbed-basic-auth.spec.d.ts.map +1 -0
- package/dist/src/embed/ts-embed.d.ts +21 -4
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/dist/src/hostEventsTypeMapping.d.ts +2 -0
- package/dist/src/hostEventsTypeMapping.d.ts.map +1 -0
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.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/types.d.ts +38 -23
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/embedApi/contracts.d.ts +101 -0
- package/dist/src/utils/embedApi/contracts.d.ts.map +1 -0
- package/dist/src/utils/embedApi/embedApiClient.d.ts +12 -0
- package/dist/src/utils/embedApi/embedApiClient.d.ts.map +1 -0
- package/dist/src/utils/embedApi/processEmbedApi.d.ts +9 -0
- package/dist/src/utils/embedApi/processEmbedApi.d.ts.map +1 -0
- package/dist/tsembed-react.es.js +161 -37
- package/dist/tsembed-react.js +160 -36
- package/dist/tsembed.es.js +163 -39
- package/dist/tsembed.js +161 -37
- package/dist/visual-embed-sdk-react-full.d.ts +170 -38
- package/dist/visual-embed-sdk-react.d.ts +170 -38
- package/dist/visual-embed-sdk.d.ts +170 -38
- package/lib/package.json +1 -1
- package/lib/src/auth.spec.js +12 -0
- package/lib/src/auth.spec.js.map +1 -1
- package/lib/src/authToken.spec.js +1 -1
- package/lib/src/authToken.spec.js.map +1 -1
- package/lib/src/embed/app.d.ts +1 -1
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +4 -3
- package/lib/src/embed/app.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/bodyless-conversation.spec.js +0 -1
- package/lib/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/lib/src/embed/hostEventClient/contracts.d.ts +79 -0
- package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -0
- package/lib/src/embed/hostEventClient/contracts.js +11 -0
- package/lib/src/embed/hostEventClient/contracts.js.map +1 -0
- package/lib/src/embed/hostEventClient/host-event-client.d.ts +25 -0
- package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -0
- package/lib/src/embed/hostEventClient/host-event-client.js +85 -0
- package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -0
- package/lib/src/embed/hostEventClient/host-event-client.spec.d.ts +2 -0
- package/lib/src/embed/hostEventClient/host-event-client.spec.d.ts.map +1 -0
- package/lib/src/embed/hostEventClient/host-event-client.spec.js +188 -0
- package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -0
- package/lib/src/embed/liveboard.d.ts +10 -8
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +3 -3
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +34 -2
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/search.spec.js +11 -0
- package/lib/src/embed/search.spec.js.map +1 -1
- package/lib/src/embed/searchEmbed-basic-auth.spec.d.ts +2 -0
- package/lib/src/embed/searchEmbed-basic-auth.spec.d.ts.map +1 -0
- package/lib/src/embed/searchEmbed-basic-auth.spec.js +101 -0
- package/lib/src/embed/searchEmbed-basic-auth.spec.js.map +1 -0
- package/lib/src/embed/ts-embed.d.ts +21 -4
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +30 -9
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +28 -3
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/hostEventsTypeMapping.d.ts +2 -0
- package/lib/src/hostEventsTypeMapping.d.ts.map +1 -0
- package/lib/src/hostEventsTypeMapping.js +2 -0
- package/lib/src/hostEventsTypeMapping.js.map +1 -0
- package/lib/src/index.d.ts +2 -1
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +2 -1
- package/lib/src/index.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/types.d.ts +38 -23
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +31 -20
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/embedApi/contracts.d.ts +101 -0
- package/lib/src/utils/embedApi/contracts.d.ts.map +1 -0
- package/lib/src/utils/embedApi/contracts.js +14 -0
- package/lib/src/utils/embedApi/contracts.js.map +1 -0
- package/lib/src/utils/embedApi/embedApiClient.d.ts +12 -0
- package/lib/src/utils/embedApi/embedApiClient.d.ts.map +1 -0
- package/lib/src/utils/embedApi/embedApiClient.js +42 -0
- package/lib/src/utils/embedApi/embedApiClient.js.map +1 -0
- package/lib/src/utils/embedApi/processEmbedApi.d.ts +9 -0
- package/lib/src/utils/embedApi/processEmbedApi.d.ts.map +1 -0
- package/lib/src/utils/embedApi/processEmbedApi.js +14 -0
- package/lib/src/utils/embedApi/processEmbedApi.js.map +1 -0
- package/lib/src/visual-embed-sdk.d.ts +181 -38
- package/package.json +1 -1
- package/src/auth.spec.ts +13 -0
- package/src/authToken.spec.ts +1 -1
- package/src/embed/app.ts +7 -4
- package/src/embed/base.ts +1 -1
- package/src/embed/bodyless-conversation.spec.ts +0 -1
- package/src/embed/hostEventClient/contracts.ts +105 -0
- package/src/embed/hostEventClient/host-event-client.spec.ts +254 -0
- package/src/embed/hostEventClient/host-event-client.ts +139 -0
- package/src/embed/liveboard.spec.ts +36 -2
- package/src/embed/liveboard.ts +13 -8
- package/src/embed/search.spec.ts +15 -0
- package/src/embed/ts-embed.spec.ts +40 -1
- package/src/embed/ts-embed.ts +57 -16
- package/src/index.ts +2 -0
- package/src/react/all-types-export.ts +1 -0
- package/src/types.ts +37 -22
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { getIFrameEl, getRootEl } from '../../test/test-utils';
|
|
2
|
+
import { HostEvent } from '../../types';
|
|
3
|
+
import { processTrigger } from '../../utils/processTrigger';
|
|
4
|
+
import * as EmbedConfigService from '../embedConfig';
|
|
5
|
+
import {
|
|
6
|
+
UIPassthroughEvent,
|
|
7
|
+
UIPassthroughRequest,
|
|
8
|
+
UIPassthroughArrayResponse,
|
|
9
|
+
HostEventRequest,
|
|
10
|
+
} from './contracts';
|
|
11
|
+
import { HostEventClient } from './host-event-client';
|
|
12
|
+
|
|
13
|
+
jest.mock('../../utils/processTrigger');
|
|
14
|
+
|
|
15
|
+
const mockProcessTrigger = processTrigger as jest.Mock;
|
|
16
|
+
|
|
17
|
+
const createHostEventClient = () => {
|
|
18
|
+
const mockIframe = document.createElement('iframe');
|
|
19
|
+
const client = new HostEventClient(mockIframe);
|
|
20
|
+
return { client, mockIframe };
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
describe('HostEventClient', () => {
|
|
24
|
+
const mockThoughtSpotHost = 'http://localhost';
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
jest.spyOn(EmbedConfigService, 'getEmbedConfig').mockReturnValue({ thoughtSpotHost: mockThoughtSpotHost });
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
jest.clearAllMocks();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe('executeUIPassthroughApi', () => {
|
|
34
|
+
it('should call processTrigger with correct parameters and return response', async () => {
|
|
35
|
+
const { client, mockIframe } = createHostEventClient();
|
|
36
|
+
|
|
37
|
+
const apiName = UIPassthroughEvent.PinAnswerToLiveboard;
|
|
38
|
+
const parameters: UIPassthroughRequest<typeof apiName> = {
|
|
39
|
+
newVizName: 'testViz',
|
|
40
|
+
};
|
|
41
|
+
const triggerResponse = Promise.resolve([
|
|
42
|
+
{ value: { pinboardId: 'testPinboard', tabId: 'testTab', vizId: 'testVizId' } },
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
mockProcessTrigger.mockResolvedValue(triggerResponse);
|
|
46
|
+
|
|
47
|
+
const result = await client.triggerUIPassthroughApi(apiName, parameters);
|
|
48
|
+
|
|
49
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(
|
|
50
|
+
mockIframe,
|
|
51
|
+
HostEvent.UIPassthrough,
|
|
52
|
+
mockThoughtSpotHost,
|
|
53
|
+
{
|
|
54
|
+
type: apiName,
|
|
55
|
+
parameters,
|
|
56
|
+
},
|
|
57
|
+
);
|
|
58
|
+
expect(result).toEqual(await triggerResponse);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe('handleUIPassthroughForHostEvent', () => {
|
|
63
|
+
it('should return the value from the first valid response', async () => {
|
|
64
|
+
const { client } = createHostEventClient();
|
|
65
|
+
const apiName = UIPassthroughEvent.PinAnswerToLiveboard;
|
|
66
|
+
const parameters: UIPassthroughRequest<typeof apiName> = {
|
|
67
|
+
newVizName: 'testViz',
|
|
68
|
+
};
|
|
69
|
+
const triggerResponse = Promise.resolve([
|
|
70
|
+
{ value: { pinboardId: 'testPinboard', tabId: 'testTab', vizId: 'testVizId' } },
|
|
71
|
+
]);
|
|
72
|
+
mockProcessTrigger.mockResolvedValue(triggerResponse);
|
|
73
|
+
|
|
74
|
+
const result = await client.handleHostEventWithParam(apiName, parameters);
|
|
75
|
+
|
|
76
|
+
expect(result).toEqual({
|
|
77
|
+
pinboardId: 'testPinboard',
|
|
78
|
+
tabId: 'testTab',
|
|
79
|
+
vizId: 'testVizId',
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should throw an error if no valid response is found', async () => {
|
|
84
|
+
const { client } = createHostEventClient();
|
|
85
|
+
const apiName = UIPassthroughEvent.PinAnswerToLiveboard;
|
|
86
|
+
const parameters: UIPassthroughRequest<typeof apiName> = {
|
|
87
|
+
newVizName: 'testViz',
|
|
88
|
+
};
|
|
89
|
+
const triggerResponse: UIPassthroughArrayResponse<typeof apiName> = [];
|
|
90
|
+
mockProcessTrigger.mockResolvedValue(triggerResponse);
|
|
91
|
+
|
|
92
|
+
await expect(client.handleHostEventWithParam(apiName, parameters))
|
|
93
|
+
.rejects.toEqual({ error: 'No answer found.' });
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('should throw an error if no valid response is found for vizId', async () => {
|
|
97
|
+
const { client } = createHostEventClient();
|
|
98
|
+
const apiName = UIPassthroughEvent.PinAnswerToLiveboard;
|
|
99
|
+
const parameters: UIPassthroughRequest<typeof apiName> = {
|
|
100
|
+
newVizName: 'testViz',
|
|
101
|
+
vizId: 'testVizId',
|
|
102
|
+
};
|
|
103
|
+
const triggerResponse: UIPassthroughArrayResponse<typeof apiName> = [];
|
|
104
|
+
mockProcessTrigger.mockResolvedValue(triggerResponse);
|
|
105
|
+
|
|
106
|
+
await expect(client.handleHostEventWithParam(apiName, parameters))
|
|
107
|
+
.rejects.toEqual({ error: 'No answer found for vizId: testVizId.' });
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should throw an error if the response contains errors', async () => {
|
|
111
|
+
const { client } = createHostEventClient();
|
|
112
|
+
const apiName = UIPassthroughEvent.PinAnswerToLiveboard;
|
|
113
|
+
const parameters: UIPassthroughRequest<typeof apiName> = {
|
|
114
|
+
newVizName: 'testViz',
|
|
115
|
+
};
|
|
116
|
+
const triggerResponse: UIPassthroughArrayResponse<typeof apiName> = [
|
|
117
|
+
{ error: 'Some error' },
|
|
118
|
+
];
|
|
119
|
+
mockProcessTrigger.mockResolvedValue(triggerResponse);
|
|
120
|
+
|
|
121
|
+
await expect(client.handleHostEventWithParam(apiName, parameters))
|
|
122
|
+
.rejects.toEqual({ error: 'Some error' });
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe('executeHostEvent', () => {
|
|
127
|
+
it('should call handleUIPassthroughForHostEvent for Pin event', async () => {
|
|
128
|
+
const { client, mockIframe } = createHostEventClient();
|
|
129
|
+
const hostEvent = HostEvent.Pin;
|
|
130
|
+
const payload: HostEventRequest<typeof hostEvent> = {
|
|
131
|
+
newVizName: 'testViz',
|
|
132
|
+
};
|
|
133
|
+
const mockResponse = {
|
|
134
|
+
value: {
|
|
135
|
+
pinboardId: 'testPinboard',
|
|
136
|
+
tabId: 'testTab',
|
|
137
|
+
vizId: 'testVizId',
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
mockProcessTrigger.mockResolvedValue([mockResponse]);
|
|
142
|
+
|
|
143
|
+
const result = await client.triggerHostEvent(hostEvent, payload);
|
|
144
|
+
|
|
145
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(
|
|
146
|
+
mockIframe,
|
|
147
|
+
HostEvent.UIPassthrough,
|
|
148
|
+
'http://localhost',
|
|
149
|
+
{ parameters: payload, type: UIPassthroughEvent.PinAnswerToLiveboard },
|
|
150
|
+
);
|
|
151
|
+
expect(result).toEqual(mockResponse.value);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('should call handleUIPassthroughForHostEvent for SaveAnswer event', async () => {
|
|
155
|
+
const { client, mockIframe } = createHostEventClient();
|
|
156
|
+
const hostEvent = HostEvent.SaveAnswer;
|
|
157
|
+
const payload: HostEventRequest<typeof hostEvent> = {
|
|
158
|
+
name: 'Test Answer',
|
|
159
|
+
description: 'Test Description',
|
|
160
|
+
vizId: 'testVizId',
|
|
161
|
+
};
|
|
162
|
+
const mockResponse = [{
|
|
163
|
+
value: {
|
|
164
|
+
saveResponse: {
|
|
165
|
+
data: {
|
|
166
|
+
Answer__save: {
|
|
167
|
+
answer: {
|
|
168
|
+
id: 'newAnswer',
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
refId: 'testVizId',
|
|
175
|
+
}];
|
|
176
|
+
mockProcessTrigger.mockResolvedValue(mockResponse);
|
|
177
|
+
const result = await client.triggerHostEvent(hostEvent, payload);
|
|
178
|
+
|
|
179
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(
|
|
180
|
+
mockIframe,
|
|
181
|
+
HostEvent.UIPassthrough,
|
|
182
|
+
mockThoughtSpotHost,
|
|
183
|
+
{
|
|
184
|
+
parameters: payload,
|
|
185
|
+
type: 'saveAnswer',
|
|
186
|
+
},
|
|
187
|
+
);
|
|
188
|
+
expect(result).toEqual({ answerId: 'newAnswer', ...mockResponse[0].value });
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it('should call hostEventFallback for unmapped events', async () => {
|
|
192
|
+
const { client } = createHostEventClient();
|
|
193
|
+
const hostEvent = 'testEvent' as HostEvent;
|
|
194
|
+
const payload = { data: 'testData' };
|
|
195
|
+
const mockResponse = { fallbackResponse: 'data' };
|
|
196
|
+
jest.spyOn(client, 'hostEventFallback').mockResolvedValue(mockResponse);
|
|
197
|
+
|
|
198
|
+
const result = await client.triggerHostEvent(hostEvent, payload);
|
|
199
|
+
|
|
200
|
+
expect(client.hostEventFallback).toHaveBeenCalledWith(hostEvent, payload);
|
|
201
|
+
expect(result).toEqual(mockResponse);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it('should call fallback for Pin event', async () => {
|
|
205
|
+
const { client, mockIframe } = createHostEventClient();
|
|
206
|
+
const hostEvent = HostEvent.Pin;
|
|
207
|
+
const payload: HostEventRequest<typeof hostEvent> = {} as any;
|
|
208
|
+
const mockResponse = {
|
|
209
|
+
value: {
|
|
210
|
+
pinboardId: 'testPinboard',
|
|
211
|
+
tabId: 'testTab',
|
|
212
|
+
vizId: 'testVizId',
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
mockProcessTrigger.mockResolvedValue([mockResponse]);
|
|
217
|
+
|
|
218
|
+
const result = await client.triggerHostEvent(hostEvent, payload);
|
|
219
|
+
|
|
220
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(
|
|
221
|
+
mockIframe,
|
|
222
|
+
HostEvent.Pin,
|
|
223
|
+
mockThoughtSpotHost,
|
|
224
|
+
{},
|
|
225
|
+
);
|
|
226
|
+
expect(result).toEqual([mockResponse]);
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('should call fallback for SaveAnswer event', async () => {
|
|
230
|
+
const { client, mockIframe } = createHostEventClient();
|
|
231
|
+
const hostEvent = HostEvent.SaveAnswer;
|
|
232
|
+
const payload: HostEventRequest<typeof hostEvent> = {} as any;
|
|
233
|
+
const mockResponse = {
|
|
234
|
+
value: {
|
|
235
|
+
pinboardId: 'testPinboard',
|
|
236
|
+
tabId: 'testTab',
|
|
237
|
+
vizId: 'testVizId',
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
mockProcessTrigger.mockResolvedValue([mockResponse]);
|
|
242
|
+
|
|
243
|
+
const result = await client.triggerHostEvent(hostEvent, payload);
|
|
244
|
+
|
|
245
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(
|
|
246
|
+
mockIframe,
|
|
247
|
+
HostEvent.Save,
|
|
248
|
+
mockThoughtSpotHost,
|
|
249
|
+
{},
|
|
250
|
+
);
|
|
251
|
+
expect(result).toEqual([mockResponse]);
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
});
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { HostEvent } from '../../types';
|
|
2
|
+
import { processTrigger as processTriggerService } from '../../utils/processTrigger';
|
|
3
|
+
import { getEmbedConfig } from '../embedConfig';
|
|
4
|
+
import {
|
|
5
|
+
UIPassthroughArrayResponse,
|
|
6
|
+
UIPassthroughEvent, HostEventRequest, HostEventResponse,
|
|
7
|
+
UIPassthroughRequest,
|
|
8
|
+
UIPassthroughResponse,
|
|
9
|
+
TriggerPayload,
|
|
10
|
+
TriggerResponse,
|
|
11
|
+
} from './contracts';
|
|
12
|
+
|
|
13
|
+
export class HostEventClient {
|
|
14
|
+
iFrame: HTMLIFrameElement;
|
|
15
|
+
|
|
16
|
+
constructor(iFrame?: HTMLIFrameElement) {
|
|
17
|
+
this.iFrame = iFrame;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A wrapper over process trigger to
|
|
22
|
+
* @param {HostEvent} message Host event to send
|
|
23
|
+
* @param {any} data Data to send with the host event
|
|
24
|
+
* @returns {Promise<any>} - the response from the process trigger
|
|
25
|
+
*/
|
|
26
|
+
protected async processTrigger(message: HostEvent, data: any): Promise<any> {
|
|
27
|
+
if (!this.iFrame) {
|
|
28
|
+
throw new Error('Iframe element is not set');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const thoughtspotHost = getEmbedConfig().thoughtSpotHost;
|
|
32
|
+
return processTriggerService(
|
|
33
|
+
this.iFrame,
|
|
34
|
+
message,
|
|
35
|
+
thoughtspotHost,
|
|
36
|
+
data,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public async handleHostEventWithParam<UIPassthroughEventT extends UIPassthroughEvent>(
|
|
41
|
+
apiName: UIPassthroughEventT,
|
|
42
|
+
parameters: UIPassthroughRequest<UIPassthroughEventT>,
|
|
43
|
+
): Promise<UIPassthroughResponse<UIPassthroughEventT>> {
|
|
44
|
+
const response = (await this.triggerUIPassthroughApi(apiName, parameters))
|
|
45
|
+
?.filter?.((r) => r.error || r.value)[0];
|
|
46
|
+
|
|
47
|
+
if (!response) {
|
|
48
|
+
const error = `No answer found${parameters.vizId ? ` for vizId: ${parameters.vizId}` : ''}.`;
|
|
49
|
+
// eslint-disable-next-line no-throw-literal
|
|
50
|
+
throw { error };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const errors = response.error
|
|
54
|
+
|| (response.value as any)?.errors
|
|
55
|
+
|| (response.value as any)?.error;
|
|
56
|
+
|
|
57
|
+
if (errors) {
|
|
58
|
+
// eslint-disable-next-line no-throw-literal
|
|
59
|
+
throw { error: response.error };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return { ...response.value };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public async hostEventFallback(
|
|
66
|
+
hostEvent: HostEvent,
|
|
67
|
+
data: any,
|
|
68
|
+
): Promise<any> {
|
|
69
|
+
return this.processTrigger(hostEvent, data);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Setter for the iframe element used for host events
|
|
74
|
+
* @param {HTMLIFrameElement} iFrame - the iframe element to set
|
|
75
|
+
*/
|
|
76
|
+
public setIframeElement(iFrame: HTMLIFrameElement): void {
|
|
77
|
+
this.iFrame = iFrame;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public async triggerUIPassthroughApi<UIPassthroughEventT extends UIPassthroughEvent>(
|
|
81
|
+
apiName: UIPassthroughEventT,
|
|
82
|
+
parameters: UIPassthroughRequest<UIPassthroughEventT>,
|
|
83
|
+
): Promise<UIPassthroughArrayResponse<UIPassthroughEventT>> {
|
|
84
|
+
const res = await this.processTrigger(HostEvent.UIPassthrough, {
|
|
85
|
+
type: apiName,
|
|
86
|
+
parameters,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
return res;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
protected async handlePinEvent(
|
|
93
|
+
payload: HostEventRequest<HostEvent.Pin>,
|
|
94
|
+
): Promise<HostEventResponse<HostEvent.Pin>> {
|
|
95
|
+
if (!payload || !('newVizName' in payload)) {
|
|
96
|
+
return this.hostEventFallback(HostEvent.Pin, payload);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return this.handleHostEventWithParam(
|
|
100
|
+
UIPassthroughEvent.PinAnswerToLiveboard, payload,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
protected async handleSaveAnswerEvent(
|
|
105
|
+
payload: HostEventRequest<HostEvent.SaveAnswer>,
|
|
106
|
+
): Promise<any> {
|
|
107
|
+
if (!payload || !('name' in payload) || !('description' in payload)) {
|
|
108
|
+
// Save is the fallback for SaveAnswer
|
|
109
|
+
return this.hostEventFallback(HostEvent.Save, payload);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const data = await this.handleHostEventWithParam(
|
|
113
|
+
UIPassthroughEvent.SaveAnswer, payload,
|
|
114
|
+
);
|
|
115
|
+
return {
|
|
116
|
+
...data,
|
|
117
|
+
answerId: data?.saveResponse?.data?.Answer__save?.answer?.id,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public async triggerHostEvent<
|
|
122
|
+
HostEventT extends HostEvent,
|
|
123
|
+
PayloadT,
|
|
124
|
+
>(
|
|
125
|
+
hostEvent: HostEventT,
|
|
126
|
+
payload?: TriggerPayload<PayloadT, HostEventT>,
|
|
127
|
+
): Promise<TriggerResponse<PayloadT, HostEventT>> {
|
|
128
|
+
switch (hostEvent) {
|
|
129
|
+
case HostEvent.Pin:
|
|
130
|
+
return this.handlePinEvent(payload as HostEventRequest<HostEvent.Pin>) as any;
|
|
131
|
+
case HostEvent.SaveAnswer:
|
|
132
|
+
return this.handleSaveAnswerEvent(
|
|
133
|
+
payload as HostEventRequest<HostEvent.SaveAnswer>,
|
|
134
|
+
) as any;
|
|
135
|
+
default:
|
|
136
|
+
return this.hostEventFallback(hostEvent, payload);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -484,8 +484,10 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
484
484
|
liveboardId,
|
|
485
485
|
} as LiveboardViewConfig);
|
|
486
486
|
liveboardEmbed.render();
|
|
487
|
-
|
|
488
|
-
|
|
487
|
+
await executeAfterWait(async () => {
|
|
488
|
+
await liveboardEmbed.trigger(HostEvent.Pin);
|
|
489
|
+
expect(mockProcessTrigger).toBeCalled();
|
|
490
|
+
});
|
|
489
491
|
});
|
|
490
492
|
|
|
491
493
|
test('should render active tab when activeTab present', async () => {
|
|
@@ -570,6 +572,27 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
570
572
|
done();
|
|
571
573
|
});
|
|
572
574
|
});
|
|
575
|
+
|
|
576
|
+
test('navigateToLiveboard with preRender', (done) => {
|
|
577
|
+
mockMessageChannel();
|
|
578
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
579
|
+
...defaultViewConfig,
|
|
580
|
+
preRenderId: 'test',
|
|
581
|
+
} as LiveboardViewConfig);
|
|
582
|
+
const onSpy = jest.spyOn(liveboardEmbed, 'trigger');
|
|
583
|
+
liveboardEmbed.prerenderGeneric();
|
|
584
|
+
executeAfterWait(() => {
|
|
585
|
+
const iframe = getIFrameEl();
|
|
586
|
+
postMessageToParent(iframe.contentWindow, {
|
|
587
|
+
type: EmbedEvent.APP_INIT,
|
|
588
|
+
});
|
|
589
|
+
});
|
|
590
|
+
executeAfterWait(() => {
|
|
591
|
+
liveboardEmbed.navigateToLiveboard('lb1', 'viz1');
|
|
592
|
+
expect(onSpy).toHaveBeenCalledWith(HostEvent.Navigate, 'embed/viz/lb1/viz1');
|
|
593
|
+
done();
|
|
594
|
+
});
|
|
595
|
+
});
|
|
573
596
|
test('should set runtime parametere values in url params', async () => {
|
|
574
597
|
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
575
598
|
...defaultViewConfig,
|
|
@@ -659,6 +682,17 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
659
682
|
});
|
|
660
683
|
});
|
|
661
684
|
|
|
685
|
+
test('get liveboard url value', async () => {
|
|
686
|
+
const libEmbed = new LiveboardEmbed(getRootEl(), {
|
|
687
|
+
liveboardId: '1234',
|
|
688
|
+
});
|
|
689
|
+
await libEmbed.render();
|
|
690
|
+
await executeAfterWait(() => {
|
|
691
|
+
const url = libEmbed.getLiveboardUrl();
|
|
692
|
+
expect(url).toEqual('http://tshost/#/pinboard/1234');
|
|
693
|
+
});
|
|
694
|
+
});
|
|
695
|
+
|
|
662
696
|
test('Show preview loader should show the loader if viz embed and showPreviewLoader is true', async () => {
|
|
663
697
|
jest.spyOn(previewService, 'getPreview').mockResolvedValue({
|
|
664
698
|
vizContent: '<div id=test>test</div>',
|
package/src/embed/liveboard.ts
CHANGED
|
@@ -23,6 +23,7 @@ import { getQueryParamString, isUndefined } from '../utils';
|
|
|
23
23
|
import { getAuthPromise } from './base';
|
|
24
24
|
import { V1Embed } from './ts-embed';
|
|
25
25
|
import { addPreviewStylesIfNotPresent } from '../utils/global-styles';
|
|
26
|
+
import { HostEventRequest, HostEventResponse } from './hostEventClient/contracts';
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* The configuration for the embedded Liveboard or visualization page view.
|
|
@@ -248,7 +249,7 @@ export interface LiveboardViewConfig
|
|
|
248
249
|
*/
|
|
249
250
|
enableAskSage?: boolean;
|
|
250
251
|
/**
|
|
251
|
-
* This flag is used to enable the 2 column layout
|
|
252
|
+
* This flag is used to enable the 2 column layout on a Liveboard
|
|
252
253
|
* @type {boolean}
|
|
253
254
|
* @default false
|
|
254
255
|
* @version SDK: 1.32.0 | ThoughtSpot:10.1.0.cl
|
|
@@ -283,7 +284,7 @@ export interface LiveboardViewConfig
|
|
|
283
284
|
*/
|
|
284
285
|
showPreviewLoader?: boolean;
|
|
285
286
|
/**
|
|
286
|
-
* This flag is used to enable the compact header
|
|
287
|
+
* This flag is used to enable the compact header on a Liveboard
|
|
287
288
|
* @type {boolean}
|
|
288
289
|
* @default false
|
|
289
290
|
* @version SDK: 1.35.0 | ThoughtSpot:10.3.0.cl
|
|
@@ -297,7 +298,7 @@ export interface LiveboardViewConfig
|
|
|
297
298
|
*/
|
|
298
299
|
isLiveboardCompactHeaderEnabled?: boolean;
|
|
299
300
|
/**
|
|
300
|
-
* This flag is used to show/hide verified
|
|
301
|
+
* This flag is used to show/hide verified icon in the Liveboard compact header
|
|
301
302
|
* @type {boolean}
|
|
302
303
|
* @default true
|
|
303
304
|
* @version SDK: 1.35.0 | ThoughtSpot:10.4.0.cl
|
|
@@ -311,7 +312,8 @@ export interface LiveboardViewConfig
|
|
|
311
312
|
*/
|
|
312
313
|
showLiveboardVerifiedBadge?: boolean;
|
|
313
314
|
/**
|
|
314
|
-
* This flag is used to show/hide re-verify banner
|
|
315
|
+
* This flag is used to show/hide the re-verify banner
|
|
316
|
+
* in Liveboard compact header
|
|
315
317
|
* @type {boolean}
|
|
316
318
|
* @default true
|
|
317
319
|
* @version SDK: 1.35.0 | ThoughtSpot:10.4.0.cl
|
|
@@ -325,7 +327,7 @@ export interface LiveboardViewConfig
|
|
|
325
327
|
*/
|
|
326
328
|
showLiveboardReverifyBanner?: boolean;
|
|
327
329
|
/**
|
|
328
|
-
* This flag is used to enable/disable hide irrelevant filters in
|
|
330
|
+
* This flag is used to enable/disable hide irrelevant filters in a Liveboard tab
|
|
329
331
|
* @type {boolean}
|
|
330
332
|
* @default false
|
|
331
333
|
* @version SDK: 1.36.0 | ThoughtSpot:10.6.0.cl
|
|
@@ -636,7 +638,10 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
636
638
|
* @param messageType The event type
|
|
637
639
|
* @param data The payload to send with the message
|
|
638
640
|
*/
|
|
639
|
-
public trigger
|
|
641
|
+
public trigger<HostEventT extends HostEvent>(
|
|
642
|
+
messageType: HostEventT,
|
|
643
|
+
data?: HostEventRequest<HostEventT>,
|
|
644
|
+
): Promise<HostEventResponse<HostEventT>> {
|
|
640
645
|
const dataWithVizId = data;
|
|
641
646
|
if (messageType === HostEvent.SetActiveTab) {
|
|
642
647
|
this.setActiveTab(data);
|
|
@@ -678,8 +683,8 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
678
683
|
}
|
|
679
684
|
|
|
680
685
|
/**
|
|
681
|
-
* Returns the full url of the
|
|
682
|
-
* this
|
|
686
|
+
* Returns the full url of the Liveboard/visualization which can be used to open
|
|
687
|
+
* this Liveboard inside the full Thoughtspot application in a new tab.
|
|
683
688
|
* @returns url string
|
|
684
689
|
*/
|
|
685
690
|
public getLiveboardUrl(): string {
|
package/src/embed/search.spec.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
expectUrlMatchesWithParams,
|
|
17
17
|
} from '../test/test-utils';
|
|
18
18
|
import { version } from '../../package.json';
|
|
19
|
+
import { SearchBarEmbed } from './search-bar';
|
|
19
20
|
|
|
20
21
|
const defaultViewConfig = {
|
|
21
22
|
frameParams: {
|
|
@@ -504,6 +505,20 @@ describe('Search embed tests', () => {
|
|
|
504
505
|
});
|
|
505
506
|
});
|
|
506
507
|
|
|
508
|
+
test('should set dataPanelCustomGroupsAccordionInitialState to EXPAND_FIRST when passed', async () => {
|
|
509
|
+
const searchEmbed = new SearchBarEmbed(getRootEl() as any, {
|
|
510
|
+
...defaultViewConfig,
|
|
511
|
+
// eslint-disable-next-line max-len
|
|
512
|
+
});
|
|
513
|
+
searchEmbed.render();
|
|
514
|
+
await executeAfterWait(() => {
|
|
515
|
+
expectUrlMatchesWithParams(
|
|
516
|
+
getIFrameSrc(),
|
|
517
|
+
`http://${thoughtSpotHost}/v2/?${defaultParams}&useLastSelectedSources=false${prefixParams}#/embed/search-bar-embed`,
|
|
518
|
+
);
|
|
519
|
+
});
|
|
520
|
+
});
|
|
521
|
+
|
|
507
522
|
test('should set dataPanelCustomGroupsAccordionInitialState to EXPAND_FIRST when passed', async () => {
|
|
508
523
|
const searchEmbed = new SearchEmbed(getRootEl(), {
|
|
509
524
|
...defaultViewConfig,
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
ConversationViewConfig,
|
|
16
16
|
ConversationEmbed,
|
|
17
17
|
SearchViewConfig,
|
|
18
|
+
AnswerService,
|
|
18
19
|
} from '../index';
|
|
19
20
|
import {
|
|
20
21
|
Action, HomeLeftNavItem, RuntimeFilter, RuntimeFilterOp, HomepageModule, HostEvent,
|
|
@@ -48,7 +49,12 @@ import * as authService from '../utils/authService/authService';
|
|
|
48
49
|
import { logger } from '../utils/logger';
|
|
49
50
|
import { version } from '../../package.json';
|
|
50
51
|
import { HiddenActionItemByDefaultForSearchEmbed } from './search';
|
|
52
|
+
import { processTrigger } from '../utils/processTrigger';
|
|
53
|
+
import { UIPassthroughEvent } from './hostEventClient/contracts';
|
|
51
54
|
|
|
55
|
+
jest.mock('../utils/processTrigger');
|
|
56
|
+
|
|
57
|
+
const mockProcessTrigger = processTrigger as jest.Mock;
|
|
52
58
|
const defaultViewConfig = {
|
|
53
59
|
frameParams: {
|
|
54
60
|
width: 1280,
|
|
@@ -127,6 +133,39 @@ describe('Unit test case for ts embed', () => {
|
|
|
127
133
|
});
|
|
128
134
|
});
|
|
129
135
|
|
|
136
|
+
test('should get answer service', async () => {
|
|
137
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
138
|
+
searchEmbed.render();
|
|
139
|
+
mockProcessTrigger.mockResolvedValue({ session: 'test' });
|
|
140
|
+
await executeAfterWait(async () => {
|
|
141
|
+
expect(await searchEmbed.getAnswerService()).toBeInstanceOf(AnswerService);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('triggerUIPassThrough with params', async () => {
|
|
146
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
147
|
+
searchEmbed.render();
|
|
148
|
+
mockProcessTrigger.mockResolvedValue({ session: 'test' });
|
|
149
|
+
await executeAfterWait(async () => {
|
|
150
|
+
const payload = { newVizName: 'test' };
|
|
151
|
+
expect(
|
|
152
|
+
await searchEmbed.triggerUIPassThrough(
|
|
153
|
+
UIPassthroughEvent.PinAnswerToLiveboard,
|
|
154
|
+
payload,
|
|
155
|
+
),
|
|
156
|
+
);
|
|
157
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(
|
|
158
|
+
getIFrameEl(),
|
|
159
|
+
HostEvent.UIPassthrough,
|
|
160
|
+
'http://tshost',
|
|
161
|
+
{
|
|
162
|
+
parameters: payload,
|
|
163
|
+
type: UIPassthroughEvent.PinAnswerToLiveboard,
|
|
164
|
+
},
|
|
165
|
+
);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
130
169
|
test('should set proper height, width and min-height to iframe', async () => {
|
|
131
170
|
// we dont have origin specific policies so just checking if
|
|
132
171
|
// policies are ending with ;
|
|
@@ -1351,7 +1390,6 @@ describe('Unit test case for ts embed', () => {
|
|
|
1351
1390
|
},
|
|
1352
1391
|
});
|
|
1353
1392
|
await appEmbed.render();
|
|
1354
|
-
console.log('val ', getIFrameSrc());
|
|
1355
1393
|
expectUrlMatchesWithParams(
|
|
1356
1394
|
getIFrameSrc(),
|
|
1357
1395
|
`http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false&${defaultParamsForPinboardEmbed}`
|
|
@@ -1817,6 +1855,7 @@ describe('Unit test case for ts embed', () => {
|
|
|
1817
1855
|
afterAll(() => {
|
|
1818
1856
|
const rootEle = document.getElementById('myRoot');
|
|
1819
1857
|
rootEle.remove();
|
|
1858
|
+
jest.clearAllMocks();
|
|
1820
1859
|
});
|
|
1821
1860
|
|
|
1822
1861
|
it('should preRender and hide the iframe', async () => {
|