1- import { html , fixture , expect } from '@open-wc/testing' ;
1+ import { html , fixture , expect , aTimeout } from '@open-wc/testing' ;
22import { UUIPopoverContainerElement } from './uui-popover-container.element' ;
33import '@umbraco-ui/uui-button/lib' ;
44
5+ class DummyElementWithShadowDom extends HTMLElement {
6+ constructor ( ) {
7+ super ( ) ;
8+ this . attachShadow ( { mode : 'open' } ) ;
9+ this . shadowRoot ! . innerHTML = `<div style="height: 200px; overflow: auto;" id="scrollable-div">
10+ <slot></slot>
11+ </div>` ;
12+ }
13+ }
14+ customElements . define ( 'dummy-shadow-dom' , DummyElementWithShadowDom ) ;
15+
516describe ( 'UUIPopoverContainerElement' , ( ) => {
617 let element : UUIPopoverContainerElement ;
718
@@ -32,7 +43,48 @@ describe('UUIPopoverContainerElement', () => {
3243 const testContainer = await fixture ( html `
3344 < main >
3445 < div style ="height: 300px; overflow: auto; " id ="outer-scroll ">
35- < div style ="height: 200px; overflow: auto; " id ="inner-scroll ">
46+ < dummy-shadow-dom >
47+ < div style ="height: 200px; overflow: auto; " id ="inner-scroll ">
48+ < div style ="height: 100px; "> </ div >
49+ < uui-button id ="trigger-button " popovertarget ="test-popover "
50+ > Open</ uui-button
51+ >
52+ < div style ="height: 400px; "> </ div >
53+ </ div >
54+ </ dummy-shadow-dom >
55+ < div style ="height: 500px; "> </ div >
56+ </ div >
57+ < uui-popover-container id ="test-popover " popover >
58+ Test content
59+ </ uui-popover-container >
60+ </ main >
61+ ` ) ;
62+
63+ const popover = testContainer . querySelector (
64+ '#test-popover' ,
65+ ) as UUIPopoverContainerElement ;
66+ const button = testContainer . querySelector ( '#trigger-button' ) ;
67+
68+ // Trigger the popover open
69+ button ?. click ( ) ;
70+ await aTimeout ( 100 ) ;
71+
72+ // Access the private scroll parents array for testing
73+ const scrollParents = popover . _getScrollParents ( ) ;
74+
75+ // Should find both scroll containers
76+ expect ( scrollParents . length ) . to . be . greaterThan ( 0 ) ;
77+
78+ // Should include the document.body as the last element
79+ expect ( scrollParents [ scrollParents . length - 1 ] ) . to . equal ( document . body ) ;
80+ } ) ;
81+
82+ it ( 'should ignore scroll parents with position: absolute' , async ( ) => {
83+ // Create a test structure with nested shadow DOM and scroll containers
84+ const testContainer = await fixture ( html `
85+ < main >
86+ < div style ="height: 300px; overflow: auto; " id ="outer-scroll ">
87+ < div style ="position: absolute; top:0; left:0; " id ="inner-scroll ">
3688 < div style ="height: 100px; "> </ div >
3789 < uui-button id ="trigger-button " popovertarget ="test-popover "
3890 > Open</ uui-button
@@ -50,20 +102,20 @@ describe('UUIPopoverContainerElement', () => {
50102 const popover = testContainer . querySelector (
51103 '#test-popover' ,
52104 ) as UUIPopoverContainerElement ;
105+ const innerScroll = testContainer . querySelector (
106+ '#inner-scroll' ,
107+ ) as HTMLElement ;
53108 const button = testContainer . querySelector ( '#trigger-button' ) ;
54109
55110 // Trigger the popover open
56111 button ?. click ( ) ;
57- await new Promise ( resolve => setTimeout ( resolve , 100 ) ) ;
112+ await aTimeout ( 100 ) ;
58113
59114 // Access the private scroll parents array for testing
60115 const scrollParents = popover . _getScrollParents ( ) ;
61116
62- // Should find both scroll containers
63- expect ( scrollParents . length ) . to . be . greaterThan ( 0 ) ;
64-
65- // Should include the document.body as the last element
66- expect ( scrollParents [ scrollParents . length - 1 ] ) . to . equal ( document . body ) ;
117+ // Should not contain the inner scroll since it's position: absolute
118+ expect ( scrollParents ) . to . not . include ( innerScroll ) ;
67119 } ) ;
68120
69121 it ( 'should reset scroll parents when called multiple times' , async ( ) => {
@@ -88,12 +140,12 @@ describe('UUIPopoverContainerElement', () => {
88140
89141 // Open and close the popover multiple times
90142 button ?. click ( ) ;
91- await new Promise ( resolve => setTimeout ( resolve , 50 ) ) ;
143+ await aTimeout ( 50 ) ;
92144 popover . hidePopover ( ) ;
93- await new Promise ( resolve => setTimeout ( resolve , 50 ) ) ;
145+ await aTimeout ( 50 ) ;
94146
95147 button ?. click ( ) ;
96- await new Promise ( resolve => setTimeout ( resolve , 50 ) ) ;
148+ await aTimeout ( 50 ) ;
97149
98150 const scrollParents = popover . _getScrollParents ( ) ;
99151
0 commit comments