/// /// Copyright 2015-2026 Micro Focus or one of its affiliates. /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// import { OverlayContainer } from '@angular/cdk/overlay'; import { Component, ViewChild } from '@angular/core'; import { ComponentFixture, fakeAsync, flushMicrotasks, inject, TestBed, tick, } from '@angular/core/testing'; import { TooltipDirective } from './tooltip.directive'; import { TooltipModule } from './tooltip.module'; @Component({ selector: 'app-tooltip-test', template: ` @if (showTrigger) { } `, imports: [TooltipModule], }) export class TooltipDirectiveSpecComponent { @ViewChild(TooltipDirective, { static: false }) tooltipDirective: TooltipDirective; isOpen: boolean = false; showTrigger: boolean = true; } describe('Tooltip Directive', () => { let component: TooltipDirectiveSpecComponent; let fixture: ComponentFixture; let overlayContainer: OverlayContainer; let overlayContainerElement: HTMLElement; beforeEach(() => { TestBed.configureTestingModule({ imports: [TooltipModule, TooltipDirectiveSpecComponent], }); fixture = TestBed.createComponent(TooltipDirectiveSpecComponent); component = fixture.componentInstance; fixture.detectChanges(); // access the overlay container inject([OverlayContainer], (oc: OverlayContainer) => { overlayContainer = oc; overlayContainerElement = oc.getContainerElement(); })(); }); afterEach(() => { overlayContainer.ngOnDestroy(); }); it('should show tooltip', fakeAsync(() => { const shownSpy = spyOn(component.tooltipDirective.shown, 'emit'); component.tooltipDirective.show(); tick(0); expect(getTooltip()).toBeTruthy(); expect(shownSpy).toHaveBeenCalledTimes(1); })); it('should show tooltip after delay', fakeAsync(() => { component.tooltipDirective.delay = 100; component.tooltipDirective.show(); tick(0); expect(getTooltip()).toBeFalsy(); tick(100); expect(getTooltip()).toBeTruthy(); })); it('should correctly destroy tooltip pending show', fakeAsync(() => { component.tooltipDirective.delay = 100; component.tooltipDirective.show(); tick(0); const tooltipDirective = component.tooltipDirective; component.showTrigger = false; fixture.detectChanges(); flushMicrotasks(); tick(100); expect(getTooltip()).toBeFalsy(); })); it('should not show tooltip when tooltip is disabled', fakeAsync(() => { component.tooltipDirective.disabled = true; component.tooltipDirective.show(); tick(0); expect(getTooltip()).toBeFalsy(); })); it('should apply the custom tooltip class', fakeAsync(() => { component.tooltipDirective.customClass = 'custom-tooltip-class'; component.tooltipDirective.show(); tick(0); expect(getTooltip()).toBeTruthy(); expect(getInnerTooltip().classList.contains('custom-tooltip-class')).toBeTruthy(); })); it('should apply the correct tooltip placement', fakeAsync(() => { component.tooltipDirective.placement = 'right'; component.tooltipDirective.show(); tick(0); expect(getTooltip()).toBeTruthy(); expect(getInnerTooltip().classList.contains('right')).toBeTruthy(); })); it('should show the correct tooltip content', fakeAsync(() => { component.tooltipDirective.show(); tick(0); expect(getTooltipContent()).toBe('Tooltip content here'); })); it('should show allow open state to be controlled via the isOpen input', fakeAsync(() => { component.isOpen = true; fixture.detectChanges(); tick(0); expect(getTooltip()).toBeTruthy(); // should also close component.isOpen = false; fixture.detectChanges(); tick(0); expect(getTooltip()).toBeFalsy(); })); function getTooltip(): HTMLElement | null { return document.querySelector('ux-tooltip'); } function getInnerTooltip(): HTMLElement | null { return getTooltip().querySelector('.tooltip'); } function getTooltipContent(): string { return getTooltip().querySelector('.tooltip-inner').innerText.trim(); } });