import { appendFrame, byId, createDetachedDocument, generateId, getOne, insertHtml, removeElement } from './assets/helpers'; import scrollParent from '../scrollParent'; const scrollerID = generateId('scroller'); const childID = generateId('child'); const style = 'with: 10px; height: 10px;'; describe('"scrollParent', () => { const scrollElm = (doc: Document) => doc.documentElement; describe.each([ [' element', (doc: Document) => doc.documentElement], [' element', (doc: Document) => doc.body] ])('%s, Returns document.scrollingElement (viewport)', (_, getElm) => { it('In the current document', () => { const doc = document; expect(scrollParent(getElm(doc))).toBe(scrollElm(doc)); }); it('In a Frame document', () => { const frame = appendFrame(); const doc = frame.contentDocument as Document; expect(scrollParent(getElm(doc))).toBe(scrollElm(doc)); frame.remove(); }); it('A DOM Node in a detached Document', () => { const doc = createDetachedDocument(); expect(scrollParent(getElm(doc))).toBe(scrollElm(doc)); }); }); describe.each([ ['Single element', `
`], ['"fixed" Element', `
`], ['Element inside "overflow: hidden;" element', `
`], ['Element inside "relative" Element', `
`], ['"absolute" Element inside an Element with "overflow"', `
`], ['"fixed" Element inside an Element with "overflow"', `
`] ])('%s: Returns document.scrollingElement (viewport)', (_, HTML) => { function suite(doc: Document) { insertHtml(HTML, doc.body); expect(scrollParent(byId(childID, doc))).toBe(scrollElm(doc)); removeElement(getOne('.root', doc), doc); } it('In the current document', () => { suite(document); }); it('In a Frame document', () => { const frame = appendFrame(); const doc = frame.contentDocument as Document; suite(doc); frame.remove(); }); it('A DOM Node in a detached Document', () => { const doc = createDetachedDocument(); suite(doc); }); }); describe('Returns the nearest element with scrolling overflow when', () => { describe.each([ ['Element is direct child', `
`], ['Element is child of "relative" child', `
`], ['It is "relative" and element is "absolute"', `
`], ['It is "relative" and element is "absolute" (skipping no scrolling "relative" parent)', `
`], ['Itself is a child of a relative scrolling element', `
`] ])('%s', (_, HTML) => { let scroller: HTMLElement; let child: HTMLElement; let root: Element; beforeEach(() => { insertHtml(HTML); scroller = byId(scrollerID); child = byId(childID); root = getOne('.root'); }); afterAll(() => { removeElement(root); }); describe.each(['overflow', 'overflowX', 'overflowY'] as const)('with: %s', (overflow) => { it.each(['auto', 'scroll'] as const)('%s', (scroll) => { scroller.style[overflow] = scroll; expect(scrollParent(child)).toBe(scroller); }); }); }); }); });