diff --git a/playwright/cps-ui-kit/components/cps-progress-linear.spec.ts b/playwright/cps-ui-kit/components/cps-progress-linear.spec.ts new file mode 100644 index 000000000..22c5e602c --- /dev/null +++ b/playwright/cps-ui-kit/components/cps-progress-linear.spec.ts @@ -0,0 +1,59 @@ +import { test, expect } from '@playwright/test'; + +test.describe('cps-progress-linear', () => { + test.beforeEach(async ({ page }) => { + await page.goto('/progress-linear'); + }); + + test.describe('Real CSS custom-property color/bgColor resolve to actual colors', () => { + test('color names real-resolve through the real stylesheet to their actual RGB values', async ({ + page + }) => { + const wrapper = page + .getByRole('progressbar', { name: 'Energy progress linear' }) + .getByTestId('cps-progress-linear'); + + await expect(wrapper).toHaveCSS('background-color', 'rgb(250, 236, 229)'); + await expect(wrapper.getByTestId('cps-progress-linear-inc')).toHaveCSS( + 'background-color', + 'rgb(255, 120, 15)' + ); + }); + }); + + test.describe('Real prefers-reduced-motion slows, not stops, both bars', () => { + test('reduced motion real-slows both bars while keeping them running', async ({ + page + }) => { + const wrapper = page + .getByRole('progressbar', { name: 'Energy progress linear' }) + .getByTestId('cps-progress-linear'); + const inc = wrapper.getByTestId('cps-progress-linear-inc'); + const dec = wrapper.getByTestId('cps-progress-linear-dec'); + + await expect(inc).toHaveCSS('animation-duration', '2s'); + await expect(inc).toHaveCSS('animation-iteration-count', 'infinite'); + await expect(dec).toHaveCSS('animation-duration', '2s'); + await expect(dec).toHaveCSS('animation-iteration-count', 'infinite'); + + await page.emulateMedia({ reducedMotion: 'reduce' }); + await page.reload(); + + const reducedWrapper = page + .getByRole('progressbar', { name: 'Energy progress linear' }) + .getByTestId('cps-progress-linear'); + const reducedInc = reducedWrapper.getByTestId('cps-progress-linear-inc'); + const reducedDec = reducedWrapper.getByTestId('cps-progress-linear-dec'); + await expect(reducedInc).toHaveCSS('animation-duration', '6s'); + await expect(reducedInc).toHaveCSS( + 'animation-iteration-count', + 'infinite' + ); + await expect(reducedDec).toHaveCSS('animation-duration', '6s'); + await expect(reducedDec).toHaveCSS( + 'animation-iteration-count', + 'infinite' + ); + }); + }); +}); diff --git a/projects/composition/src/app/pages/progress-linear-page/progress-linear-page.component.html b/projects/composition/src/app/pages/progress-linear-page/progress-linear-page.component.html index eb1e96dba..f2b7b8be1 100644 --- a/projects/composition/src/app/pages/progress-linear-page/progress-linear-page.component.html +++ b/projects/composition/src/app/pages/progress-linear-page/progress-linear-page.component.html @@ -4,6 +4,7 @@
diff --git a/projects/cps-ui-kit/src/lib/directives/cps-tooltip/cps-tooltip.directive.ts b/projects/cps-ui-kit/src/lib/directives/cps-tooltip/cps-tooltip.directive.ts index 195f8ab47..21c577ab9 100644 --- a/projects/cps-ui-kit/src/lib/directives/cps-tooltip/cps-tooltip.directive.ts +++ b/projects/cps-ui-kit/src/lib/directives/cps-tooltip/cps-tooltip.directive.ts @@ -191,12 +191,15 @@ export class CpsTooltipDirective implements OnDestroy { // Tab from the trigger moves focus into the persistent tooltip instead of // the next page element, so keyboard users can interact with tooltip content. + // preventScroll avoids the browser's own scroll-into-view side effect, + // which would otherwise fire a real scroll event and immediately destroy + // the very tooltip focus just moved into (see _onScrollDestroy). onTabFromTrigger(event: Event): void { if (!this.tooltipPersistent() || !this._popup) return; const focusable = this._focusableIn(this._popup); if (!focusable.length) return; event.preventDefault(); - focusable[0].focus(); + focusable[0].focus({ preventScroll: true }); } onClick(): void { @@ -237,10 +240,10 @@ export class CpsTooltipDirective implements OnDestroy { const last = focusable[focusable.length - 1]; const active = this._document.activeElement; if (!event.shiftKey && active === last) { - this._ariaTarget?.focus(); + this._ariaTarget?.focus({ preventScroll: true }); } else if (event.shiftKey && active === first) { event.preventDefault(); - this._ariaTarget?.focus(); + this._ariaTarget?.focus({ preventScroll: true }); } };