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  });