• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

thoughtspot / visual-embed-sdk / #1932

06 Jun 2025 01:26PM UTC coverage: 93.61% (-0.2%) from 93.827%
#1932

Pull #215

yinstardev
logger test failure
Pull Request #215: SCAL-256749 present-event

1103 of 1256 branches covered (87.82%)

Branch coverage included in aggregate %.

40 of 46 new or added lines in 3 files covered. (86.96%)

5 existing lines in 1 file now uncovered.

2662 of 2766 relevant lines covered (96.24%)

67.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.74
/src/utils/processTrigger.ts
1
import { ERROR_MESSAGE } from '../errors';
16✔
2
import { HostEvent } from '../types';
16✔
3
import { logger } from '../utils/logger';
16✔
4

5
/**
6
 * Handle the Present event locally before forwarding
7
 * @param iFrame - The iframe element to make fullscreen
8
 */
9
function handlePresentEvent(iFrame: HTMLIFrameElement) {
10
    const iframe = iFrame;
3✔
11
    
12
    if (!iframe) {
3!
NEW
13
        logger.warn('No iframe found on the page');
×
NEW
14
        return;
×
15
    }
16

17
    // Check if already in fullscreen mode
18
    const isInFullscreen = !!(
3✔
19
        document.fullscreenElement ||
9✔
20
        (document as any).webkitFullscreenElement ||
21
        (document as any).mozFullScreenElement ||
22
        (document as any).msFullscreenElement
23
    );
24

25
    if (isInFullscreen) {
3✔
26
        // Already in fullscreen, nothing to do
27
        return;
1✔
28
    }
29

30
    // Try to request fullscreen with vendor prefixes and error handling
31
    const fullscreenMethods = [
2✔
32
        'requestFullscreen',
33
        'webkitRequestFullscreen', 
34
        'mozRequestFullScreen',
35
        'msRequestFullscreen'
36
    ];
37

38
    let fullscreenRequested = false;
2✔
39
    
40
    for (const method of fullscreenMethods) {
2✔
41
        if (typeof (iframe as any)[method] === 'function') {
5✔
42
            try {
1✔
43
                const result = (iframe as any)[method]();
1✔
44
                if (result && typeof result.catch === 'function') {
1✔
45
                    result.catch((error: any) => {
1✔
NEW
46
                        logger.warn(`Failed to enter fullscreen using ${method}:`, error);
×
47
                    });
48
                }
49
                fullscreenRequested = true;
1✔
50
                break;
1✔
51
            } catch (error) {
NEW
52
                logger.warn(`Failed to enter fullscreen using ${method}:`, error);
×
53
            }
54
        }
55
    }
56

57
    if (!fullscreenRequested) {
2✔
58
        logger.error('Fullscreen API is not supported by this browser.');
1✔
59
    }
60
}
61

62
/**
63
 * Reloads the ThoughtSpot iframe.
64
 * @param iFrame
65
 */
66
export const reload = (iFrame: HTMLIFrameElement) => {
16✔
67
    const src = iFrame.src;
1✔
68
    iFrame.src = '';
1✔
69
    setTimeout(() => {
1✔
70
        iFrame.src = src;
1✔
71
    }, 100);
72
};
73

74
/**
75
 * Post iframe message.
76
 * @param iFrame
77
 * @param message
78
 * @param message.type
79
 * @param message.data
80
 * @param thoughtSpotHost
81
 * @param channel
82
 */
83
function postIframeMessage(
84
    iFrame: HTMLIFrameElement,
85
    message: { type: HostEvent; data: any },
86
    thoughtSpotHost: string,
87
    channel?: MessageChannel,
88
) {
89
    return iFrame.contentWindow.postMessage(message, thoughtSpotHost, [channel?.port2]);
15!
90
}
91

92
export const TRIGGER_TIMEOUT = 30000;
16✔
93

94
/**
95
 *
96
 * @param iFrame
97
 * @param messageType
98
 * @param thoughtSpotHost
99
 * @param data
100
 */
101
export function processTrigger(
16✔
102
    iFrame: HTMLIFrameElement,
103
    messageType: HostEvent,
104
    thoughtSpotHost: string,
105
    data: any,
106
): Promise<any> {
107
    return new Promise<any>((res, rej) => {
16✔
108
        if (messageType === HostEvent.Reload) {
16✔
109
            reload(iFrame);
1✔
110
            return res(null);
1✔
111
        }
112
        
113
        if (messageType === HostEvent.Present) {
15✔
114
            handlePresentEvent(iFrame);
3✔
115
        }
116
        
117
        const channel = new MessageChannel();
15✔
118
        channel.port1.onmessage = ({ data: responseData }) => {
15✔
119
            channel.port1.close();
5✔
120
            const error = responseData.error || responseData?.data?.error;
5!
121
            if (error) {
5✔
122
                rej(error);
1✔
123
            } else {
124
                res(responseData);
4✔
125
            }
126
        };
127

128
        // Close the messageChannel and resolve the promise if timeout.
129
        setTimeout(() => {
15✔
130
            channel.port1.close();
3✔
131
            res(new Error(ERROR_MESSAGE.TRIGGER_TIMED_OUT));
3✔
132
        }, TRIGGER_TIMEOUT);
133

134
        return postIframeMessage(iFrame, { type: messageType, data }, thoughtSpotHost, channel);
15✔
135
    });
136
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc