From f791e3c02feaed015b2babd3b9c5a3733a6a1a4d Mon Sep 17 00:00:00 2001 From: Stoyan Date: Fri, 12 Jun 2026 09:25:50 +0300 Subject: [PATCH] test(ui5-datetime-picker): unskip unstable test --- packages/main/cypress/specs/DateTimePicker.cy.tsx | 10 +--------- packages/main/src/Calendar.ts | 10 ++++++++-- packages/main/src/DayPicker.ts | 3 ++- packages/main/src/TimeSelectionClocks.ts | 14 ++++++++++---- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/packages/main/cypress/specs/DateTimePicker.cy.tsx b/packages/main/cypress/specs/DateTimePicker.cy.tsx index 837371e45285..db29848bcdee 100644 --- a/packages/main/cypress/specs/DateTimePicker.cy.tsx +++ b/packages/main/cypress/specs/DateTimePicker.cy.tsx @@ -343,15 +343,7 @@ describe("DateTimePicker general interaction", () => { .ui5DateTimePickerClose(); }); - // Skipped: this test has been failing intermittently on CI for weeks. - // The "Unstable test, needs investigation" note below has been there from before. - // Root cause appears to be a focus race in TimeSelectionClocks._activateClock, - // which waits for `animationend` to advance focus between hours/minutes/seconds. - // When animations are disabled (as this test does via setAnimationMode(None)), - // `animationend` never fires, so the next clock button never becomes focused. - // Skipping until the underlying component is fixed. - //Unstable test, needs investigation - it.skip("tests selection of 12:34:56 AM", () => { + it("tests selection of 12:34:56 AM", () => { setAnimationMode(AnimationMode.None); cy.mount(); diff --git a/packages/main/src/Calendar.ts b/packages/main/src/Calendar.ts index e012dc354379..5c8043978d8f 100644 --- a/packages/main/src/Calendar.ts +++ b/packages/main/src/Calendar.ts @@ -27,7 +27,7 @@ import CalendarDate from "./CalendarDate.js"; import CalendarDateRange from "./CalendarDateRange.js"; import "./SpecialCalendarDate.js"; import CalendarPart from "./CalendarPart.js"; -import type { DayPickerChangeEventDetail } from "./DayPicker.js"; +import type { DayPickerChangeEventDetail, DayPickerNavigateEventDetail } from "./DayPicker.js"; import type { MonthPickerChangeEventDetail } from "./MonthPicker.js"; import type { YearPickerChangeEventDetail } from "./YearPicker.js"; import CalendarSelectionMode from "./types/CalendarSelectionMode.js"; @@ -918,8 +918,14 @@ class Calendar extends CalendarPart { this.switchToYearPicker(); } - async onNavigate(e: CustomEvent) { + async onNavigate(e: CustomEvent) { this.timestamp = e.detail.timestamp; + // Mouse-driven navigation handles its own focus; the click already landed + // where the user wants. Refocusing after the deferred render would steal + // focus from a sibling component (e.g. a time picker in DateTimePicker). + if (e.detail.mouse) { + return; + } await renderFinished(); this._currentPickerDOM.focus(); } diff --git a/packages/main/src/DayPicker.ts b/packages/main/src/DayPicker.ts index f47dc63d4c6f..25a793bd42a1 100644 --- a/packages/main/src/DayPicker.ts +++ b/packages/main/src/DayPicker.ts @@ -104,6 +104,7 @@ type DayPickerChangeEventDetail = { type DayPickerNavigateEventDetail = { timestamp: number, + mouse?: boolean, } /** @@ -612,7 +613,7 @@ class DayPicker extends CalendarPart implements ICalendarPicker { } this._safelySetTimestamp(this._getTimestampFromDom(target)); - this.fireDecoratorEvent("navigate", { timestamp: this.timestamp! }); + this.fireDecoratorEvent("navigate", { timestamp: this.timestamp!, mouse: true }); } /** diff --git a/packages/main/src/TimeSelectionClocks.ts b/packages/main/src/TimeSelectionClocks.ts index 9ab39f1922a9..7cf14c9b979c 100644 --- a/packages/main/src/TimeSelectionClocks.ts +++ b/packages/main/src/TimeSelectionClocks.ts @@ -1,6 +1,8 @@ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js"; +import AnimationMode from "@ui5/webcomponents-base/dist/types/AnimationMode.js"; +import { getAnimationMode } from "@ui5/webcomponents-base/dist/config/AnimationMode.js"; import "@ui5/webcomponents-localization/dist/features/calendar/Gregorian.js"; // default calendar for bundling import { isDown, @@ -416,6 +418,10 @@ class TimeSelectionClocks extends TimePickerInternals { return; } + if (getAnimationMode() === AnimationMode.None) { + skipAnimation = true; + } + const currentClockComponent = this._clockComponent(this._activeIndex); const newClockComponent = this._clockComponent(clockIndex); @@ -428,7 +434,7 @@ class TimeSelectionClocks extends TimePickerInternals { newClockComponent._skipAnimation = true; this._activateClock(clockIndex); } else { - currentClockComponent?._firstNumberElement?.addEventListener("animationend", () => this._activateClock(clockIndex), { once: true }); + currentClockComponent?._firstNumberElement?.addEventListener("animationend", () => { this._activateClock(clockIndex); }, { once: true }); currentClockComponent?._clockWrapper?.classList.add("ui5-tp-clock-transition"); } } @@ -438,12 +444,12 @@ class TimeSelectionClocks extends TimePickerInternals { * @param clockIndex the index of the clock to be activated */ _activateClock(clockIndex: number) { - const newButton = this._buttonComponent(clockIndex); - this._entities[this._activeIndex].active = false; this._activeIndex = clockIndex; this._entities[this._activeIndex].active = true; - newButton && newButton.focus(); + + const newButton = this._buttonComponent(clockIndex); + newButton?.getFocusDomRef()?.focus(); } /**