@thoughtspot/visual-embed-sdk 1.39.1 → 1.39.2-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/package.json +1 -1
- package/cjs/src/config.spec.js +9 -0
- package/cjs/src/config.spec.js.map +1 -1
- package/cjs/src/embed/app.d.ts +75 -15
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +69 -9
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +374 -12
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.d.ts +19 -7
- package/cjs/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/cjs/src/embed/bodyless-conversation.js +24 -4
- package/cjs/src/embed/bodyless-conversation.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.spec.js +8 -190
- package/cjs/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/cjs/src/embed/conversation.spec.js +28 -0
- package/cjs/src/embed/conversation.spec.js.map +1 -1
- package/cjs/src/embed/embedConfig.d.ts +9 -7
- package/cjs/src/embed/embedConfig.d.ts.map +1 -1
- package/cjs/src/embed/embedConfig.js +9 -7
- package/cjs/src/embed/embedConfig.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +56 -17
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +48 -4
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +215 -11
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +5 -0
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +16 -1
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +164 -0
- 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 +2 -2
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +2 -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 +3 -2
- package/cjs/src/react/all-types-export.js.map +1 -1
- package/cjs/src/react/index.d.ts +71 -20
- package/cjs/src/react/index.d.ts.map +1 -1
- package/cjs/src/react/index.js +79 -42
- package/cjs/src/react/index.js.map +1 -1
- package/cjs/src/react/index.spec.js +436 -100
- package/cjs/src/react/index.spec.js.map +1 -1
- package/cjs/src/types.d.ts +80 -6
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +45 -1
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
- package/cjs/src/utils/graphql/nlsService/conversation-service.js +2 -0
- package/cjs/src/utils/graphql/nlsService/conversation-service.js.map +1 -1
- package/cjs/src/utils/processTrigger.js +2 -1
- package/cjs/src/utils/processTrigger.js.map +1 -1
- package/cjs/src/utils.d.ts +6 -0
- package/cjs/src/utils.d.ts.map +1 -1
- package/cjs/src/utils.js +23 -3
- package/cjs/src/utils.js.map +1 -1
- package/cjs/src/utils.spec.js +237 -1
- package/cjs/src/utils.spec.js.map +1 -1
- package/dist/{index-JaFaxrvQ.js → index-CmEQfuE3.js} +1 -1
- package/dist/index-DeFzsyFF.js +7371 -0
- package/dist/index-Dpf0rd6w.js +7371 -0
- package/dist/index-UuEbsISo.js +7447 -0
- package/dist/index-e3Uw3YFO.js +7371 -0
- package/dist/src/embed/app.d.ts +75 -15
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/bodyless-conversation.d.ts +19 -7
- package/dist/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/dist/src/embed/embedConfig.d.ts +9 -7
- package/dist/src/embed/embedConfig.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +56 -17
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +5 -0
- 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 +2 -2
- 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/react/index.d.ts +71 -20
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/types.d.ts +80 -6
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
- package/dist/src/utils.d.ts +6 -0
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +320 -78
- package/dist/tsembed-react.js +320 -76
- package/dist/tsembed.es.js +238 -31
- package/dist/tsembed.js +236 -29
- package/dist/visual-embed-sdk-react-full.d.ts +288 -72
- package/dist/visual-embed-sdk-react.d.ts +288 -72
- package/dist/visual-embed-sdk.d.ts +218 -53
- package/lib/package.json +1 -1
- package/lib/src/config.spec.js +9 -0
- package/lib/src/config.spec.js.map +1 -1
- package/lib/src/embed/app.d.ts +75 -15
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +69 -9
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +376 -14
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.d.ts +19 -7
- package/lib/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/lib/src/embed/bodyless-conversation.js +23 -4
- package/lib/src/embed/bodyless-conversation.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.spec.js +9 -191
- package/lib/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/lib/src/embed/conversation.spec.js +30 -2
- package/lib/src/embed/conversation.spec.js.map +1 -1
- package/lib/src/embed/embedConfig.d.ts +9 -7
- package/lib/src/embed/embedConfig.d.ts.map +1 -1
- package/lib/src/embed/embedConfig.js +9 -7
- package/lib/src/embed/embedConfig.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +56 -17
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +49 -5
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +215 -11
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +5 -0
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +16 -1
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +164 -0
- 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 +2 -2
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +2 -2
- 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/react/index.d.ts +71 -20
- package/lib/src/react/index.d.ts.map +1 -1
- package/lib/src/react/index.js +79 -43
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/react/index.spec.js +439 -103
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/types.d.ts +80 -6
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +45 -1
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
- package/lib/src/utils/graphql/nlsService/conversation-service.js +2 -0
- package/lib/src/utils/graphql/nlsService/conversation-service.js.map +1 -1
- package/lib/src/utils/processTrigger.js +2 -1
- package/lib/src/utils/processTrigger.js.map +1 -1
- package/lib/src/utils.d.ts +6 -0
- package/lib/src/utils.d.ts.map +1 -1
- package/lib/src/utils.js +21 -2
- package/lib/src/utils.js.map +1 -1
- package/lib/src/utils.spec.js +238 -2
- package/lib/src/utils.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +219 -54
- package/package.json +1 -1
- package/src/config.spec.ts +11 -0
- package/src/embed/app.spec.ts +479 -26
- package/src/embed/app.ts +133 -27
- package/src/embed/bodyless-conversation.spec.ts +9 -203
- package/src/embed/bodyless-conversation.ts +24 -10
- package/src/embed/conversation.spec.ts +40 -2
- package/src/embed/embedConfig.ts +10 -8
- package/src/embed/liveboard.spec.ts +256 -5
- package/src/embed/liveboard.ts +99 -27
- package/src/embed/ts-embed.spec.ts +225 -0
- package/src/embed/ts-embed.ts +19 -0
- package/src/errors.ts +1 -0
- package/src/index.ts +2 -0
- package/src/react/all-types-export.ts +2 -1
- package/src/react/index.spec.tsx +556 -157
- package/src/react/index.tsx +117 -51
- package/src/types.ts +117 -43
- package/src/utils/graphql/nlsService/conversation-service.ts +2 -0
- package/src/utils/processTrigger.ts +1 -1
- package/src/utils.spec.ts +279 -2
- package/src/utils.ts +28 -2
package/src/embed/app.spec.ts
CHANGED
|
@@ -6,11 +6,10 @@ import {
|
|
|
6
6
|
HomePageSearchBarMode,
|
|
7
7
|
PrimaryNavbarVersion,
|
|
8
8
|
HomePage,
|
|
9
|
+
ListPage,
|
|
9
10
|
} from './app';
|
|
10
11
|
import { init } from '../index';
|
|
11
|
-
import {
|
|
12
|
-
Action, AuthType, EmbedEvent, HostEvent, RuntimeFilterOp,
|
|
13
|
-
} from '../types';
|
|
12
|
+
import { Action, AuthType, EmbedEvent, HostEvent, RuntimeFilterOp } from '../types';
|
|
14
13
|
import {
|
|
15
14
|
executeAfterWait,
|
|
16
15
|
getDocumentBody,
|
|
@@ -45,12 +44,13 @@ beforeAll(() => {
|
|
|
45
44
|
authType: AuthType.None,
|
|
46
45
|
});
|
|
47
46
|
jest.spyOn(auth, 'postLoginService').mockImplementation(() => Promise.resolve({}));
|
|
48
|
-
(window as any).ResizeObserver =
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
(window as any).ResizeObserver =
|
|
48
|
+
window.ResizeObserver ||
|
|
49
|
+
jest.fn().mockImplementation(() => ({
|
|
50
|
+
disconnect: jest.fn(),
|
|
51
|
+
observe: jest.fn(),
|
|
52
|
+
unobserve: jest.fn(),
|
|
53
|
+
}));
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
const cleanUp = () => {
|
|
@@ -316,6 +316,20 @@ describe('App embed tests', () => {
|
|
|
316
316
|
});
|
|
317
317
|
});
|
|
318
318
|
|
|
319
|
+
test('should set coverAndFilterOptionInPDF to false in url', async () => {
|
|
320
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
321
|
+
...defaultViewConfig,
|
|
322
|
+
coverAndFilterOptionInPDF: false,
|
|
323
|
+
} as AppViewConfig);
|
|
324
|
+
appEmbed.render();
|
|
325
|
+
await executeAfterWait(() => {
|
|
326
|
+
expectUrlMatchesWithParams(
|
|
327
|
+
getIFrameSrc(),
|
|
328
|
+
`http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&arePdfCoverFilterPageCheckboxesEnabled=false${defaultParamsPost}#/home`,
|
|
329
|
+
);
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
|
|
319
333
|
test('should set isLiveboardStylingAndGroupingEnabled to true in url', async () => {
|
|
320
334
|
const appEmbed = new AppEmbed(getRootEl(), {
|
|
321
335
|
...defaultViewConfig,
|
|
@@ -611,6 +625,59 @@ describe('App embed tests', () => {
|
|
|
611
625
|
});
|
|
612
626
|
});
|
|
613
627
|
|
|
628
|
+
test('Should add listpageVersion=v3 when listPageVersion is ListWithUXChanges to the iframe src', async () => {
|
|
629
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
630
|
+
...defaultViewConfig,
|
|
631
|
+
discoveryExperience: {
|
|
632
|
+
listPageVersion: ListPage.ListWithUXChanges,
|
|
633
|
+
},
|
|
634
|
+
} as AppViewConfig);
|
|
635
|
+
|
|
636
|
+
appEmbed.render();
|
|
637
|
+
await executeAfterWait(() => {
|
|
638
|
+
expectUrlMatchesWithParams(
|
|
639
|
+
getIFrameSrc(),
|
|
640
|
+
`http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false&modularHomeExperience=false&listpageVersion=v3${defaultParams}${defaultParamsPost}#/home`,
|
|
641
|
+
);
|
|
642
|
+
});
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
test('Should not add listpageVersion when listPageVersion is List (v2) to the iframe src', async () => {
|
|
646
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
647
|
+
...defaultViewConfig,
|
|
648
|
+
discoveryExperience: {
|
|
649
|
+
listPageVersion: ListPage.List,
|
|
650
|
+
},
|
|
651
|
+
} as AppViewConfig);
|
|
652
|
+
|
|
653
|
+
appEmbed.render();
|
|
654
|
+
await executeAfterWait(() => {
|
|
655
|
+
expectUrlMatchesWithParams(
|
|
656
|
+
getIFrameSrc(),
|
|
657
|
+
`http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false&modularHomeExperience=false${defaultParams}${defaultParamsPost}#/home`,
|
|
658
|
+
);
|
|
659
|
+
});
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
test('Should add listpageVersion=v3 combined with other discoveryExperience options to the iframe src', async () => {
|
|
663
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
664
|
+
...defaultViewConfig,
|
|
665
|
+
discoveryExperience: {
|
|
666
|
+
primaryNavbarVersion: PrimaryNavbarVersion.Sliding,
|
|
667
|
+
homePage: HomePage.Modular,
|
|
668
|
+
listPageVersion: ListPage.ListWithUXChanges,
|
|
669
|
+
},
|
|
670
|
+
} as AppViewConfig);
|
|
671
|
+
|
|
672
|
+
appEmbed.render();
|
|
673
|
+
await executeAfterWait(() => {
|
|
674
|
+
expectUrlMatchesWithParams(
|
|
675
|
+
getIFrameSrc(),
|
|
676
|
+
`http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false&modularHomeExperience=true&navigationVersion=v3&listpageVersion=v3${defaultParams}${defaultParamsPost}#/home`,
|
|
677
|
+
);
|
|
678
|
+
});
|
|
679
|
+
});
|
|
680
|
+
|
|
614
681
|
test('Should add enablePendoHelp flag to the iframe src conditional on navbar', async () => {
|
|
615
682
|
const appEmbed = new AppEmbed(getRootEl(), {
|
|
616
683
|
...defaultViewConfig,
|
|
@@ -687,7 +754,8 @@ describe('App embed tests', () => {
|
|
|
687
754
|
const appEmbed = new AppEmbed(getRootEl(), {
|
|
688
755
|
...defaultViewConfig,
|
|
689
756
|
// eslint-disable-next-line max-len
|
|
690
|
-
dataPanelCustomGroupsAccordionInitialState:
|
|
757
|
+
dataPanelCustomGroupsAccordionInitialState:
|
|
758
|
+
DataPanelCustomColumnGroupsAccordionState.EXPAND_FIRST,
|
|
691
759
|
} as AppViewConfig);
|
|
692
760
|
|
|
693
761
|
appEmbed.render();
|
|
@@ -700,34 +768,41 @@ describe('App embed tests', () => {
|
|
|
700
768
|
});
|
|
701
769
|
|
|
702
770
|
test('should register event handlers to adjust iframe height', async () => {
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
771
|
+
let embedHeightCallback: any = () => {};
|
|
772
|
+
const onSpy = jest.spyOn(AppEmbed.prototype, 'on').mockImplementation((event, callback) => {
|
|
773
|
+
if (event === EmbedEvent.RouteChange) {
|
|
774
|
+
callback({ data: { currentPath: '/answers' } }, jest.fn());
|
|
775
|
+
}
|
|
776
|
+
if (event === EmbedEvent.EmbedHeight) {
|
|
777
|
+
embedHeightCallback = callback;
|
|
778
|
+
}
|
|
779
|
+
if (event === EmbedEvent.EmbedIframeCenter) {
|
|
780
|
+
callback({}, jest.fn());
|
|
781
|
+
}
|
|
782
|
+
return null;
|
|
783
|
+
});
|
|
716
784
|
jest.spyOn(TsEmbed.prototype as any, 'getIframeCenter').mockReturnValue({});
|
|
717
785
|
jest.spyOn(TsEmbed.prototype as any, 'setIFrameHeight').mockReturnValue({});
|
|
718
786
|
const appEmbed = new AppEmbed(getRootEl(), {
|
|
719
787
|
...defaultViewConfig,
|
|
720
788
|
fullHeight: true,
|
|
789
|
+
lazyLoadingForFullHeight: true,
|
|
721
790
|
} as AppViewConfig);
|
|
722
791
|
|
|
723
|
-
|
|
792
|
+
// Set the iframe before render
|
|
793
|
+
(appEmbed as any).iFrame = document.createElement('iframe');
|
|
794
|
+
|
|
795
|
+
// Wait for render to complete
|
|
796
|
+
await appEmbed.render();
|
|
797
|
+
embedHeightCallback({ data: '100%' });
|
|
724
798
|
|
|
799
|
+
// Verify event handlers were registered
|
|
725
800
|
await executeAfterWait(() => {
|
|
726
801
|
expect(onSpy).toHaveBeenCalledWith(EmbedEvent.EmbedHeight, expect.anything());
|
|
727
802
|
expect(onSpy).toHaveBeenCalledWith(EmbedEvent.RouteChange, expect.anything());
|
|
728
803
|
expect(onSpy).toHaveBeenCalledWith(EmbedEvent.EmbedIframeCenter, expect.anything());
|
|
729
|
-
|
|
730
|
-
|
|
804
|
+
expect(onSpy).toHaveBeenCalledWith(EmbedEvent.RequestVisibleEmbedCoordinates, expect.anything());
|
|
805
|
+
}, 100);
|
|
731
806
|
});
|
|
732
807
|
|
|
733
808
|
describe('Navigate to Page API', () => {
|
|
@@ -815,4 +890,382 @@ describe('App embed tests', () => {
|
|
|
815
890
|
);
|
|
816
891
|
});
|
|
817
892
|
});
|
|
893
|
+
|
|
894
|
+
describe('LazyLoadingForFullHeight functionality', () => {
|
|
895
|
+
let mockIFrame: HTMLIFrameElement;
|
|
896
|
+
|
|
897
|
+
beforeEach(() => {
|
|
898
|
+
mockIFrame = document.createElement('iframe');
|
|
899
|
+
mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({
|
|
900
|
+
top: 100,
|
|
901
|
+
left: 150,
|
|
902
|
+
bottom: 600,
|
|
903
|
+
right: 800,
|
|
904
|
+
width: 650,
|
|
905
|
+
height: 500,
|
|
906
|
+
});
|
|
907
|
+
jest.spyOn(document, 'createElement').mockImplementation((tagName) => {
|
|
908
|
+
if (tagName === 'iframe') {
|
|
909
|
+
return mockIFrame;
|
|
910
|
+
}
|
|
911
|
+
return document.createElement(tagName);
|
|
912
|
+
});
|
|
913
|
+
});
|
|
914
|
+
|
|
915
|
+
afterEach(() => {
|
|
916
|
+
jest.restoreAllMocks();
|
|
917
|
+
});
|
|
918
|
+
|
|
919
|
+
test('should set lazyLoadingMargin parameter when provided', async () => {
|
|
920
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
921
|
+
...defaultViewConfig,
|
|
922
|
+
fullHeight: true,
|
|
923
|
+
lazyLoadingForFullHeight: true,
|
|
924
|
+
lazyLoadingMargin: '100px 0px',
|
|
925
|
+
} as AppViewConfig);
|
|
926
|
+
|
|
927
|
+
await appEmbed.render();
|
|
928
|
+
|
|
929
|
+
await executeAfterWait(() => {
|
|
930
|
+
const iframeSrc = getIFrameSrc();
|
|
931
|
+
expect(iframeSrc).toContain('isLazyLoadingForEmbedEnabled=true');
|
|
932
|
+
expect(iframeSrc).toContain('isFullHeightPinboard=true');
|
|
933
|
+
expect(iframeSrc).toContain('rootMarginForLazyLoad=100px%200px');
|
|
934
|
+
}, 100);
|
|
935
|
+
});
|
|
936
|
+
|
|
937
|
+
test('should set isLazyLoadingForEmbedEnabled=true when both fullHeight and lazyLoadingForFullHeight are enabled', async () => {
|
|
938
|
+
// Mock the iframe element first
|
|
939
|
+
mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({
|
|
940
|
+
top: 100,
|
|
941
|
+
left: 150,
|
|
942
|
+
bottom: 600,
|
|
943
|
+
right: 800,
|
|
944
|
+
width: 650,
|
|
945
|
+
height: 500,
|
|
946
|
+
});
|
|
947
|
+
Object.defineProperty(mockIFrame, 'scrollHeight', { value: 500 });
|
|
948
|
+
|
|
949
|
+
// Mock the event handlers
|
|
950
|
+
const onSpy = jest.spyOn(AppEmbed.prototype, 'on').mockImplementation((event, callback) => {
|
|
951
|
+
return null;
|
|
952
|
+
});
|
|
953
|
+
jest.spyOn(TsEmbed.prototype as any, 'getIframeCenter').mockReturnValue({});
|
|
954
|
+
jest.spyOn(TsEmbed.prototype as any, 'setIFrameHeight').mockReturnValue({});
|
|
955
|
+
|
|
956
|
+
// Create the AppEmbed instance
|
|
957
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
958
|
+
...defaultViewConfig,
|
|
959
|
+
fullHeight: true,
|
|
960
|
+
lazyLoadingForFullHeight: true,
|
|
961
|
+
} as AppViewConfig);
|
|
962
|
+
|
|
963
|
+
// Set the iframe before render
|
|
964
|
+
(appEmbed as any).iFrame = mockIFrame;
|
|
965
|
+
|
|
966
|
+
// Add the iframe to the DOM
|
|
967
|
+
const rootEl = getRootEl();
|
|
968
|
+
rootEl.appendChild(mockIFrame);
|
|
969
|
+
|
|
970
|
+
// Wait for render to complete
|
|
971
|
+
await appEmbed.render();
|
|
972
|
+
|
|
973
|
+
// Wait for iframe initialization and URL parameters to be set
|
|
974
|
+
await executeAfterWait(() => {
|
|
975
|
+
const iframeSrc = appEmbed.getIFrameSrc();
|
|
976
|
+
expect(iframeSrc).toContain('isLazyLoadingForEmbedEnabled=true');
|
|
977
|
+
expect(iframeSrc).toContain('isFullHeightPinboard=true');
|
|
978
|
+
}, 100);
|
|
979
|
+
});
|
|
980
|
+
|
|
981
|
+
test('should not set lazyLoadingForEmbed when lazyLoadingForFullHeight is enabled but fullHeight is false', async () => {
|
|
982
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
983
|
+
...defaultViewConfig,
|
|
984
|
+
fullHeight: false,
|
|
985
|
+
lazyLoadingForFullHeight: true,
|
|
986
|
+
} as AppViewConfig);
|
|
987
|
+
|
|
988
|
+
// Wait for render to complete
|
|
989
|
+
await appEmbed.render();
|
|
990
|
+
|
|
991
|
+
// Wait for iframe initialization and URL parameters to be set
|
|
992
|
+
await executeAfterWait(() => {
|
|
993
|
+
const iframeSrc = getIFrameSrc();
|
|
994
|
+
expect(iframeSrc).not.toContain('isLazyLoadingForEmbedEnabled=true');
|
|
995
|
+
expect(iframeSrc).not.toContain('isFullHeightPinboard=true');
|
|
996
|
+
}, 100); // 100ms wait time to ensure iframe src is set
|
|
997
|
+
});
|
|
998
|
+
|
|
999
|
+
test('should not set isLazyLoadingForEmbedEnabled when fullHeight is true but lazyLoadingForFullHeight is false', async () => {
|
|
1000
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
1001
|
+
...defaultViewConfig,
|
|
1002
|
+
fullHeight: true,
|
|
1003
|
+
lazyLoadingForFullHeight: false,
|
|
1004
|
+
} as AppViewConfig);
|
|
1005
|
+
|
|
1006
|
+
// Wait for render to complete
|
|
1007
|
+
await appEmbed.render();
|
|
1008
|
+
|
|
1009
|
+
// Wait for iframe initialization and URL parameters to be set
|
|
1010
|
+
await executeAfterWait(() => {
|
|
1011
|
+
const iframeSrc = getIFrameSrc();
|
|
1012
|
+
expect(iframeSrc).not.toContain('isLazyLoadingForEmbedEnabled=true');
|
|
1013
|
+
expect(iframeSrc).toContain('isFullHeightPinboard=true');
|
|
1014
|
+
}, 100); // 100ms wait time to ensure iframe src is set
|
|
1015
|
+
});
|
|
1016
|
+
|
|
1017
|
+
test('should register RequestFullHeightLazyLoadData event handler when fullHeight is enabled', async () => {
|
|
1018
|
+
const onSpy = jest.spyOn(AppEmbed.prototype, 'on');
|
|
1019
|
+
|
|
1020
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
1021
|
+
...defaultViewConfig,
|
|
1022
|
+
fullHeight: true,
|
|
1023
|
+
} as AppViewConfig);
|
|
1024
|
+
|
|
1025
|
+
await appEmbed.render();
|
|
1026
|
+
|
|
1027
|
+
expect(onSpy).toHaveBeenCalledWith(EmbedEvent.RequestVisibleEmbedCoordinates, expect.any(Function));
|
|
1028
|
+
|
|
1029
|
+
onSpy.mockRestore();
|
|
1030
|
+
});
|
|
1031
|
+
|
|
1032
|
+
test('should send correct visible data when RequestFullHeightLazyLoadData is triggered', async () => {
|
|
1033
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
1034
|
+
...defaultViewConfig,
|
|
1035
|
+
fullHeight: true,
|
|
1036
|
+
lazyLoadingForFullHeight: true,
|
|
1037
|
+
} as AppViewConfig);
|
|
1038
|
+
|
|
1039
|
+
const mockTrigger = jest.spyOn(appEmbed, 'trigger');
|
|
1040
|
+
|
|
1041
|
+
await appEmbed.render();
|
|
1042
|
+
|
|
1043
|
+
// Trigger the lazy load data calculation
|
|
1044
|
+
(appEmbed as any).sendFullHeightLazyLoadData();
|
|
1045
|
+
|
|
1046
|
+
expect(mockTrigger).toHaveBeenCalledWith(HostEvent.VisibleEmbedCoordinates, {
|
|
1047
|
+
top: 0,
|
|
1048
|
+
height: 500,
|
|
1049
|
+
left: 0,
|
|
1050
|
+
width: 650,
|
|
1051
|
+
});
|
|
1052
|
+
});
|
|
1053
|
+
|
|
1054
|
+
test('should calculate correct visible data for partially visible full height element', async () => {
|
|
1055
|
+
// Mock iframe partially clipped from top and left
|
|
1056
|
+
mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({
|
|
1057
|
+
top: -50,
|
|
1058
|
+
left: -30,
|
|
1059
|
+
bottom: 700,
|
|
1060
|
+
right: 1024,
|
|
1061
|
+
width: 1054,
|
|
1062
|
+
height: 750,
|
|
1063
|
+
});
|
|
1064
|
+
|
|
1065
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
1066
|
+
...defaultViewConfig,
|
|
1067
|
+
fullHeight: true,
|
|
1068
|
+
lazyLoadingForFullHeight: true,
|
|
1069
|
+
} as AppViewConfig);
|
|
1070
|
+
|
|
1071
|
+
const mockTrigger = jest.spyOn(appEmbed, 'trigger');
|
|
1072
|
+
|
|
1073
|
+
await appEmbed.render();
|
|
1074
|
+
|
|
1075
|
+
// Trigger the lazy load data calculation
|
|
1076
|
+
(appEmbed as any).sendFullHeightLazyLoadData();
|
|
1077
|
+
|
|
1078
|
+
expect(mockTrigger).toHaveBeenCalledWith(HostEvent.VisibleEmbedCoordinates, {
|
|
1079
|
+
top: 50, // 50px clipped from top
|
|
1080
|
+
height: 700, // visible height (from 0 to 700)
|
|
1081
|
+
left: 30, // 30px clipped from left
|
|
1082
|
+
width: 1024, // visible width (from 0 to 1024)
|
|
1083
|
+
});
|
|
1084
|
+
});
|
|
1085
|
+
|
|
1086
|
+
test('should add window event listeners for resize and scroll when fullHeight and lazyLoadingForFullHeight are enabled', async () => {
|
|
1087
|
+
const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
|
|
1088
|
+
|
|
1089
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
1090
|
+
...defaultViewConfig,
|
|
1091
|
+
fullHeight: true,
|
|
1092
|
+
lazyLoadingForFullHeight: true,
|
|
1093
|
+
} as AppViewConfig);
|
|
1094
|
+
|
|
1095
|
+
await appEmbed.render();
|
|
1096
|
+
|
|
1097
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('resize', expect.any(Function));
|
|
1098
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('scroll', expect.any(Function));
|
|
1099
|
+
|
|
1100
|
+
addEventListenerSpy.mockRestore();
|
|
1101
|
+
});
|
|
1102
|
+
|
|
1103
|
+
test('should remove window event listeners on destroy when fullHeight and lazyLoadingForFullHeight are enabled', async () => {
|
|
1104
|
+
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
|
|
1105
|
+
|
|
1106
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
1107
|
+
...defaultViewConfig,
|
|
1108
|
+
fullHeight: true,
|
|
1109
|
+
lazyLoadingForFullHeight: true,
|
|
1110
|
+
} as AppViewConfig);
|
|
1111
|
+
|
|
1112
|
+
await appEmbed.render();
|
|
1113
|
+
appEmbed.destroy();
|
|
1114
|
+
|
|
1115
|
+
expect(removeEventListenerSpy).toHaveBeenCalledWith('resize', expect.any(Function));
|
|
1116
|
+
expect(removeEventListenerSpy).toHaveBeenCalledWith('scroll', expect.any(Function));
|
|
1117
|
+
|
|
1118
|
+
removeEventListenerSpy.mockRestore();
|
|
1119
|
+
});
|
|
1120
|
+
|
|
1121
|
+
test('should handle RequestVisibleEmbedCoordinates event and respond with correct data', async () => {
|
|
1122
|
+
// Mock the iframe element
|
|
1123
|
+
mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({
|
|
1124
|
+
top: 100,
|
|
1125
|
+
left: 150,
|
|
1126
|
+
bottom: 600,
|
|
1127
|
+
right: 800,
|
|
1128
|
+
width: 650,
|
|
1129
|
+
height: 500,
|
|
1130
|
+
});
|
|
1131
|
+
Object.defineProperty(mockIFrame, 'scrollHeight', { value: 500 });
|
|
1132
|
+
|
|
1133
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
1134
|
+
...defaultViewConfig,
|
|
1135
|
+
fullHeight: true,
|
|
1136
|
+
lazyLoadingForFullHeight: true,
|
|
1137
|
+
} as AppViewConfig);
|
|
1138
|
+
|
|
1139
|
+
// Set the iframe before render
|
|
1140
|
+
(appEmbed as any).iFrame = mockIFrame;
|
|
1141
|
+
|
|
1142
|
+
await appEmbed.render();
|
|
1143
|
+
|
|
1144
|
+
// Create a mock responder function
|
|
1145
|
+
const mockResponder = jest.fn();
|
|
1146
|
+
|
|
1147
|
+
// Trigger the handler directly
|
|
1148
|
+
(appEmbed as any).requestVisibleEmbedCoordinatesHandler({}, mockResponder);
|
|
1149
|
+
|
|
1150
|
+
// Verify the responder was called with the correct data
|
|
1151
|
+
expect(mockResponder).toHaveBeenCalledWith({
|
|
1152
|
+
type: EmbedEvent.RequestVisibleEmbedCoordinates,
|
|
1153
|
+
data: {
|
|
1154
|
+
top: 0,
|
|
1155
|
+
height: 500,
|
|
1156
|
+
left: 0,
|
|
1157
|
+
width: 650,
|
|
1158
|
+
},
|
|
1159
|
+
});
|
|
1160
|
+
});
|
|
1161
|
+
});
|
|
1162
|
+
|
|
1163
|
+
describe('IFrame height management', () => {
|
|
1164
|
+
let mockIFrame: HTMLIFrameElement;
|
|
1165
|
+
|
|
1166
|
+
beforeEach(() => {
|
|
1167
|
+
mockIFrame = document.createElement('iframe');
|
|
1168
|
+
mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({
|
|
1169
|
+
top: 100,
|
|
1170
|
+
left: 150,
|
|
1171
|
+
bottom: 600,
|
|
1172
|
+
right: 800,
|
|
1173
|
+
width: 650,
|
|
1174
|
+
height: 500,
|
|
1175
|
+
});
|
|
1176
|
+
Object.defineProperty(mockIFrame, 'scrollHeight', { value: 500 });
|
|
1177
|
+
});
|
|
1178
|
+
|
|
1179
|
+
test('should not call setIFrameHeight if currentPath starts with "/embed/viz/"', () => {
|
|
1180
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
1181
|
+
...defaultViewConfig,
|
|
1182
|
+
fullHeight: true,
|
|
1183
|
+
} as AppViewConfig) as any;
|
|
1184
|
+
const spySetIFrameHeight = jest.spyOn(appEmbed, 'setIFrameHeight');
|
|
1185
|
+
|
|
1186
|
+
appEmbed.render();
|
|
1187
|
+
appEmbed.setIframeHeightForNonEmbedLiveboard({
|
|
1188
|
+
data: { currentPath: '/embed/viz/' },
|
|
1189
|
+
type: 'Route',
|
|
1190
|
+
});
|
|
1191
|
+
|
|
1192
|
+
expect(spySetIFrameHeight).not.toHaveBeenCalled();
|
|
1193
|
+
});
|
|
1194
|
+
|
|
1195
|
+
test('should not call setIFrameHeight if currentPath starts with "/embed/insights/viz/"', () => {
|
|
1196
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
1197
|
+
...defaultViewConfig,
|
|
1198
|
+
fullHeight: true,
|
|
1199
|
+
} as AppViewConfig) as any;
|
|
1200
|
+
const spySetIFrameHeight = jest.spyOn(appEmbed, 'setIFrameHeight');
|
|
1201
|
+
|
|
1202
|
+
appEmbed.render();
|
|
1203
|
+
appEmbed.setIframeHeightForNonEmbedLiveboard({
|
|
1204
|
+
data: { currentPath: '/embed/insights/viz/' },
|
|
1205
|
+
type: 'Route',
|
|
1206
|
+
});
|
|
1207
|
+
|
|
1208
|
+
expect(spySetIFrameHeight).not.toHaveBeenCalled();
|
|
1209
|
+
});
|
|
1210
|
+
|
|
1211
|
+
test('should call setIFrameHeight if currentPath starts with "/some/other/path/"', () => {
|
|
1212
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
1213
|
+
...defaultViewConfig,
|
|
1214
|
+
fullHeight: true,
|
|
1215
|
+
} as AppViewConfig) as any;
|
|
1216
|
+
const spySetIFrameHeight = jest
|
|
1217
|
+
.spyOn(appEmbed, 'setIFrameHeight')
|
|
1218
|
+
.mockImplementation(jest.fn());
|
|
1219
|
+
|
|
1220
|
+
appEmbed.render();
|
|
1221
|
+
appEmbed.setIframeHeightForNonEmbedLiveboard({
|
|
1222
|
+
data: { currentPath: '/some/other/path/' },
|
|
1223
|
+
type: 'Route',
|
|
1224
|
+
});
|
|
1225
|
+
|
|
1226
|
+
expect(spySetIFrameHeight).toHaveBeenCalled();
|
|
1227
|
+
});
|
|
1228
|
+
|
|
1229
|
+
test('should update iframe height correctly', async () => {
|
|
1230
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
1231
|
+
...defaultViewConfig,
|
|
1232
|
+
fullHeight: true,
|
|
1233
|
+
} as AppViewConfig) as any;
|
|
1234
|
+
|
|
1235
|
+
// Set up the mock iframe
|
|
1236
|
+
appEmbed.iFrame = mockIFrame;
|
|
1237
|
+
document.body.appendChild(mockIFrame);
|
|
1238
|
+
|
|
1239
|
+
await appEmbed.render();
|
|
1240
|
+
const mockEvent = {
|
|
1241
|
+
data: 600,
|
|
1242
|
+
type: EmbedEvent.EmbedHeight,
|
|
1243
|
+
};
|
|
1244
|
+
appEmbed.updateIFrameHeight(mockEvent);
|
|
1245
|
+
|
|
1246
|
+
// Check if the iframe style was updated
|
|
1247
|
+
expect(mockIFrame.style.height).toBe('600px');
|
|
1248
|
+
});
|
|
1249
|
+
|
|
1250
|
+
test('should handle updateIFrameHeight with default height', async () => {
|
|
1251
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
1252
|
+
...defaultViewConfig,
|
|
1253
|
+
fullHeight: true,
|
|
1254
|
+
} as AppViewConfig) as any;
|
|
1255
|
+
|
|
1256
|
+
// Set up the mock iframe
|
|
1257
|
+
appEmbed.iFrame = mockIFrame;
|
|
1258
|
+
document.body.appendChild(mockIFrame);
|
|
1259
|
+
|
|
1260
|
+
await appEmbed.render();
|
|
1261
|
+
const mockEvent = {
|
|
1262
|
+
data: 0, // This will make it use the scrollHeight
|
|
1263
|
+
type: EmbedEvent.EmbedHeight,
|
|
1264
|
+
};
|
|
1265
|
+
appEmbed.updateIFrameHeight(mockEvent);
|
|
1266
|
+
|
|
1267
|
+
// Should use the scrollHeight
|
|
1268
|
+
expect(mockIFrame.style.height).toBe('500px');
|
|
1269
|
+
});
|
|
1270
|
+
});
|
|
818
1271
|
});
|