go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/common/components/tooltip/tooltip.test.ts (about) 1 // Copyright 2021 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 import { aTimeout, fixture, html } from '@open-wc/testing-helpers'; 16 17 import './tooltip'; 18 import { 19 HideTooltipEventDetail, 20 ShowTooltipEventDetail, 21 TooltipElement, 22 } from './tooltip'; 23 24 describe('Tooltip', () => { 25 test('should only display one tooltip at a time', async () => { 26 const tooltipContainer = await fixture<TooltipElement>( 27 html`<milo-tooltip></milo-tooltip>`, 28 ); 29 30 const tooltip1 = document.createElement('div'); 31 const tooltip2 = document.createElement('div'); 32 33 window.dispatchEvent( 34 new CustomEvent<ShowTooltipEventDetail>('show-tooltip', { 35 detail: { 36 tooltip: tooltip1, 37 targetRect: tooltipContainer.getBoundingClientRect(), 38 gapSize: 5, 39 }, 40 }), 41 ); 42 43 await aTimeout(0); 44 expect(tooltip1.isConnected).toBeTruthy(); 45 expect(tooltip2.isConnected).toBeFalsy(); 46 47 window.dispatchEvent( 48 new CustomEvent<ShowTooltipEventDetail>('show-tooltip', { 49 detail: { 50 tooltip: tooltip2, 51 targetRect: tooltipContainer.getBoundingClientRect(), 52 gapSize: 5, 53 }, 54 }), 55 ); 56 57 await aTimeout(0); 58 expect(tooltip1.isConnected).toBeFalsy(); 59 expect(tooltip2.isConnected).toBeTruthy(); 60 }); 61 62 test('should hide tooltip after specified delay', async () => { 63 const tooltipContainer = await fixture<TooltipElement>( 64 html`<milo-tooltip></milo-tooltip>`, 65 ); 66 67 const tooltip = document.createElement('div'); 68 69 window.dispatchEvent( 70 new CustomEvent<ShowTooltipEventDetail>('show-tooltip', { 71 detail: { 72 tooltip, 73 targetRect: tooltipContainer.getBoundingClientRect(), 74 gapSize: 5, 75 }, 76 }), 77 ); 78 79 await aTimeout(0); 80 expect(tooltip.isConnected).toBeTruthy(); 81 82 window.dispatchEvent( 83 new CustomEvent<HideTooltipEventDetail>('hide-tooltip', { 84 detail: { delay: 10 }, 85 }), 86 ); 87 88 await aTimeout(5); 89 expect(tooltip.isConnected).toBeTruthy(); 90 91 await aTimeout(5); 92 expect(tooltip.isConnected).toBeFalsy(); 93 }); 94 95 test('should handle race condition correctly', async () => { 96 const tooltipContainer = await fixture<TooltipElement>( 97 html`<milo-tooltip></milo-tooltip>`, 98 ); 99 100 const tooltip1 = document.createElement('div'); 101 const tooltip2 = document.createElement('div'); 102 103 window.dispatchEvent( 104 new CustomEvent<ShowTooltipEventDetail>('show-tooltip', { 105 detail: { 106 tooltip: tooltip1, 107 targetRect: tooltipContainer.getBoundingClientRect(), 108 gapSize: 5, 109 }, 110 }), 111 ); 112 113 await aTimeout(0); 114 expect(tooltip1.isConnected).toBeTruthy(); 115 116 window.dispatchEvent( 117 new CustomEvent<HideTooltipEventDetail>('hide-tooltip', { 118 detail: { delay: 10 }, 119 }), 120 ); 121 122 await aTimeout(0); 123 expect(tooltip1.isConnected).toBeTruthy(); 124 125 // Show another tooltip before the first one is dismissed. 126 window.dispatchEvent( 127 new CustomEvent<ShowTooltipEventDetail>('show-tooltip', { 128 detail: { 129 tooltip: tooltip2, 130 targetRect: tooltipContainer.getBoundingClientRect(), 131 gapSize: 5, 132 }, 133 }), 134 ); 135 136 await aTimeout(10); 137 expect(tooltip1.isConnected).toBeFalsy(); 138 expect(tooltip2.isConnected).toBeTruthy(); 139 }); 140 });