From d8115c068fc167d5b790a285b60fa3006ce22a51 Mon Sep 17 00:00:00 2001 From: Maximilien B Date: Mon, 16 Feb 2026 15:22:57 +0100 Subject: [PATCH 1/2] Updated: custom tooltip assertion on disabled elements - and GREATLY improve assertion time --- .../custom-assertions/tooltip.ts | 20 +++++++- addon/modifiers/enable-tooltip.ts | 4 +- .../modifiers/enable-tooltip-test.ts | 46 ++++++++++++++++++- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/addon-test-support/custom-assertions/tooltip.ts b/addon-test-support/custom-assertions/tooltip.ts index 8ff8d6ddc..c51f6e0fc 100644 --- a/addon-test-support/custom-assertions/tooltip.ts +++ b/addon-test-support/custom-assertions/tooltip.ts @@ -1,11 +1,24 @@ import { triggerEvent, waitFor } from '@ember/test-helpers'; import * as QUnit from 'qunit'; import { isEmpty } from '@ember/utils'; +import sinon from 'sinon'; +import { ANIMATION_DURATION, RENDERING_DELAY } from '@upfluence/oss-components/modifiers/enable-tooltip'; export type Placement = 'top' | 'bottom' | 'left' | 'right' | undefined; async function triggerEventOnElement(selector: string, trigger?: string) { - await triggerEvent(selector, trigger || 'mouseover'); + const element = document.querySelector(selector) as HTMLElement; + const clock = sinon.useFakeTimers(); + + if (element?.hasAttribute('disabled')) { + element.dispatchEvent(new Event(trigger || 'mouseover', { bubbles: true })); + } else { + await triggerEvent(selector, trigger || 'mouseover'); + } + + clock.tick(RENDERING_DELAY + ANIMATION_DURATION); + clock.restore(); + await waitFor('.upf-tooltip'); } @@ -41,9 +54,12 @@ const assertion = (selector: string) => { doesNotExist: async (trigger?: string, message?: string) => { let result: boolean = false; let actual: Element | null = null; + const clock = sinon.useFakeTimers(); await triggerEvent(selector, trigger || 'mouseover'); - await waitFor('.upf-tooltip', { timeout: 350 }) + clock.tick(RENDERING_DELAY + ANIMATION_DURATION); + clock.restore(); + await waitFor('.upf-tooltip', { timeout: 50 }) .catch((err) => { if (err.message === 'waitFor timed out waiting for selector ".upf-tooltip"') { result = true; diff --git a/addon/modifiers/enable-tooltip.ts b/addon/modifiers/enable-tooltip.ts index 6dfd2066f..45de94f67 100644 --- a/addon/modifiers/enable-tooltip.ts +++ b/addon/modifiers/enable-tooltip.ts @@ -30,8 +30,8 @@ type EnableTooltipState = { isRendered: boolean; }; -const ANIMATION_DURATION = 250; -const RENDERING_DELAY = 300; +export const ANIMATION_DURATION = 250; +export const RENDERING_DELAY = 300; const DEFAULT_CONFIGURATION = { placement: 'bottom' as Placement, trigger: 'hover focus', diff --git a/tests/integration/components/modifiers/enable-tooltip-test.ts b/tests/integration/components/modifiers/enable-tooltip-test.ts index 26fc82099..7f51e75a9 100644 --- a/tests/integration/components/modifiers/enable-tooltip-test.ts +++ b/tests/integration/components/modifiers/enable-tooltip-test.ts @@ -16,7 +16,7 @@ module('Integration | Component | modifiers/enable-tooltip', function (hooks) { async function renderTooltip() { await render(hbs`
+ {{enable-tooltip title=this.title subtitle=this.subtitle placement=this.placement icon=this.icon trigger=this.trigger html=this.html}}>
`); } @@ -145,4 +145,48 @@ module('Integration | Component | modifiers/enable-tooltip', function (hooks) { await assert.tooltip('.test-container').isNotHtmlSafe(); }); }); + + module('works on disabled elements', () => { + async function renderDisabledButton() { + await render(hbs` + + `); + } + + test('it renders the tooltip on disabled button and using the custom assertion can verify its existence', async function (assert) { + await renderDisabledButton(); + + await assert.tooltip('.test-button').exists(); + }); + + test('it renders the tooltip on disabled button and using the custom assertion can verify its title', async function (assert) { + await renderDisabledButton(); + + await assert.tooltip('.test-button').hasTitle(this.title); + }); + + test('it renders the tooltip on disabled button and using the custom assertion can verify its subtitle', async function (assert) { + this.subtitle = 'subtitle'; + await renderDisabledButton(); + + await assert.tooltip('.test-button').hasSubtitle(this.subtitle); + }); + + test('it renders the tooltip on disabled button and using the custom assertion can verify its icon', async function (assert) { + this.icon = 'far fa-wine-glass-alt'; + await renderDisabledButton(); + + await assert.tooltip('.test-button').hasIcon(this.icon); + }); + + test('it renders the tooltip on disabled button and using the custom assertion can verify its placement', async function (assert) { + this.placement = 'top'; + await renderDisabledButton(); + + await assert.tooltip('.test-button').hasPlacement(this.placement); + }); + }); }); From 6faa41c112315ba13341da7b17c01c340ba3ac96 Mon Sep 17 00:00:00 2001 From: Maximilien B Date: Mon, 16 Feb 2026 16:35:58 +0100 Subject: [PATCH 2/2] Fixed: PR comments --- .../custom-assertions/tooltip.ts | 26 +++---- .../modifiers/enable-tooltip-test.ts | 72 +++++++++++++------ 2 files changed, 64 insertions(+), 34 deletions(-) diff --git a/addon-test-support/custom-assertions/tooltip.ts b/addon-test-support/custom-assertions/tooltip.ts index c51f6e0fc..80c2d8d91 100644 --- a/addon-test-support/custom-assertions/tooltip.ts +++ b/addon-test-support/custom-assertions/tooltip.ts @@ -6,20 +6,22 @@ import { ANIMATION_DURATION, RENDERING_DELAY } from '@upfluence/oss-components/m export type Placement = 'top' | 'bottom' | 'left' | 'right' | undefined; -async function triggerEventOnElement(selector: string, trigger?: string) { +async function triggerEventOnElement(selector: string, trigger: string = 'mouseover') { const element = document.querySelector(selector) as HTMLElement; const clock = sinon.useFakeTimers(); - if (element?.hasAttribute('disabled')) { - element.dispatchEvent(new Event(trigger || 'mouseover', { bubbles: true })); - } else { - await triggerEvent(selector, trigger || 'mouseover'); - } - - clock.tick(RENDERING_DELAY + ANIMATION_DURATION); - clock.restore(); + try { + if (element?.hasAttribute('disabled')) { + element.dispatchEvent(new MouseEvent(trigger, { bubbles: true })); + } else { + await triggerEvent(selector, trigger); + } - await waitFor('.upf-tooltip'); + clock.tick(RENDERING_DELAY + ANIMATION_DURATION); + await waitFor('.upf-tooltip'); + } finally { + clock.restore(); + } } export interface TooltipAssertions { @@ -51,12 +53,12 @@ const assertion = (selector: string) => { }); }, - doesNotExist: async (trigger?: string, message?: string) => { + doesNotExist: async (trigger: string = 'mouseover', message?: string) => { let result: boolean = false; let actual: Element | null = null; const clock = sinon.useFakeTimers(); - await triggerEvent(selector, trigger || 'mouseover'); + await triggerEvent(selector, trigger); clock.tick(RENDERING_DELAY + ANIMATION_DURATION); clock.restore(); await waitFor('.upf-tooltip', { timeout: 50 }) diff --git a/tests/integration/components/modifiers/enable-tooltip-test.ts b/tests/integration/components/modifiers/enable-tooltip-test.ts index 7f51e75a9..db743106b 100644 --- a/tests/integration/components/modifiers/enable-tooltip-test.ts +++ b/tests/integration/components/modifiers/enable-tooltip-test.ts @@ -74,34 +74,34 @@ module('Integration | Component | modifiers/enable-tooltip', function (hooks) { }); test('When content has no overflow, it does not display tooltip on hover', async function (assert) { await render(hbs` -
- abc -
- `); +
+ abc +
+ `); await assert.tooltip('.test-container').doesNotExist(); }); test('When content has overflow, it displays tooltip on hover', async function (assert) { await render(hbs` -
- abcdefghijklmnopqrstuvwxyz -
- `); +
+ abcdefghijklmnopqrstuvwxyz +
+ `); await assert.tooltip('.test-container').exists(); }); @@ -188,5 +188,33 @@ module('Integration | Component | modifiers/enable-tooltip', function (hooks) { await assert.tooltip('.test-button').hasPlacement(this.placement); }); + + test("it renders the tooltip on disabled button and using the custom assertion can verify it doesn't have an icon", async function (assert) { + await renderDisabledButton(); + + await assert.tooltip('.test-button').doesNotHaveIcon(); + }); + + test("it renders the tooltip on disabled button and using the custom assertion can verify it doesn't have a subtitle", async function (assert) { + await renderDisabledButton(); + + await assert.tooltip('.test-button').doesNotHaveSubtitle(); + }); + + module('html attribute', () => { + test('it renders the tooltip on disabled button and using the custom assertion can verify its html safe mode', async function (assert) { + this.html = true; + await renderDisabledButton(); + + await assert.tooltip('.test-button').isHtmlSafe(); + }); + + test('it renders the tooltip on disabled button and using the custom assertion can verify it is not in html safe mode', async function (assert) { + this.html = false; + await renderDisabledButton(); + + await assert.tooltip('.test-button').isNotHtmlSafe(); + }); + }); }); });