-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(project): add DOM test helpers (#4860)
- Loading branch information
Showing
4 changed files
with
168 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/** | ||
* Copyright IBM Corp. 2016, 2018 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import { getByText, isElementVisible } from '../dom'; | ||
|
||
describe('DOM test helpers', () => { | ||
let container; | ||
|
||
beforeEach(() => { | ||
container = document.createElement('div'); | ||
document.body.appendChild(container); | ||
}); | ||
|
||
afterEach(() => { | ||
document.body.removeChild(container); | ||
}); | ||
|
||
describe('getByText', () => { | ||
it('should get the matching node for the given text input', () => { | ||
const nodes = [ | ||
'<div>Text A</div>', | ||
'<button>Text B</button>', | ||
'<button>Text C <svg></svg></button>', | ||
]; | ||
container.innerHTML = nodes.join(''); | ||
|
||
expect(getByText(container, 'Text A')).toEqual(container.childNodes[0]); | ||
expect(getByText(container, 'Text B')).toEqual(container.childNodes[1]); | ||
expect(getByText(container, 'Text C')).toEqual(container.childNodes[2]); | ||
}); | ||
|
||
it('should return null if no matches are found', () => { | ||
expect(getByText(container, 'Not found')).toEqual(null); | ||
}); | ||
}); | ||
|
||
describe('isElementVisible', () => { | ||
it('should detect if an element is visible', () => { | ||
expect(isElementVisible(container)).toBe(true); | ||
}); | ||
|
||
it('should detect if an element is not visible', () => { | ||
const hidden = Array.from({ length: 6 }).map(() => | ||
document.createElement('div') | ||
); | ||
|
||
// <div hidden></div> | ||
hidden[0].setAttribute('hidden', ''); | ||
|
||
// <div style="display: none;"></div> | ||
hidden[1].style.display = 'none'; | ||
|
||
// <div style="visibility: hidden;"></div> | ||
hidden[2].style.visibility = 'hidden'; | ||
|
||
// <div style="visibility: collapse;"></div> | ||
hidden[3].style.visibility = 'collapse'; | ||
|
||
// <div style="opacity: 0;"></div> | ||
hidden[4].style.opacity = '0'; | ||
|
||
// <div style="opacity: 0;"></div> | ||
hidden[5].style.opacity = 0; | ||
|
||
for (const node of hidden) { | ||
container.appendChild(node); | ||
expect(isElementVisible(node)).toBe(false); | ||
} | ||
}); | ||
|
||
it('should detect if an element has a parent that is not visible', () => { | ||
const hiddenParent = document.createElement('div'); | ||
hiddenParent.style.display = 'none'; | ||
|
||
const visibleChild = document.createElement('div'); | ||
hiddenParent.appendChild(visibleChild); | ||
|
||
expect(isElementVisible(hiddenParent)).toBe(false); | ||
expect(isElementVisible(visibleChild)).toBe(false); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/** | ||
* Copyright IBM Corp. 2016, 2018 | ||
* | ||
* This source code is licensed under the Apache-2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import prettier from 'prettier'; | ||
|
||
/** | ||
* Find the HTMLElement that includes the given `text` | ||
* | ||
* @param {HTMLElement} node | ||
* @param {string} text | ||
* @returns {?HTMLElement} | ||
*/ | ||
export function getByText(node, text) { | ||
if (node.nodeType === Node.TEXT_NODE && node.textContent.trim() === text) { | ||
return node.parentNode; | ||
} | ||
|
||
for (const child of node.childNodes) { | ||
const match = getByText(child, text); | ||
if (match) { | ||
return match; | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
|
||
/** | ||
* Check if an element is currently visible to an end-user. | ||
* | ||
* @param {HTMLElement} element | ||
* @returns {boolean} | ||
*/ | ||
export function isElementVisible(element) { | ||
const { getComputedStyle } = element.ownerDocument.defaultView; | ||
const { display, visibility, opacity } = getComputedStyle(element); | ||
|
||
if ( | ||
element.hasAttribute('hidden') || | ||
display === 'none' || | ||
visibility === 'hidden' || | ||
visibility === 'collapse' || | ||
opacity === '0' || | ||
opacity === 0 | ||
) { | ||
return false; | ||
} | ||
|
||
if (element.parentElement) { | ||
return isElementVisible(element.parentElement); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* Pretty-print the outerHTML of the given element. Uses prettier under the | ||
* hood. | ||
* | ||
* @param {HTMLElement} element | ||
* @returns {string} | ||
*/ | ||
export function debug(element) { | ||
return prettier.format(element.outerHTML, { | ||
parser: 'html', | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters