diff options
Diffstat (limited to 'spec/frontend/helpers')
-rw-r--r-- | spec/frontend/helpers/dom_shims/README.md | 12 | ||||
-rw-r--r-- | spec/frontend/helpers/dom_shims/get_client_rects.js | 50 | ||||
-rw-r--r-- | spec/frontend/helpers/dom_shims/get_client_rects_spec.js | 71 | ||||
-rw-r--r-- | spec/frontend/helpers/dom_shims/index.js | 1 |
4 files changed, 134 insertions, 0 deletions
diff --git a/spec/frontend/helpers/dom_shims/README.md b/spec/frontend/helpers/dom_shims/README.md new file mode 100644 index 00000000000..1105e4b0c4c --- /dev/null +++ b/spec/frontend/helpers/dom_shims/README.md @@ -0,0 +1,12 @@ +## Jest DOM shims + +This is where we shim parts of JSDom. It is imported in our root `test_setup.js`. + +### Why do we need this? + +Since JSDom mocks a real DOM environment (which is a good thing), it +unfortunately does not support some jQuery matchers. + +### References + +- https://gitlab.com/gitlab-org/gitlab/merge_requests/17906#note_224448120 diff --git a/spec/frontend/helpers/dom_shims/get_client_rects.js b/spec/frontend/helpers/dom_shims/get_client_rects.js new file mode 100644 index 00000000000..d740c1bf154 --- /dev/null +++ b/spec/frontend/helpers/dom_shims/get_client_rects.js @@ -0,0 +1,50 @@ +function hasHiddenStyle(node) { + if (!node.style) { + return false; + } else if (node.style.display === 'none' || node.style.visibility === 'hidden') { + return true; + } + + return false; +} + +function createDefaultClientRect() { + return { + bottom: 0, + height: 0, + left: 0, + right: 0, + top: 0, + width: 0, + x: 0, + y: 0, + }; +} + +/** + * This is needed to get the `toBeVisible` matcher to work in `jsdom` + * + * Reference: + * - https://github.com/jsdom/jsdom/issues/1322 + * - https://github.com/unindented/custom-jquery-matchers/blob/v2.1.0/packages/custom-jquery-matchers/src/matchers.js#L157 + */ +window.Element.prototype.getClientRects = function getClientRects() { + let node = this; + + while (node) { + if (node === document) { + break; + } + + if (hasHiddenStyle(node)) { + return []; + } + node = node.parentNode; + } + + if (!node) { + return []; + } + + return [createDefaultClientRect()]; +}; diff --git a/spec/frontend/helpers/dom_shims/get_client_rects_spec.js b/spec/frontend/helpers/dom_shims/get_client_rects_spec.js new file mode 100644 index 00000000000..e7b8f1e235b --- /dev/null +++ b/spec/frontend/helpers/dom_shims/get_client_rects_spec.js @@ -0,0 +1,71 @@ +const createTestElement = () => { + const element = document.createElement('div'); + + element.textContent = 'Hello World!'; + + return element; +}; + +describe('DOM patch for getClientRects', () => { + let origHtml; + let el; + + beforeEach(() => { + origHtml = document.body.innerHTML; + el = createTestElement(); + }); + + afterEach(() => { + document.body.innerHTML = origHtml; + }); + + describe('toBeVisible matcher', () => { + describe('when not attached to document', () => { + it('does not match', () => { + expect(el).not.toBeVisible(); + }); + }); + + describe('when attached to document', () => { + beforeEach(() => { + document.body.appendChild(el); + }); + + it('matches', () => { + expect(el).toBeVisible(); + }); + }); + + describe('with parent and attached to document', () => { + let parentEl; + + beforeEach(() => { + parentEl = createTestElement(); + parentEl.appendChild(el); + document.body.appendChild(parentEl); + }); + + it('matches', () => { + expect(el).toBeVisible(); + }); + + describe.each` + style + ${{ display: 'none' }} + ${{ visibility: 'hidden' }} + `('with style $style', ({ style }) => { + it('does not match when applied to element', () => { + Object.assign(el.style, style); + + expect(el).not.toBeVisible(); + }); + + it('does not match when applied to parent', () => { + Object.assign(parentEl.style, style); + + expect(el).not.toBeVisible(); + }); + }); + }); + }); +}); diff --git a/spec/frontend/helpers/dom_shims/index.js b/spec/frontend/helpers/dom_shims/index.js new file mode 100644 index 00000000000..40256398e6d --- /dev/null +++ b/spec/frontend/helpers/dom_shims/index.js @@ -0,0 +1 @@ +import './get_client_rects'; |