@thoughtspot/visual-embed-sdk
Version:
ThoughtSpot Embed SDK
858 lines • 40 kB
JavaScript
import { LiveboardEmbed } from './liveboard';
import { init } from '../index';
import { Action, AuthType, ContextMenuTriggerOptions, EmbedEvent, HostEvent, RuntimeFilterOp, } from '../types';
import { executeAfterWait, getDocumentBody, getIFrameSrc, getRootEl, defaultParams, defaultParamsWithoutHiddenActions, expectUrlMatchesWithParams, postMessageToParent, getIFrameEl, mockMessageChannel, waitFor, } from '../test/test-utils';
import * as tsEmbed from './ts-embed';
import * as processTriggerInstance from '../utils/processTrigger';
import * as auth from '../auth';
import * as previewService from '../utils/graphql/preview-service';
const defaultViewConfig = {
frameParams: {
width: 1280,
height: 720,
},
};
const liveboardId = 'eca215d4-0d2c-4a55-90e3-d81ef6848ae0';
const activeTabId = '502693ba-9818-4e71-8ecd-d1a194e46861';
const newActiveTabId = '910e2398-eed9-443c-a975-355976629d27';
const vizId = '6e73f724-660e-11eb-ae93-0242ac130002';
const thoughtSpotHost = 'tshost';
const prefixParams = '&isLiveboardEmbed=true';
const prefixParamsVizEmbed = '&isLiveboardEmbed=true&isVizEmbed=true';
beforeAll(() => {
init({
thoughtSpotHost,
authType: AuthType.None,
});
jest.spyOn(auth, 'postLoginService').mockImplementation(() => Promise.resolve({}));
});
describe('Liveboard/viz embed tests', () => {
beforeEach(() => {
document.body.innerHTML = getDocumentBody();
});
test('should render liveboard', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('should render liveboard with data panel v2 flag set to false by default', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}&enableDataPanelV2=false#/embed/viz/${liveboardId}`);
});
});
test('should set disabled actions', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
disabledActions: [Action.DownloadAsCsv, Action.DownloadAsPdf, Action.DownloadAsXlsx],
disabledActionReason: 'Action denied',
...defaultViewConfig,
liveboardId,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true&${defaultParamsWithoutHiddenActions}&disableAction=[%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]&disableHint=Action%20denied&hideAction=[%22${Action.ReportError}%22]${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('should set hidden actions', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
hiddenActions: [Action.DownloadAsCsv, Action.DownloadAsPdf, Action.DownloadAsXlsx],
...defaultViewConfig,
liveboardId,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true&${defaultParamsWithoutHiddenActions}&hideAction=[%22${Action.ReportError}%22,%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('should set visible actions', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
visibleActions: [Action.DownloadAsCsv, Action.DownloadAsPdf, Action.DownloadAsXlsx],
...defaultViewConfig,
liveboardId,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&visibleAction=[%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('should set enable2ColumnLayout to true in url', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
enable2ColumnLayout: true,
...defaultViewConfig,
liveboardId,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&enable2ColumnLayout=true${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('should set isLiveboardStylingAndGroupingEnabled to true in url', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
isLiveboardStylingAndGroupingEnabled: true,
...defaultViewConfig,
liveboardId,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isLiveboardStylingAndGroupingEnabled=true${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('should set visible actions as empty array', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
visibleActions: [],
...defaultViewConfig,
liveboardId,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&visibleAction=[]${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('should enable viz transformations true', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
enableVizTransformations: true,
...defaultViewConfig,
liveboardId,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&enableVizTransform=true${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('should enable viz oAuthPollingInterval true', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
oAuthPollingInterval: 1000,
isForceRedirect: true,
dataSourceId: '12356',
...defaultViewConfig,
liveboardId,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&oAuthPollingInterval=1000&isForceRedirect=true&dataSourceId=12356${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('should disable viz transformations when enableVizTransformations false', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
enableVizTransformations: false,
...defaultViewConfig,
liveboardId,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&enableVizTransform=false${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('should render viz', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
vizId,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParamsVizEmbed}#/embed/viz/${liveboardId}/${vizId}`);
});
});
test('should apply runtime filters', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
vizId,
runtimeFilters: [
{
columnName: 'sales',
operator: RuntimeFilterOp.EQ,
values: [1000],
},
],
excludeRuntimeFiltersfromURL: false,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true&col1=sales&op1=EQ&val1=1000${defaultParams}${prefixParamsVizEmbed}#/embed/viz/${liveboardId}/${vizId}`);
});
});
test('Should add isLiveboardHeaderSticky flag to the iframe src', async () => {
const appEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
isLiveboardHeaderSticky: false,
});
appEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isLiveboardHeaderSticky=false${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('Should add isLiveboardCompactHeaderEnabled flag to the iframe src', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
isLiveboardCompactHeaderEnabled: false,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isLiveboardHeaderV2Enabled=false${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('Should add showLiveboardReverifyBanner flag to the iframe src', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
showLiveboardReverifyBanner: false,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&showLiveboardReverifyBanner=false${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('Should add showLiveboardVerifiedBadge flag to the iframe src', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
showLiveboardVerifiedBadge: false,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&showLiveboardVerifiedBadge=false${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('Should add hideIrrelevantFiltersAtTabLevel flag to the iframe src', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
hideIrrelevantChipsInLiveboardTabs: true,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&hideIrrelevantFiltersAtTabLevel=true${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('should add coverAndFilterOptionInPDF flag and set value to true to the iframe src', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
coverAndFilterOptionInPDF: true,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&arePdfCoverFilterPageCheckboxesEnabled=true${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('should add coverAndFilterOptionInPDF flag and set value to false to the iframe src', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
coverAndFilterOptionInPDF: false,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&arePdfCoverFilterPageCheckboxesEnabled=false&${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('should not append runtime filters in URL if excludeRuntimeFiltersfromURL is true', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
vizId,
runtimeFilters: [
{
columnName: 'sales',
operator: RuntimeFilterOp.EQ,
values: [1000],
},
],
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParamsVizEmbed}#/embed/viz/${liveboardId}/${vizId}`);
});
});
test('Should not append runtime parameters in URL if excludeRuntimeParametersfromURL is true', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
vizId,
runtimeParameters: [
{
name: 'sales',
value: 1000,
},
],
excludeRuntimeParametersfromURL: true,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParamsVizEmbed}#/embed/viz/${liveboardId}/${vizId}`);
});
});
test('should append runtime filters in URL if excludeRuntimeFiltersfromURL is undefined', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
vizId,
runtimeFilters: [
{
columnName: 'sales',
operator: RuntimeFilterOp.EQ,
values: [1000],
},
],
});
liveboardEmbed.render();
const runtimeFilter = 'col1=sales&op1=EQ&val1=1000';
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParamsVizEmbed}&${runtimeFilter}#/embed/viz/${liveboardId}/${vizId}`);
});
});
test('should register event handler to adjust iframe height', async () => {
const onSpy = jest.spyOn(LiveboardEmbed.prototype, 'on');
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
fullHeight: true,
liveboardId,
vizId,
});
liveboardEmbed.render();
executeAfterWait(() => {
expect(onSpy).toHaveBeenCalledWith(EmbedEvent.EmbedHeight, expect.anything());
});
});
test('should not call setIFrameHeight if currentPath starts with "/embed/viz/"', () => {
const myObject = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
fullHeight: true,
liveboardId,
});
const spySetIFrameHeight = jest.spyOn(myObject, 'setIFrameHeight');
myObject.render();
myObject.setIframeHeightForNonEmbedLiveboard({
data: { currentPath: '/embed/viz/' },
type: 'Route',
});
// Assert that setIFrameHeight is not called
expect(spySetIFrameHeight).not.toHaveBeenCalled();
});
test('should not call setIFrameHeight if currentPath starts with "/embed/insights/viz/"', () => {
const myObject = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
fullHeight: true,
liveboardId,
});
const spySetIFrameHeight = jest.spyOn(myObject, 'setIFrameHeight');
myObject.render();
myObject.setIframeHeightForNonEmbedLiveboard({
data: { currentPath: '/embed/insights/viz/' },
type: 'Route',
});
// Assert that setIFrameHeight is not called
expect(spySetIFrameHeight).not.toHaveBeenCalled();
});
test('should call setIFrameHeight if currentPath starts with "/some/other/path/"', () => {
const myObject = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
fullHeight: true,
liveboardId,
});
const spySetIFrameHeight = jest
.spyOn(myObject, 'setIFrameHeight')
.mockImplementation(jest.fn());
myObject.render();
myObject.setIframeHeightForNonEmbedLiveboard({
data: { currentPath: '/some/other/path/' },
type: 'Route',
});
// Assert that setIFrameHeight is not called
expect(spySetIFrameHeight).toHaveBeenCalled();
});
test('Should set the visible vizs', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
visibleVizs: ['abcd', 'pqrs'],
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&pinboardVisibleVizs=[%22abcd%22,%22pqrs%22]${prefixParams}#/embed/viz/${liveboardId}`);
});
});
test('should process the trigger, for vizEmbed', async () => {
const mockProcessTrigger = spyOn(processTriggerInstance, 'processTrigger');
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
enableVizTransformations: true,
...defaultViewConfig,
vizId: '1234',
liveboardId,
});
liveboardEmbed.render();
await executeAfterWait(async () => {
await liveboardEmbed.trigger(HostEvent.Pin);
expect(mockProcessTrigger).toBeCalled();
});
});
test('should render active tab when activeTab present', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
liveboardId,
activeTabId,
liveboardV2: true,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isLiveboardEmbed=true&isPinboardV2Enabled=true#/embed/viz/${liveboardId}/tab/${activeTabId}`);
});
});
test('Should set liveboard options', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
liveboardId,
activeTabId,
liveboardV2: true,
defaultHeight: 100,
preventLiveboardFilterRemoval: true,
enableAskSage: true,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&preventPinboardFilterRemoval=true&isLiveboardEmbed=true&isPinboardV2Enabled=true&enableAskSage=true#/embed/viz/${liveboardId}/tab/${activeTabId}`);
});
});
test('Should set contextMenuTrigger options', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
liveboardId,
activeTabId,
liveboardV2: true,
contextMenuTrigger: ContextMenuTriggerOptions.LEFT_CLICK,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&contextMenuEnabledOnWhichClick=left&isLiveboardEmbed=true&isPinboardV2Enabled=true#/embed/viz/${liveboardId}/tab/${activeTabId}`);
});
});
test('Should set hideTabPanel option', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
liveboardId,
activeTabId,
liveboardV2: true,
hideTabPanel: true,
});
liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&hideTabPanel=true&isLiveboardEmbed=true&isPinboardV2Enabled=true#/embed/viz/${liveboardId}/tab/${activeTabId}`);
});
});
test('navigateToLiveboard should trigger the navigate event with the correct path', async (done) => {
mockMessageChannel();
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
});
const onSpy = jest.spyOn(liveboardEmbed, 'trigger');
await liveboardEmbed.prerenderGeneric();
executeAfterWait(() => {
const iframe = getIFrameEl();
postMessageToParent(iframe.contentWindow, {
type: EmbedEvent.APP_INIT,
});
});
executeAfterWait(() => {
liveboardEmbed.navigateToLiveboard('lb1', 'viz1');
expect(onSpy).toHaveBeenCalledWith(HostEvent.Navigate, 'embed/viz/lb1/viz1');
done();
});
});
test('navigateToLiveboard with preRender', async (done) => {
mockMessageChannel();
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
preRenderId: 'test',
});
const onSpy = jest.spyOn(liveboardEmbed, 'trigger');
await liveboardEmbed.prerenderGeneric();
executeAfterWait(() => {
const iframe = getIFrameEl();
postMessageToParent(iframe.contentWindow, {
type: EmbedEvent.APP_INIT,
});
});
executeAfterWait(() => {
liveboardEmbed.navigateToLiveboard('lb1', 'viz1');
expect(onSpy).toHaveBeenCalledWith(HostEvent.Navigate, 'embed/viz/lb1/viz1');
done();
});
});
test('should set runtime parametere values in url params', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
runtimeParameters: [
{
name: 'Integer Date Range',
value: 1,
},
],
});
await liveboardEmbed.render();
await executeAfterWait(() => {
expectUrlMatchesWithParams(getIFrameSrc(), `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}¶m1=Integer%20Date%20Range¶mVal1=1#/embed/viz/${liveboardId}`);
});
});
test('SetActiveTab Hostevent should not trigger the navigate event with the correct path, for vizEmbed', async () => {
const mockProcessTrigger = jest.spyOn(tsEmbed.TsEmbed.prototype, 'trigger');
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
enableVizTransformations: true,
...defaultViewConfig,
liveboardId,
vizId,
});
liveboardEmbed.render();
executeAfterWait(() => {
const result = liveboardEmbed.trigger(HostEvent.SetActiveTab, {
tabId: newActiveTabId,
});
expect(mockProcessTrigger).not.toBeCalled();
});
});
test('SetActiveTab Hostevent trigger the navigate event with the correct path, not vizEmbed', async () => {
const mockProcessTrigger = jest.spyOn(tsEmbed.TsEmbed.prototype, 'trigger');
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
enableVizTransformations: true,
...defaultViewConfig,
liveboardId,
});
await liveboardEmbed.render();
await executeAfterWait(() => {
const result = liveboardEmbed.trigger(HostEvent.SetActiveTab, {
tabId: newActiveTabId,
});
expect(mockProcessTrigger).toHaveBeenCalledWith(HostEvent.Navigate, `embed/viz/${liveboardId}/tab/${newActiveTabId}`);
});
});
describe('PreRender flow for liveboard embed', () => {
test('it should preRender generic with liveboard id is not passed', async (done) => {
const consoleSpy = jest.spyOn(console, 'error');
const libEmbed = new LiveboardEmbed(getRootEl(), {
preRenderId: 'testPreRender',
});
const prerenderGenericSpy = jest.spyOn(libEmbed, 'prerenderGeneric');
await libEmbed.preRender();
executeAfterWait(() => {
const iFrame = document.getElementById(libEmbed.getPreRenderIds().child);
// should render the generic link
expect(prerenderGenericSpy).toHaveBeenCalledTimes(1);
expect(iFrame.src).toMatch(/http:\/\/tshost\/.*&isLiveboardEmbed=true.*#$/);
expect(consoleSpy).toHaveBeenCalledTimes(0);
done();
});
});
test('Show preview loader should not show the loader if not viz embed or showPreviewLoader is false', async () => {
const libEmbed = new LiveboardEmbed(getRootEl(), {
liveboardId: '1234',
});
await libEmbed.render();
await executeAfterWait(() => {
expect(getRootEl().innerHTML).not.toContain('ts-viz-preview-loader');
});
});
test('get liveboard url value', async () => {
const libEmbed = new LiveboardEmbed(getRootEl(), {
liveboardId: '1234',
});
await libEmbed.render();
await executeAfterWait(() => {
const url = libEmbed.getLiveboardUrl();
expect(url).toEqual('http://tshost/#/pinboard/1234');
});
});
test('Show preview loader should show the loader if viz embed and showPreviewLoader is true', async () => {
jest.spyOn(previewService, 'getPreview').mockResolvedValue({
vizContent: '<div id=test>test</div>',
});
const libEmbed = new LiveboardEmbed(getRootEl(), {
liveboardId: '1234',
vizId: '5678',
showPreviewLoader: true,
});
await libEmbed.render();
expect(previewService.getPreview).toHaveBeenCalledWith('http://tshost', '5678', '1234');
await executeAfterWait(() => {
expect(getRootEl().style.position).toEqual('relative');
expect(getRootEl().innerHTML).toContain('<div class="ts-viz-preview-loader">');
expect(getRootEl().innerHTML).toContain('<div id="test">test</div>');
});
libEmbed.test__executeCallbacks(EmbedEvent.Data, {});
await executeAfterWait(() => {
expect(getRootEl().innerHTML).not.toContain('ts-viz-preview-loader');
});
});
test('it should navigateToLiveboard with liveboard id is not passed', async (done) => {
mockMessageChannel();
const consoleSpy = jest.spyOn(console, 'error');
const testPreRenderId = 'testPreRender';
const libEmbed = new LiveboardEmbed(getRootEl(), {
preRenderId: testPreRenderId,
});
let resizeObserverCb;
window.ResizeObserver =
window.ResizeObserver ||
jest.fn().mockImplementation((resizeObserverCbParam) => {
resizeObserverCb = resizeObserverCbParam;
return {
disconnect: jest.fn(),
observe: jest.fn(),
unobserve: jest.fn(),
};
});
await libEmbed.preRender();
await waitFor(() => !!getIFrameEl());
const ts = '__tsEmbed';
expect(document.getElementById(libEmbed.getPreRenderIds().wrapper)[ts]).toEqual(libEmbed);
const testLiveboardId = 'testLiveboardId';
const newLibEmbed = new LiveboardEmbed(getRootEl(), {
preRenderId: testPreRenderId,
liveboardId: testLiveboardId,
});
const navigateToLiveboardSpy = jest.spyOn(newLibEmbed, 'navigateToLiveboard');
await newLibEmbed.showPreRender();
executeAfterWait(() => {
const iFrame = document.getElementById(libEmbed.getPreRenderIds().child);
// should render the generic link
expect(navigateToLiveboardSpy).toHaveBeenCalledWith(testLiveboardId);
expect(iFrame.src).toMatch(/http:\/\/tshost\/.*&isLiveboardEmbed=true.*#$/);
expect(consoleSpy).toHaveBeenCalledTimes(0);
done();
});
});
});
describe('LazyLoadingForFullHeight functionality', () => {
let mockIFrame;
beforeEach(() => {
mockIFrame = document.createElement('iframe');
mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({
top: 100,
left: 150,
bottom: 600,
right: 800,
width: 650,
height: 500,
});
jest.spyOn(document, 'createElement').mockImplementation((tagName) => {
if (tagName === 'iframe') {
return mockIFrame;
}
return document.createElement(tagName);
});
});
afterEach(() => {
jest.restoreAllMocks();
});
test('should set lazyLoadingMargin parameter when provided', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
fullHeight: true,
lazyLoadingForFullHeight: true,
lazyLoadingMargin: '100px 0px',
});
await liveboardEmbed.render();
await executeAfterWait(() => {
const iframeSrc = getIFrameSrc();
expect(iframeSrc).toContain('isLazyLoadingForEmbedEnabled=true');
expect(iframeSrc).toContain('isFullHeightPinboard=true');
expect(iframeSrc).toContain('rootMarginForLazyLoad=100px%200px');
}, 100);
});
test('should set isLazyLoadingForEmbedEnabled=true when both fullHeight and lazyLoadingForFullHeight are enabled', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
fullHeight: true,
lazyLoadingForFullHeight: true,
});
await liveboardEmbed.render();
await executeAfterWait(() => {
const iframeSrc = getIFrameSrc();
expect(iframeSrc).toContain('isLazyLoadingForEmbedEnabled=true');
expect(iframeSrc).toContain('isFullHeightPinboard=true');
}, 100);
});
test('should not set lazyLoadingForEmbed when lazyLoadingForFullHeight is enabled but fullHeight is false', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
fullHeight: false,
lazyLoadingForFullHeight: true,
});
await liveboardEmbed.render();
await executeAfterWait(() => {
const iframeSrc = getIFrameSrc();
expect(iframeSrc).not.toContain('isLazyLoadingForEmbedEnabled=true');
expect(iframeSrc).not.toContain('isFullHeightPinboard=true');
}, 100);
});
test('should not set isLazyLoadingForEmbedEnabled when fullHeight is true but lazyLoadingForFullHeight is false', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
fullHeight: true,
lazyLoadingForFullHeight: false,
});
await liveboardEmbed.render();
await executeAfterWait(() => {
const iframeSrc = getIFrameSrc();
expect(iframeSrc).not.toContain('isLazyLoadingForEmbedEnabled=true');
expect(iframeSrc).toContain('isFullHeightPinboard=true');
}, 100);
});
test('should register event handlers to adjust iframe height', async () => {
const onSpy = jest.spyOn(LiveboardEmbed.prototype, 'on');
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
fullHeight: true,
lazyLoadingForFullHeight: true,
});
await liveboardEmbed.render();
await executeAfterWait(() => {
expect(onSpy).toHaveBeenCalledWith(EmbedEvent.EmbedHeight, expect.anything());
expect(onSpy).toHaveBeenCalledWith(EmbedEvent.RouteChange, expect.anything());
expect(onSpy).toHaveBeenCalledWith(EmbedEvent.EmbedIframeCenter, expect.anything());
expect(onSpy).toHaveBeenCalledWith(EmbedEvent.RequestVisibleEmbedCoordinates, expect.anything());
}, 100);
});
test('should send correct visible data when RequestVisibleEmbedCoordinates is triggered', async () => {
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
fullHeight: true,
lazyLoadingForFullHeight: true,
});
const mockTrigger = jest.spyOn(liveboardEmbed, 'trigger');
await liveboardEmbed.render();
// Trigger the lazy load data calculation
liveboardEmbed.sendFullHeightLazyLoadData();
expect(mockTrigger).toHaveBeenCalledWith(HostEvent.VisibleEmbedCoordinates, {
top: 0,
height: 500,
left: 0,
width: 650,
});
});
test('should calculate correct visible data for partially visible full height element', async () => {
mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({
top: -50,
left: -30,
bottom: 700,
right: 1024,
width: 1054,
height: 750,
});
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
fullHeight: true,
lazyLoadingForFullHeight: true,
});
const mockTrigger = jest.spyOn(liveboardEmbed, 'trigger');
await liveboardEmbed.render();
// Trigger the lazy load data calculation
liveboardEmbed.sendFullHeightLazyLoadData();
expect(mockTrigger).toHaveBeenCalledWith(HostEvent.VisibleEmbedCoordinates, {
top: 50,
height: 700,
left: 30,
width: 1024,
});
});
test('should add window event listeners for resize and scroll when fullHeight and lazyLoadingForFullHeight are enabled', async () => {
const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
fullHeight: true,
lazyLoadingForFullHeight: true,
});
await liveboardEmbed.render();
// Wait for the post-render events to be registered
await executeAfterWait(() => {
expect(addEventListenerSpy).toHaveBeenCalledWith('resize', expect.anything());
expect(addEventListenerSpy).toHaveBeenCalledWith('scroll', expect.anything(), true);
}, 100);
addEventListenerSpy.mockRestore();
});
test('should remove window event listeners on destroy when fullHeight and lazyLoadingForFullHeight are enabled', async () => {
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
fullHeight: true,
lazyLoadingForFullHeight: true,
});
await liveboardEmbed.render();
liveboardEmbed.destroy();
expect(removeEventListenerSpy).toHaveBeenCalledWith('resize', expect.anything());
expect(removeEventListenerSpy).toHaveBeenCalledWith('scroll', expect.anything());
removeEventListenerSpy.mockRestore();
});
test('should handle RequestVisibleEmbedCoordinates event and respond with correct data', async () => {
// Mock the iframe element
mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({
top: 100,
left: 150,
bottom: 600,
right: 800,
width: 650,
height: 500,
});
Object.defineProperty(mockIFrame, 'scrollHeight', { value: 500 });
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
...defaultViewConfig,
liveboardId,
fullHeight: true,
lazyLoadingForFullHeight: true,
});
// Set the iframe before render
liveboardEmbed.iFrame = mockIFrame;
await liveboardEmbed.render();
// Create a mock responder function
const mockResponder = jest.fn();
// Trigger the handler directly
liveboardEmbed.requestVisibleEmbedCoordinatesHandler({}, mockResponder);
// Verify the responder was called with the correct data
expect(mockResponder).toHaveBeenCalledWith({
type: EmbedEvent.RequestVisibleEmbedCoordinates,
data: {
top: 0,
height: 500,
left: 0,
width: 650,
},
});
});
});
describe('Host events for liveborad', () => {
test('Host event with empty param', async () => {
const mockProcessTrigger = jest.spyOn(tsEmbed.TsEmbed.prototype, 'trigger');
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
liveboardId: '123',
...defaultViewConfig,
vizId: 'testViz',
});
await liveboardEmbed.render();
mockProcessTrigger.mockResolvedValue({ session: 'test' });
await executeAfterWait(async () => {
await liveboardEmbed.trigger(HostEvent.Save);
expect(mockProcessTrigger).toHaveBeenCalledWith(HostEvent.Save, {
vizId: 'testViz',
});
});
});
});
});
//# sourceMappingURL=liveboard.spec.js.map