Skip to content

Commit 9f343b0

Browse files
committed
feat: isVisible
1 parent 3110633 commit 9f343b0

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed

src/domWrapper.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { nextTick } from 'vue'
22

33
import { createWrapperError } from './errorWrapper'
44
import { TriggerOptions, createDOMEvent } from './createDomEvent'
5+
import { isElementVisible } from './utils/isElementVisible'
56

67
export class DOMWrapper<ElementType extends Element> {
78
element: ElementType
@@ -36,6 +37,10 @@ export class DOMWrapper<ElementType extends Element> {
3637
return true
3738
}
3839

40+
isVisible() {
41+
return isElementVisible(this.element)
42+
}
43+
3944
text() {
4045
return this.element.textContent?.trim()
4146
}

src/utils/isElementVisible.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*!
2+
* isElementVisible
3+
* Adapted from https://github.com/testing-library/jest-dom
4+
* Licensed under the MIT License.
5+
*/
6+
7+
type StylableElement = HTMLElement | SVGElement
8+
9+
function isStyleVisible<T extends StylableElement>(element: T) {
10+
const { display, visibility, opacity } = element.style
11+
return (
12+
display !== 'none' &&
13+
visibility !== 'hidden' &&
14+
visibility !== 'collapse' &&
15+
opacity !== '0'
16+
)
17+
}
18+
19+
function isAttributeVisible<T extends StylableElement>(element: T) {
20+
return (
21+
!element.hasAttribute('hidden') &&
22+
(element.nodeName === 'DETAILS' ? element.hasAttribute('open') : true)
23+
)
24+
}
25+
26+
export function isElementVisible<T extends StylableElement>(element: T) {
27+
return (
28+
element.nodeName !== '#comment' &&
29+
isStyleVisible(element) &&
30+
isAttributeVisible(element) &&
31+
(!element.parentElement || isElementVisible(element.parentElement))
32+
)
33+
}

tests/isVisible.spec.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { mount } from '../src'
2+
3+
describe('isVisible', () => {
4+
const Comp = {
5+
template: `<div><span v-show="show" /></div>`,
6+
props: {
7+
show: {
8+
type: Boolean
9+
}
10+
}
11+
}
12+
13+
it('returns false when element hidden via v-show', () => {
14+
const wrapper = mount(Comp, {
15+
props: {
16+
show: false
17+
}
18+
})
19+
20+
expect(wrapper.find('span').isVisible()).toBe(false)
21+
})
22+
23+
it('returns true when element is visible via v-show', () => {
24+
const wrapper = mount(Comp, {
25+
props: {
26+
show: true
27+
}
28+
})
29+
30+
expect(wrapper.find('span').isVisible()).toBe(true)
31+
})
32+
33+
it('element becomes hidden reactively', async () => {
34+
const Comp = {
35+
template: `<button @click="show = false" /><span v-show="show" />`,
36+
data() {
37+
return {
38+
show: true
39+
}
40+
}
41+
}
42+
const wrapper = mount(Comp)
43+
44+
expect(wrapper.find('span').isVisible()).toBe(true)
45+
await wrapper.find('button').trigger('click')
46+
expect(wrapper.find('span').isVisible()).toBe(false)
47+
})
48+
})

0 commit comments

Comments
 (0)