Skip to content

Commit 79c3bf4

Browse files
authored
Add Tests on scrollbar.js & better handling if a style property doesn't exists (#33948)
* scrollbar.js: add some tests transfer test from modal.spec. to scrollbar.spec proper handling if style property doesn't exist
1 parent 9e4f87a commit 79c3bf4

File tree

3 files changed

+127
-245
lines changed

3 files changed

+127
-245
lines changed

js/src/util/scrollbar.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,11 @@ const _setElementAttributes = (selector, styleProp, callback) => {
4444
}
4545

4646
const actualValue = element.style[styleProp]
47+
if (actualValue) {
48+
Manipulator.setDataAttribute(element, styleProp, actualValue)
49+
}
50+
4751
const calculatedValue = window.getComputedStyle(element)[styleProp]
48-
Manipulator.setDataAttribute(element, styleProp, actualValue)
4952
element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`
5053
})
5154
}

js/tests/unit/modal.spec.js

Lines changed: 4 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import Modal from '../../src/modal'
22
import EventHandler from '../../src/dom/event-handler'
3-
import { getWidth as getScrollBarWidth } from '../../src/util/scrollbar'
43

54
/** Test helpers */
65
import { clearBodyAndDocument, clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture'
@@ -62,170 +61,22 @@ describe('Modal', () => {
6261
it('should toggle a modal', done => {
6362
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
6463

65-
document.documentElement.style.overflowY = 'scroll'
64+
const initialOverFlow = document.body.style.overflow
6665
const modalEl = fixtureEl.querySelector('.modal')
6766
const modal = new Modal(modalEl)
68-
const originalPadding = '0px'
67+
const originalPadding = '10px'
6968

7069
document.body.style.paddingRight = originalPadding
7170

7271
modalEl.addEventListener('shown.bs.modal', () => {
7372
expect(document.body.getAttribute('data-bs-padding-right')).toEqual(originalPadding, 'original body padding should be stored in data-bs-padding-right')
73+
expect(document.body.style.overflow).toEqual('hidden')
7474
modal.toggle()
7575
})
7676

7777
modalEl.addEventListener('hidden.bs.modal', () => {
7878
expect(document.body.getAttribute('data-bs-padding-right')).toBeNull()
79-
expect().nothing()
80-
document.documentElement.style.overflowY = 'auto'
81-
done()
82-
})
83-
84-
modal.toggle()
85-
})
86-
87-
it('should adjust the inline padding of fixed elements when opening and restore when closing', done => {
88-
fixtureEl.innerHTML = [
89-
'<div class="fixed-top" style="padding-right: 0px"></div>',
90-
'<div class="modal"><div class="modal-dialog"></div></div>'
91-
].join('')
92-
93-
document.documentElement.style.overflowY = 'scroll'
94-
const fixedEl = fixtureEl.querySelector('.fixed-top')
95-
const originalPadding = Number.parseInt(window.getComputedStyle(fixedEl).paddingRight, 10)
96-
const modalEl = fixtureEl.querySelector('.modal')
97-
const modal = new Modal(modalEl)
98-
const scrollBarWidth = getScrollBarWidth()
99-
100-
modalEl.addEventListener('shown.bs.modal', () => {
101-
const expectedPadding = originalPadding + scrollBarWidth
102-
const currentPadding = Number.parseInt(window.getComputedStyle(fixedEl).paddingRight, 10)
103-
104-
expect(fixedEl.getAttribute('data-bs-padding-right')).toEqual(`${originalPadding}px`, 'original fixed element padding should be stored in data-bs-padding-right')
105-
expect(currentPadding).toEqual(expectedPadding, 'fixed element padding should be adjusted while opening')
106-
modal.toggle()
107-
})
108-
109-
modalEl.addEventListener('hidden.bs.modal', () => {
110-
const currentPadding = Number.parseInt(window.getComputedStyle(fixedEl).paddingRight, 10)
111-
112-
expect(fixedEl.hasAttribute('data-bs-padding-right')).toEqual(false, 'data-bs-padding-right should be cleared after closing')
113-
expect(currentPadding).toEqual(originalPadding, 'fixed element padding should be reset after closing')
114-
document.documentElement.style.overflowY = 'auto'
115-
done()
116-
})
117-
118-
modal.toggle()
119-
})
120-
121-
it('should adjust the inline margin of sticky elements when opening and restore when closing', done => {
122-
fixtureEl.innerHTML = [
123-
'<div class="sticky-top" style="margin-right: 0px;"></div>',
124-
'<div class="modal"><div class="modal-dialog"></div></div>'
125-
].join('')
126-
127-
document.documentElement.style.overflowY = 'scroll'
128-
129-
const stickyTopEl = fixtureEl.querySelector('.sticky-top')
130-
const originalMargin = Number.parseInt(window.getComputedStyle(stickyTopEl).marginRight, 10)
131-
const modalEl = fixtureEl.querySelector('.modal')
132-
const modal = new Modal(modalEl)
133-
const scrollBarWidth = getScrollBarWidth()
134-
135-
modalEl.addEventListener('shown.bs.modal', () => {
136-
const expectedMargin = originalMargin - scrollBarWidth
137-
const currentMargin = Number.parseInt(window.getComputedStyle(stickyTopEl).marginRight, 10)
138-
139-
expect(stickyTopEl.getAttribute('data-bs-margin-right')).toEqual(`${originalMargin}px`, 'original sticky element margin should be stored in data-bs-margin-right')
140-
expect(currentMargin).toEqual(expectedMargin, 'sticky element margin should be adjusted while opening')
141-
modal.toggle()
142-
})
143-
144-
modalEl.addEventListener('hidden.bs.modal', () => {
145-
const currentMargin = Number.parseInt(window.getComputedStyle(stickyTopEl).marginRight, 10)
146-
147-
expect(stickyTopEl.hasAttribute('data-bs-margin-right')).toEqual(false, 'data-bs-margin-right should be cleared after closing')
148-
expect(currentMargin).toEqual(originalMargin, 'sticky element margin should be reset after closing')
149-
150-
document.documentElement.style.overflowY = 'auto'
151-
done()
152-
})
153-
154-
modal.toggle()
155-
})
156-
157-
it('should not adjust the inline margin and padding of sticky and fixed elements when element do not have full width', done => {
158-
fixtureEl.innerHTML = [
159-
'<div class="sticky-top" style="margin-right: 0px; padding-right: 0px; width: calc(100vw - 50%)"></div>',
160-
'<div class="modal"><div class="modal-dialog"></div></div>'
161-
].join('')
162-
163-
const stickyTopEl = fixtureEl.querySelector('.sticky-top')
164-
const originalMargin = Number.parseInt(window.getComputedStyle(stickyTopEl).marginRight, 10)
165-
const originalPadding = Number.parseInt(window.getComputedStyle(stickyTopEl).paddingRight, 10)
166-
const modalEl = fixtureEl.querySelector('.modal')
167-
const modal = new Modal(modalEl)
168-
169-
modalEl.addEventListener('shown.bs.modal', () => {
170-
const currentMargin = Number.parseInt(window.getComputedStyle(stickyTopEl).marginRight, 10)
171-
const currentPadding = Number.parseInt(window.getComputedStyle(stickyTopEl).paddingRight, 10)
172-
173-
expect(currentMargin).toEqual(originalMargin, 'sticky element\'s margin should not be adjusted while opening')
174-
expect(currentPadding).toEqual(originalPadding, 'sticky element\'s padding should not be adjusted while opening')
175-
done()
176-
})
177-
178-
modal.show()
179-
})
180-
181-
it('should ignore values set via CSS when trying to restore body padding after closing', done => {
182-
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
183-
const styleTest = document.createElement('style')
184-
185-
styleTest.type = 'text/css'
186-
styleTest.appendChild(document.createTextNode('body { padding-right: 7px; }'))
187-
document.head.appendChild(styleTest)
188-
189-
const modalEl = fixtureEl.querySelector('.modal')
190-
const modal = new Modal(modalEl)
191-
192-
modalEl.addEventListener('shown.bs.modal', () => {
193-
modal.toggle()
194-
})
195-
196-
modalEl.addEventListener('hidden.bs.modal', () => {
197-
expect(window.getComputedStyle(document.body).paddingLeft).toEqual('0px', 'body does not have inline padding set')
198-
document.head.removeChild(styleTest)
199-
done()
200-
})
201-
202-
modal.toggle()
203-
})
204-
205-
it('should ignore other inline styles when trying to restore body padding after closing', done => {
206-
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
207-
const styleTest = document.createElement('style')
208-
209-
styleTest.type = 'text/css'
210-
styleTest.appendChild(document.createTextNode('body { padding-right: 7px; }'))
211-
212-
document.head.appendChild(styleTest)
213-
document.body.style.color = 'red'
214-
215-
const modalEl = fixtureEl.querySelector('.modal')
216-
const modal = new Modal(modalEl)
217-
218-
modalEl.addEventListener('shown.bs.modal', () => {
219-
modal.toggle()
220-
})
221-
222-
modalEl.addEventListener('hidden.bs.modal', () => {
223-
const bodyPaddingRight = document.body.style.paddingRight
224-
225-
expect(bodyPaddingRight === '0px' || bodyPaddingRight === '').toEqual(true, 'body does not have inline padding set')
226-
expect(document.body.style.color).toEqual('red', 'body still has other inline styles set')
227-
document.head.removeChild(styleTest)
228-
document.body.removeAttribute('style')
79+
expect(document.body.style.overflow).toEqual(initialOverFlow)
22980
done()
23081
})
23182

@@ -659,61 +510,6 @@ describe('Modal', () => {
659510
modal.show()
660511
})
661512

662-
it('should not adjust the inline body padding when it does not overflow', done => {
663-
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
664-
665-
const modalEl = fixtureEl.querySelector('.modal')
666-
const modal = new Modal(modalEl)
667-
const originalPadding = window.getComputedStyle(document.body).paddingRight
668-
669-
// Hide scrollbars to prevent the body overflowing
670-
document.body.style.overflow = 'hidden'
671-
document.documentElement.style.paddingRight = '0px'
672-
673-
modalEl.addEventListener('shown.bs.modal', () => {
674-
const currentPadding = window.getComputedStyle(document.body).paddingRight
675-
676-
expect(currentPadding).toEqual(originalPadding, 'body padding should not be adjusted')
677-
678-
// Restore scrollbars
679-
document.body.style.overflow = 'auto'
680-
done()
681-
})
682-
683-
modal.show()
684-
})
685-
686-
it('should not adjust the inline body padding when it does not overflow, even on a scaled display', done => {
687-
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
688-
689-
const modalEl = fixtureEl.querySelector('.modal')
690-
const modal = new Modal(modalEl)
691-
const originalPadding = window.getComputedStyle(document.body).paddingRight
692-
693-
// Remove body margins as would be done by Bootstrap css
694-
document.body.style.margin = '0'
695-
696-
// Hide scrollbars to prevent the body overflowing
697-
document.body.style.overflow = 'hidden'
698-
699-
// Simulate a discrepancy between exact, i.e. floating point body width, and rounded body width
700-
// as it can occur when zooming or scaling the display to something else than 100%
701-
document.documentElement.style.paddingRight = '.48px'
702-
703-
modalEl.addEventListener('shown.bs.modal', () => {
704-
const currentPadding = window.getComputedStyle(document.body).paddingRight
705-
706-
expect(currentPadding).toEqual(originalPadding, 'body padding should not be adjusted')
707-
708-
// Restore overridden css
709-
document.body.style.removeProperty('margin')
710-
document.body.style.removeProperty('overflow')
711-
done()
712-
})
713-
714-
modal.show()
715-
})
716-
717513
it('should enforce focus', done => {
718514
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
719515

0 commit comments

Comments
 (0)