Welcome to mirror list, hosted at ThFree Co, Russian Federation.

browser_spec.js « utils « lib « javascripts « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 6b1074a3b4f625813372d7f1d076be50d9f9e117 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/**
 * This file should only contain browser specific specs.
 * If you need to add or update a spec, please see spec/frontend/lib/utils/*.js
 * https://gitlab.com/gitlab-org/gitlab/issues/194242#note_292137135
 * https://gitlab.com/groups/gitlab-org/-/epics/895#what-if-theres-a-karma-spec-which-is-simply-unmovable-to-jest-ie-it-is-dependent-on-a-running-browser-environment
 */

import MockAdapter from 'axios-mock-adapter';
import { GlBreakpointInstance as breakpointInstance } from '@gitlab/ui/dist/utils';
import axios from '~/lib/utils/axios_utils';
import * as commonUtils from '~/lib/utils/common_utils';
import { faviconDataUrl, overlayDataUrl, faviconWithOverlayDataUrl } from './mock_data';

const PIXEL_TOLERANCE = 0.2;

/**
 * Loads a data URL as the src of an
 * {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image|Image}
 * and resolves to that Image once loaded.
 *
 * @param url
 * @returns {Promise}
 */
const urlToImage = url =>
  new Promise(resolve => {
    const img = new Image();
    img.onload = function() {
      resolve(img);
    };
    img.src = url;
  });

describe('common_utils browser specific specs', () => {
  describe('contentTop', () => {
    it('does not add height for fileTitle or compareVersionsHeader if screen is too small', () => {
      spyOn(breakpointInstance, 'isDesktop').and.returnValue(false);

      setFixtures(`
          <div class="diff-file file-title-flex-parent">
            blah blah blah
          </div>
          <div class="mr-version-controls">
            more blah blah blah
          </div>
        `);

      expect(commonUtils.contentTop()).toBe(0);
    });

    it('adds height for fileTitle and compareVersionsHeader screen is large enough', () => {
      spyOn(breakpointInstance, 'isDesktop').and.returnValue(true);

      setFixtures(`
          <div class="diff-file file-title-flex-parent">
            blah blah blah
          </div>
          <div class="mr-version-controls">
            more blah blah blah
          </div>
        `);

      expect(commonUtils.contentTop()).toBe(18);
    });
  });

  describe('createOverlayIcon', () => {
    it('should return the favicon with the overlay', done => {
      commonUtils
        .createOverlayIcon(faviconDataUrl, overlayDataUrl)
        .then(url => Promise.all([urlToImage(url), urlToImage(faviconWithOverlayDataUrl)]))
        .then(([actual, expected]) => {
          expect(actual).toImageDiffEqual(expected, PIXEL_TOLERANCE);
          done();
        })
        .catch(done.fail);
    });
  });

  describe('setFaviconOverlay', () => {
    beforeEach(() => {
      const favicon = document.createElement('link');
      favicon.setAttribute('id', 'favicon');
      favicon.setAttribute('data-original-href', faviconDataUrl);
      document.body.appendChild(favicon);
    });

    afterEach(() => {
      document.body.removeChild(document.getElementById('favicon'));
    });

    it('should set page favicon to provided favicon overlay', done => {
      commonUtils
        .setFaviconOverlay(overlayDataUrl)
        .then(() => document.getElementById('favicon').getAttribute('href'))
        .then(url => Promise.all([urlToImage(url), urlToImage(faviconWithOverlayDataUrl)]))
        .then(([actual, expected]) => {
          expect(actual).toImageDiffEqual(expected, PIXEL_TOLERANCE);
          done();
        })
        .catch(done.fail);
    });
  });

  describe('setCiStatusFavicon', () => {
    const BUILD_URL = `${gl.TEST_HOST}/frontend-fixtures/builds-project/-/jobs/1/status.json`;
    let mock;

    beforeEach(() => {
      const favicon = document.createElement('link');
      favicon.setAttribute('id', 'favicon');
      favicon.setAttribute('href', 'null');
      favicon.setAttribute('data-original-href', faviconDataUrl);
      document.body.appendChild(favicon);
      mock = new MockAdapter(axios);
    });

    afterEach(() => {
      mock.restore();
      document.body.removeChild(document.getElementById('favicon'));
    });

    it('should reset favicon in case of error', done => {
      mock.onGet(BUILD_URL).replyOnce(500);

      commonUtils.setCiStatusFavicon(BUILD_URL).catch(() => {
        const favicon = document.getElementById('favicon');

        expect(favicon.getAttribute('href')).toEqual(faviconDataUrl);
        done();
      });
    });

    it('should set page favicon to CI status favicon based on provided status', done => {
      mock.onGet(BUILD_URL).reply(200, {
        favicon: overlayDataUrl,
      });

      commonUtils
        .setCiStatusFavicon(BUILD_URL)
        .then(() => document.getElementById('favicon').getAttribute('href'))
        .then(url => Promise.all([urlToImage(url), urlToImage(faviconWithOverlayDataUrl)]))
        .then(([actual, expected]) => {
          expect(actual).toImageDiffEqual(expected, PIXEL_TOLERANCE);
          done();
        })
        .catch(done.fail);
    });
  });

  describe('isInViewport', () => {
    let el;

    beforeEach(() => {
      el = document.createElement('div');
    });

    afterEach(() => {
      document.body.removeChild(el);
    });

    it('returns true when provided `el` is in viewport', () => {
      el.setAttribute('style', `position: absolute; right: ${window.innerWidth + 0.2};`);
      document.body.appendChild(el);

      expect(commonUtils.isInViewport(el)).toBe(true);
    });

    it('returns false when provided `el` is not in viewport', () => {
      el.setAttribute('style', 'position: absolute; top: -1000px; left: -1000px;');
      document.body.appendChild(el);

      expect(commonUtils.isInViewport(el)).toBe(false);
    });
  });
});