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

yext / answers-search-ui / 13118033733

03 Feb 2025 04:23PM UTC coverage: 61.767% (-0.4%) from 62.179%
13118033733

Pull #1914

github

web-flow
Merge 4bafd1b70 into 4bbe5b26d
Pull Request #1914: Generative Direct Answers integration

2026 of 3430 branches covered (59.07%)

Branch coverage included in aggregate %.

67 of 113 new or added lines in 7 files covered. (59.29%)

30 existing lines in 4 files now uncovered.

3483 of 5489 relevant lines covered (63.45%)

26.65 hits per line

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

17.31
/src/core/analytics/visibilityanalyticshandler.js
1
import { isIE } from '../utils/useragent';
2
import AnalyticsEvent from '../analytics/analyticsevent';
3
import Searcher from '../models/searcher';
4
import StorageKeys from '../storage/storagekeys';
5

6
const RESULTS_VISIBILITY_EVENT = {
1✔
7
  HIDDEN: 'RESULTS_HIDDEN',
8
  UNHIDDEN: 'RESULTS_UNHIDDEN'
9
};
10

11
/**
12
 * Manages the document's visibility status and handles any visibility related analytics events.
13
 */
14
export default class VisibilityAnalyticsHandler {
15
  constructor (analyticsReporterService, verticalKey) {
16
    this._previousResultsVisibilityEvent = undefined;
7✔
17
    this._analyticsReporterService = analyticsReporterService;
7✔
18
    this._verticalKey = verticalKey;
7✔
19
  }
20

21
  /**
22
   * Initialize visibility change event listener(s) to send analytics events
23
   * when a result page have become visible or have been hidden.
24
   *
25
   * @param {Storage} storage - a container around application state
26
   */
27
  initVisibilityChangeListeners (storage) {
28
    /**
29
     * Safari desktop listener and IE11 listeners fire visibility change event twice when switch
30
     * to new tab and then close browser. Variable "_previousResultsVisibilityEvent" is used to ensure
31
     * RESULTS_HIDDEN analytics event does not get send again if the page is already hidden.
32
     */
33
    document.addEventListener('visibilitychange', () => {
7✔
34
      if (this._resultsVisibilityChangeToHidden()) {
×
35
        this._previousResultsVisibilityEvent = RESULTS_VISIBILITY_EVENT.HIDDEN;
×
36
        this._reportVisibilityChangeEvent(RESULTS_VISIBILITY_EVENT.HIDDEN);
×
37
      } else if (this._resultsVisibilityChangeToVisible()) {
×
38
        this._previousResultsVisibilityEvent = RESULTS_VISIBILITY_EVENT.UNHIDDEN;
×
39
        this._reportVisibilityChangeEvent(RESULTS_VISIBILITY_EVENT.UNHIDDEN);
×
40
      }
41
    });
42

43
    /**
44
     * VisibilityChange API does not register when page is terminated (close tab/browser) in IE11.
45
     * Unload event is used to capture those RESULTS_HIDDEN scenarios.
46
     */
47
    if (isIE()) {
7!
48
      window.addEventListener('unload', () => {
×
49
        if (this._previousResultsVisibilityEvent !== RESULTS_VISIBILITY_EVENT.HIDDEN) {
×
50
          this._reportVisibilityChangeEvent(RESULTS_VISIBILITY_EVENT.HIDDEN);
×
51
        }
52
      });
53
    }
54

55
    /**
56
     * Page history updates caused by pushState() or replaceState(), such as when a search is performed,
57
     * will not trigger a complete page load so the document's visibility state will not change. Use
58
     * popstate event and storage listener on QUERY_ID to report result visibility change events for
59
     * back/forward page navigation of the same answers page.
60
     */
61
    window.addEventListener('popstate', () => {
7✔
62
      const poppedStateQueryId = storage.get(StorageKeys.HISTORY_POP_STATE)?.get('pop-state-queryId');
×
63
      const storageQueryId = this._analyticsReporterService.getQueryId();
×
64
      this._analyticsReporterService.setQueryId(poppedStateQueryId);
×
65
      this._previousResultsVisibilityEvent = RESULTS_VISIBILITY_EVENT.HIDDEN;
×
66
      this._reportVisibilityChangeEvent(RESULTS_VISIBILITY_EVENT.HIDDEN);
×
67
      this._analyticsReporterService.setQueryId(storageQueryId);
×
68
    });
69

70
    storage.registerListener({
7✔
71
      eventType: 'update',
72
      storageKey: StorageKeys.QUERY_ID,
73
      callback: id => {
UNCOV
74
        if (this._resultsVisibilityChangeToVisible()) {
×
UNCOV
75
          this._previousResultsVisibilityEvent = RESULTS_VISIBILITY_EVENT.UNHIDDEN;
×
UNCOV
76
          this._reportVisibilityChangeEvent(RESULTS_VISIBILITY_EVENT.UNHIDDEN);
×
77
        }
78
      }
79
    });
80
  }
81

82
  /**
83
   * Returns true if results page was previously reported as unhidden and the page is now hidden.
84
   *
85
   * @returns {boolean}
86
   */
87
  _resultsVisibilityChangeToHidden () {
88
    return document.visibilityState === 'hidden' && this._previousResultsVisibilityEvent !== RESULTS_VISIBILITY_EVENT.HIDDEN;
×
89
  }
90

91
  /**
92
   * Returns true if results page was previously reported as hidden and the page is now visible.
93
   *
94
   * @returns {boolean}
95
   */
96
  _resultsVisibilityChangeToVisible () {
UNCOV
97
    return document.visibilityState === 'visible' && this._previousResultsVisibilityEvent !== RESULTS_VISIBILITY_EVENT.UNHIDDEN;
×
98
  }
99

100
  /**
101
   * Send visibility change related analytics event.
102
   *
103
   * @param {string} eventName - the name of the analytics event to report
104
   */
105
  _reportVisibilityChangeEvent (eventName) {
UNCOV
106
    const queryId = this._analyticsReporterService.getQueryId();
×
UNCOV
107
    if (!queryId) {
×
UNCOV
108
      return;
×
109
    }
110
    const searcher = this._verticalKey ? Searcher.VERTICAL : Searcher.UNIVERSAL;
×
111
    const event = new AnalyticsEvent(eventName).addOptions({ searcher });
×
112
    this._analyticsReporterService.report(event);
×
113
  }
114
}
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

© 2025 Coveralls, Inc