From fb25448e03c7d849a515b4bbe771f72862f271a6 Mon Sep 17 00:00:00 2001 From: Eldar Iusupzhanov Date: Tue, 31 Mar 2026 20:20:52 +0800 Subject: [PATCH 1/4] rewrite testcafe test to jest --- .../scheduler/common/deleteAppointments.ts | 102 -------- .../__tests__/__mock__/model/popup.ts | 8 + .../__tests__/__mock__/model/scheduler.ts | 16 ++ .../__tests__/__mock__/model/tooltip.ts | 38 +++ .../__tests__/appointment_tooltip.test.ts | 217 ++++++++++++++++++ .../scheduler/__tests__/appointments.test.ts | 82 ++++++- .../js/__internal/scheduler/m_scheduler.ts | 1 + 7 files changed, 359 insertions(+), 105 deletions(-) delete mode 100644 e2e/testcafe-devextreme/tests/scheduler/common/deleteAppointments.ts create mode 100644 packages/devextreme/js/__internal/scheduler/__tests__/__mock__/model/tooltip.ts create mode 100644 packages/devextreme/js/__internal/scheduler/__tests__/appointment_tooltip.test.ts diff --git a/e2e/testcafe-devextreme/tests/scheduler/common/deleteAppointments.ts b/e2e/testcafe-devextreme/tests/scheduler/common/deleteAppointments.ts deleted file mode 100644 index a68b8a792f7f..000000000000 --- a/e2e/testcafe-devextreme/tests/scheduler/common/deleteAppointments.ts +++ /dev/null @@ -1,102 +0,0 @@ -import Scheduler from 'devextreme-testcafe-models/scheduler'; -import { createWidget } from '../../../helpers/createWidget'; -import url from '../../../helpers/getPageUrl'; - -fixture.disablePageReloads`Delete appointments` - .page(url(__dirname, '../../container.html')); - -const createRecurrenceData = (): Record[] => [{ - Text: 'Text', - StartDate: new Date(2017, 4, 22, 1, 30, 0, 0), - EndDate: new Date(2017, 4, 22, 2, 30, 0, 0), - RecurrenceRule: 'FREQ=DAILY', -}]; - -const createScheduler = async (data): Promise => { - await createWidget('dxScheduler', { - dataSource: data, - views: ['week'], - currentView: 'week', - currentDate: new Date(2017, 4, 22), - textExpr: 'Text', - startDateExpr: 'StartDate', - endDateExpr: 'EndDate', - allDayExpr: 'AllDay', - recurrenceRuleExpr: 'RecurrenceRule', - recurrenceExceptionExpr: 'RecurrenceException', - }); -}; - -const createSimpleData = (): Record[] => [{ - Text: 'Text', - StartDate: new Date(2017, 4, 22, 1, 30, 0, 0), - EndDate: new Date(2017, 4, 22, 2, 30, 0, 0), -}, { - Text: 'Text2', - StartDate: new Date(2017, 4, 22, 12, 0, 0, 0), - EndDate: new Date(2017, 4, 22, 13, 0, 0, 0), -}]; - -test('Recurrence appointments should be deleted by click on \'delete\' button', async (t) => { - const scheduler = new Scheduler('#container'); - - await t - .expect(scheduler.getAppointmentCount()).eql(6) - .click(scheduler.getAppointment('Text', 3).element) - - .expect(scheduler.appointmentTooltip.element.exists) - .ok() - .click(scheduler.appointmentTooltip.deleteButton) - .click(Scheduler.getDeleteRecurrenceDialog().appointment) - .wait(100) - - .expect(scheduler.getAppointmentCount()) - .eql(5); - - await t - .click(scheduler.getAppointment('Text', 3).element) - - .click(scheduler.appointmentTooltip.deleteButton) - .click(Scheduler.getDeleteRecurrenceDialog().series) - - .expect(scheduler.getAppointmentCount()) - .eql(0); -}).before(async () => createScheduler(createRecurrenceData())); - -test('Recurrence appointments should be deleted by press \'delete\' key', async (t) => { - const scheduler = new Scheduler('#container'); - - await t - .expect(scheduler.getAppointmentCount()).eql(6) - .click(scheduler.getAppointment('Text', 3).element) - .pressKey('delete') - .click(Scheduler.getDeleteRecurrenceDialog().appointment) - .wait(100) - .expect(scheduler.getAppointmentCount()) - .eql(5); - - await t - .click(scheduler.getAppointment('Text', 3).element) - .pressKey('delete') - .click(Scheduler.getDeleteRecurrenceDialog().series) - .expect(scheduler.getAppointmentCount()) - .eql(0); -}).before(async () => createScheduler(createRecurrenceData())); - -test('Common appointments should be deleted by click on \'delete\' button and press \'delete\' key', async (t) => { - const scheduler = new Scheduler('#container'); - - await t - .expect(scheduler.getAppointmentCount()).eql(2) - .click(scheduler.getAppointment('Text').element) - .click(scheduler.appointmentTooltip.deleteButton) - .expect(scheduler.getAppointmentCount()) - .eql(1); - - await t - .expect(scheduler.getAppointmentCount()).eql(1) - .click(scheduler.getAppointment('Text2').element) - .pressKey('delete') - .expect(scheduler.getAppointmentCount()) - .eql(0); -}).before(async () => createScheduler(createSimpleData())); diff --git a/packages/devextreme/js/__internal/scheduler/__tests__/__mock__/model/popup.ts b/packages/devextreme/js/__internal/scheduler/__tests__/__mock__/model/popup.ts index d901240db91c..dd0757e23655 100644 --- a/packages/devextreme/js/__internal/scheduler/__tests__/__mock__/model/popup.ts +++ b/packages/devextreme/js/__internal/scheduler/__tests__/__mock__/model/popup.ts @@ -72,10 +72,18 @@ export class PopupModel { return this.queries.getByRole('button', { name: 'Edit series' }) as HTMLElement; } + get deleteSeriesButton(): HTMLElement { + return this.queries.getByRole('button', { name: 'Delete series' }) as HTMLElement; + } + get editAppointmentButton(): HTMLElement { return this.queries.getByRole('button', { name: 'Edit appointment' }) as HTMLElement; } + get deleteAppointmentButton(): HTMLElement { + return this.queries.getByRole('button', { name: 'Delete appointment' }) as HTMLElement; + } + get recurrenceSettingsButton(): HTMLElement { return queryRequiredElement(this.element, '.dx-scheduler-form-recurrence-settings-button'); } diff --git a/packages/devextreme/js/__internal/scheduler/__tests__/__mock__/model/scheduler.ts b/packages/devextreme/js/__internal/scheduler/__tests__/__mock__/model/scheduler.ts index 946fb15ad4ea..fecaf1f7b029 100644 --- a/packages/devextreme/js/__internal/scheduler/__tests__/__mock__/model/scheduler.ts +++ b/packages/devextreme/js/__internal/scheduler/__tests__/__mock__/model/scheduler.ts @@ -6,6 +6,7 @@ import { POPUP_DIALOG_CLASS } from '../../../m_scheduler'; import type { AppointmentModel } from './appointment'; import { createAppointmentModel } from './appointment'; import { PopupModel } from './popup'; +import { TooltipModel } from './tooltip'; const getTexts = ( cells: ArrayLike, @@ -25,6 +26,10 @@ export class SchedulerModel { return this.getPopup(); } + get tooltip(): TooltipModel { + return new TooltipModel(); + } + get toolbar(): ToolbarModel { return new ToolbarModel(this.queries.getByRole('toolbar')); } @@ -55,6 +60,17 @@ export class SchedulerModel { return getTexts(collectors); } + getCollectorButton(index = 0): HTMLElement { + const allButtons = this.queries.queryAllByRole('button') as HTMLElement[]; + const collectors = allButtons.filter((btn) => btn.classList.contains('dx-scheduler-appointment-collector')); + + if (collectors.length === 0) { + throw new Error('Collector button not found'); + } + + return collectors[index]; + } + getDateTableContent(): string[] { const cells = this.container.querySelectorAll('.dx-scheduler-date-table-cell'); return getTexts(cells); diff --git a/packages/devextreme/js/__internal/scheduler/__tests__/__mock__/model/tooltip.ts b/packages/devextreme/js/__internal/scheduler/__tests__/__mock__/model/tooltip.ts new file mode 100644 index 000000000000..6444af4f4e57 --- /dev/null +++ b/packages/devextreme/js/__internal/scheduler/__tests__/__mock__/model/tooltip.ts @@ -0,0 +1,38 @@ +import { within } from '@testing-library/dom'; + +const TOOLTIP_WRAPPER_SELECTOR = '.dx-overlay-wrapper.dx-scheduler-appointment-tooltip-wrapper'; + +export class TooltipModel { + private get element(): HTMLElement | null { + return document.querySelector(TOOLTIP_WRAPPER_SELECTOR); + } + + isVisible(): boolean { + return this.element !== null; + } + + getScrollableContent(): Element | null { + return this.element?.querySelector('.dx-scrollable .dx-scrollview-content') ?? null; + } + + getDeleteButton(index = 0): HTMLElement { + const tooltip = this.element; + const buttons = tooltip + ? within(tooltip).queryAllByRole('button').filter((btn) => btn.classList.contains('dx-tooltip-appointment-item-delete-button')) + : []; + + if (buttons.length === 0) { + throw new Error('Tooltip delete button not found'); + } + + return buttons[index]; + } + + getAppointmentItem(index = 0): HTMLElement | null { + const tooltip = this.element; + if (!tooltip) { + return null; + } + return within(tooltip).queryAllByRole('option')[index] ?? null; + } +} diff --git a/packages/devextreme/js/__internal/scheduler/__tests__/appointment_tooltip.test.ts b/packages/devextreme/js/__internal/scheduler/__tests__/appointment_tooltip.test.ts new file mode 100644 index 000000000000..e0dbabbbb0e4 --- /dev/null +++ b/packages/devextreme/js/__internal/scheduler/__tests__/appointment_tooltip.test.ts @@ -0,0 +1,217 @@ +import { + afterEach, beforeEach, describe, expect, it, jest, +} from '@jest/globals'; +import fx from '@js/common/core/animation/fx'; + +import { createScheduler } from './__mock__/create_scheduler'; +import { setupSchedulerTestEnvironment } from './__mock__/m_mock_scheduler'; + +describe('Appointment tooltip behavior', () => { + beforeEach(() => { + fx.off = true; + setupSchedulerTestEnvironment(); + }); + + afterEach(() => { + fx.off = false; + jest.useRealTimers(); + document.body.innerHTML = ''; + }); + + describe('Deleting appointments', () => { + it('should delete appointment by Delete key when focused in tooltip from collector', async () => { + const data = [ + { + text: 'Apt1', + startDate: new Date(2017, 4, 22, 9, 30), + endDate: new Date(2017, 4, 22, 10, 30), + }, + { + text: 'Apt2', + startDate: new Date(2017, 4, 22, 9, 30), + endDate: new Date(2017, 4, 22, 10, 30), + }, + ]; + + const { scheduler, POM } = await createScheduler({ + dataSource: [...data], + views: [{ type: 'month', maxAppointmentsPerCell: 1 }], + currentView: 'month', + currentDate: new Date(2017, 4, 22), + height: 600, + }); + + POM.getCollectorButton().click(); + + const tooltipScrollableContent = POM.tooltip.getScrollableContent(); + tooltipScrollableContent?.dispatchEvent(new FocusEvent('focusin', { bubbles: true })); + tooltipScrollableContent?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Delete', bubbles: true })); + + expect(POM.tooltip.isVisible()).toBe(false); + expect((scheduler as any).getDataSource().items()).toEqual([data[0]]); + }); + + it('should delete appointment on delete button click in tooltip', async () => { + const data = [ + { + text: 'Apt1', + startDate: new Date(2017, 4, 22, 9, 30), + endDate: new Date(2017, 4, 22, 10, 30), + }, + { + text: 'Apt2', + startDate: new Date(2017, 4, 22, 9, 30), + endDate: new Date(2017, 4, 22, 10, 30), + }, + ]; + + const { POM, scheduler } = await createScheduler({ + dataSource: data, + views: [{ type: 'month', maxAppointmentsPerCell: 1 }], + currentView: 'month', + currentDate: new Date(2017, 4, 22), + height: 600, + }); + + POM.getCollectorButton().click(); + POM.tooltip.getDeleteButton().click(); + + expect(POM.tooltip.isVisible()).toBe(false); + expect((scheduler as any).getDataSource().items()).toEqual([data[0]]); + }); + + it('should not delete appointment by Delete key when editing.allowDeleting=false', async () => { + const data = [ + { + text: 'Apt1', + startDate: new Date(2017, 4, 22, 9, 30), + endDate: new Date(2017, 4, 22, 10, 30), + }, + { + text: 'Apt2', + startDate: new Date(2017, 4, 22, 9, 30), + endDate: new Date(2017, 4, 22, 10, 30), + }, + ]; + + const { POM, scheduler } = await createScheduler({ + dataSource: [...data], + views: [{ type: 'month', maxAppointmentsPerCell: 1 }], + currentView: 'month', + currentDate: new Date(2017, 4, 22), + height: 600, + editing: { + allowDeleting: false, + }, + }); + + POM.getCollectorButton().click(); + + const tooltipScrollableContent = POM.tooltip.getScrollableContent(); + tooltipScrollableContent?.dispatchEvent(new FocusEvent('focusin', { bubbles: true })); + tooltipScrollableContent?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Delete', bubbles: true })); + + expect((scheduler as any).getDataSource().items()).toEqual([...data]); + }); + + it('should not delete disabled appointment by Delete key when focused in tooltip from collector', async () => { + const data = [ + { + text: 'Apt1', + startDate: new Date(2017, 4, 22, 9, 30), + endDate: new Date(2017, 4, 22, 10, 30), + }, + { + text: 'Apt2', + startDate: new Date(2017, 4, 22, 9, 30), + endDate: new Date(2017, 4, 22, 10, 30), + disabled: true, + }, + ]; + + const { POM, scheduler } = await createScheduler({ + dataSource: [...data], + views: [{ type: 'month', maxAppointmentsPerCell: 1 }], + currentView: 'month', + currentDate: new Date(2017, 4, 22), + height: 600, + }); + + POM.getCollectorButton().click(); + + const tooltipScrollableContent = POM.tooltip.getScrollableContent(); + tooltipScrollableContent?.dispatchEvent(new FocusEvent('focusin', { bubbles: true })); + tooltipScrollableContent?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Delete', bubbles: true })); + + expect((scheduler as any).getDataSource().items()).toEqual([...data]); + }); + + it('should delete single occurrence on delete button click and clicking \'Delete appointment\'', async () => { + const data = [ + { + text: 'Apt1', + startDate: new Date(2017, 4, 22, 9, 30), + endDate: new Date(2017, 4, 22, 10, 30), + }, + { + text: 'Apt2', + startDate: new Date(2017, 4, 22, 9, 30), + endDate: new Date(2017, 4, 22, 10, 30), + recurrenceRule: 'FREQ=DAILY', + }, + ]; + + const { POM, scheduler } = await createScheduler({ + dataSource: [{ ...data[0] }, { ...data[1] }], + views: [{ type: 'month', maxAppointmentsPerCell: 1 }], + currentView: 'month', + currentDate: new Date(2017, 4, 22), + editing: true, + height: 600, + }); + + POM.getCollectorButton().click(); + POM.tooltip.getDeleteButton(0).click(); + POM.popup.deleteAppointmentButton.click(); + + expect((scheduler as any).getDataSource().items()).toEqual([ + data[0], + { + ...data[1], + recurrenceException: '20170522T013000Z', + }, + ]); + }); + + it('should delete all occurrences on delete and clicking \'Delete series\'', async () => { + const data = [ + { + text: 'Apt1', + startDate: new Date(2017, 4, 22, 9, 30), + endDate: new Date(2017, 4, 22, 10, 30), + }, + { + text: 'Apt2', + startDate: new Date(2017, 4, 22, 9, 30), + endDate: new Date(2017, 4, 22, 10, 30), + recurrenceRule: 'FREQ=DAILY', + }, + ]; + + const { POM, scheduler } = await createScheduler({ + dataSource: [{ ...data[0] }, { ...data[1] }], + views: [{ type: 'month', maxAppointmentsPerCell: 1 }], + currentView: 'month', + currentDate: new Date(2017, 4, 22), + editing: true, + height: 600, + }); + + POM.getCollectorButton().click(); + POM.tooltip.getDeleteButton(0).click(); + POM.popup.deleteSeriesButton.click(); + + expect((scheduler as any).getDataSource().items()).toEqual([data[0]]); + }); + }); +}); diff --git a/packages/devextreme/js/__internal/scheduler/__tests__/appointments.test.ts b/packages/devextreme/js/__internal/scheduler/__tests__/appointments.test.ts index e50e51e78830..e7a889b3ac6f 100644 --- a/packages/devextreme/js/__internal/scheduler/__tests__/appointments.test.ts +++ b/packages/devextreme/js/__internal/scheduler/__tests__/appointments.test.ts @@ -1,16 +1,24 @@ import { afterEach, describe, expect, it, jest, } from '@jest/globals'; +import $ from '@js/core/renderer'; import { createScheduler } from './__mock__/create_scheduler'; import { setupSchedulerTestEnvironment } from './__mock__/m_mock_scheduler'; describe('Appointments', () => { + beforeEach(() => { + setupSchedulerTestEnvironment(); + }); afterEach(() => { + const $scheduler = $('.dx-scheduler'); + // @ts-expect-error + $scheduler.dxScheduler('dispose'); + document.body.innerHTML = ''; jest.useRealTimers(); }); + it('All-day appointment should not be resizable if current view is "day"', async () => { - setupSchedulerTestEnvironment(); const { POM } = await createScheduler({ dataSource: [{ text: 'Appointment 1', @@ -27,7 +35,6 @@ describe('Appointments', () => { }); it('should display "(No subject)" for appointments without title', async () => { - setupSchedulerTestEnvironment({ height: 200 }); const appointmentWithoutTitle = { startDate: new Date(2017, 4, 9, 9, 30), endDate: new Date(2017, 4, 9, 11), @@ -50,7 +57,6 @@ describe('Appointments', () => { }); it('should display "(No subject)" in tooltip for appointments without title', async () => { - setupSchedulerTestEnvironment({ height: 200 }); const appointmentWithoutTitle = { startDate: new Date(2017, 4, 9, 9, 30), endDate: new Date(2017, 4, 9, 11), @@ -81,4 +87,74 @@ describe('Appointments', () => { expect(tooltipTitleElement?.textContent?.trim()).toBe('(No subject)'); } }); + + describe('Keyboard Navigation', () => { + describe('Delete hotkey', () => { + it('should delete single occurrence on Delete and clicking \'Delete appointment\'', async () => { + const { POM, keydown } = await createScheduler({ + dataSource: [{ + text: 'Recurring Appointment', + startDate: new Date(2015, 1, 9, 8), + endDate: new Date(2015, 1, 9, 9), + recurrenceRule: 'FREQ=DAILY', + }], + currentView: 'week', + currentDate: new Date(2015, 1, 9), + }); + + const initialCount = POM.getAppointments().length; + const appointment = POM.getAppointments()[2]; + + appointment.element.focus(); + keydown(appointment.element, 'Delete'); + + POM.popup.deleteAppointmentButton.click(); + + expect(POM.getAppointments().length).toBe(initialCount - 1); + }); + + it('should delete all occurrences on delete and clicking \'Delete series\'', async () => { + const { POM, keydown, scheduler } = await createScheduler({ + dataSource: [{ + text: 'Recurring Appointment', + startDate: new Date(2015, 1, 9, 8), + endDate: new Date(2015, 1, 9, 9), + recurrenceRule: 'FREQ=DAILY', + }], + editing: true, + currentView: 'week', + currentDate: new Date(2015, 1, 9), + }); + + const appointment = POM.getAppointments()[0]; + + appointment.element.focus(); + keydown(appointment.element, 'Delete'); + + POM.popup.deleteSeriesButton.click(); + + expect(POM.getAppointments().length).toBe(0); + }); + + it('should delete appointment on Delete', async () => { + const { POM, keydown } = await createScheduler({ + dataSource: [{ + text: 'Recurring Appointment', + startDate: new Date(2015, 1, 9, 8), + endDate: new Date(2015, 1, 9, 9), + }], + currentView: 'day', + currentDate: new Date(2015, 1, 9), + }); + + const initialCount = POM.getAppointments().length; + const appointment = POM.getAppointments()[0]; + + appointment.element.focus(); + keydown(appointment.element, 'Delete'); + + expect(POM.getAppointments().length).toBe(initialCount - 1); + }); + }); + }); }); diff --git a/packages/devextreme/js/__internal/scheduler/m_scheduler.ts b/packages/devextreme/js/__internal/scheduler/m_scheduler.ts index 78e433bd02c3..874688852489 100644 --- a/packages/devextreme/js/__internal/scheduler/m_scheduler.ts +++ b/packages/devextreme/js/__internal/scheduler/m_scheduler.ts @@ -1655,6 +1655,7 @@ class Scheduler extends SchedulerOptionsBaseWidget { } private showRecurrenceChangeConfirm(isDeleted) { + console.log('ABOBAOBAOB showRecurrenceChangeConfirm'); const title = messageLocalization.format(isDeleted ? 'dxScheduler-confirmRecurrenceDeleteTitle' : 'dxScheduler-confirmRecurrenceEditTitle'); const message = messageLocalization.format(isDeleted ? 'dxScheduler-confirmRecurrenceDeleteMessage' : 'dxScheduler-confirmRecurrenceEditMessage'); const seriesText = messageLocalization.format(isDeleted ? 'dxScheduler-confirmRecurrenceDeleteSeries' : 'dxScheduler-confirmRecurrenceEditSeries'); From 212bebab12f7aba26691a60fab98549f1a4bb27a Mon Sep 17 00:00:00 2001 From: Eldar Iusupzhanov Date: Tue, 31 Mar 2026 20:40:50 +0800 Subject: [PATCH 2/4] fix ci --- .../scheduler/__tests__/appointment_tooltip.test.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/__tests__/appointment_tooltip.test.ts b/packages/devextreme/js/__internal/scheduler/__tests__/appointment_tooltip.test.ts index e0dbabbbb0e4..5aaef654c88c 100644 --- a/packages/devextreme/js/__internal/scheduler/__tests__/appointment_tooltip.test.ts +++ b/packages/devextreme/js/__internal/scheduler/__tests__/appointment_tooltip.test.ts @@ -174,13 +174,14 @@ describe('Appointment tooltip behavior', () => { POM.tooltip.getDeleteButton(0).click(); POM.popup.deleteAppointmentButton.click(); - expect((scheduler as any).getDataSource().items()).toEqual([ + const items = (scheduler as any).getDataSource().items(); + + expect(items).toEqual([ data[0], - { - ...data[1], - recurrenceException: '20170522T013000Z', - }, + expect.objectContaining(data[1]), ]); + + expect(Boolean(items[1].recurrenceException)).toBe(true); }); it('should delete all occurrences on delete and clicking \'Delete series\'', async () => { From e8a43b70398f00f8da8bf5faa3d72c7030c69e5a Mon Sep 17 00:00:00 2001 From: Eldar Iusupzhanov Date: Tue, 31 Mar 2026 20:41:59 +0800 Subject: [PATCH 3/4] fix lint --- .../js/__internal/scheduler/__tests__/appointments.test.ts | 6 +++--- packages/devextreme/js/__internal/scheduler/m_scheduler.ts | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/__tests__/appointments.test.ts b/packages/devextreme/js/__internal/scheduler/__tests__/appointments.test.ts index e7a889b3ac6f..d5474a194e80 100644 --- a/packages/devextreme/js/__internal/scheduler/__tests__/appointments.test.ts +++ b/packages/devextreme/js/__internal/scheduler/__tests__/appointments.test.ts @@ -114,7 +114,7 @@ describe('Appointments', () => { }); it('should delete all occurrences on delete and clicking \'Delete series\'', async () => { - const { POM, keydown, scheduler } = await createScheduler({ + const { POM, keydown } = await createScheduler({ dataSource: [{ text: 'Recurring Appointment', startDate: new Date(2015, 1, 9, 8), @@ -125,9 +125,9 @@ describe('Appointments', () => { currentView: 'week', currentDate: new Date(2015, 1, 9), }); - + const appointment = POM.getAppointments()[0]; - + appointment.element.focus(); keydown(appointment.element, 'Delete'); diff --git a/packages/devextreme/js/__internal/scheduler/m_scheduler.ts b/packages/devextreme/js/__internal/scheduler/m_scheduler.ts index 874688852489..78e433bd02c3 100644 --- a/packages/devextreme/js/__internal/scheduler/m_scheduler.ts +++ b/packages/devextreme/js/__internal/scheduler/m_scheduler.ts @@ -1655,7 +1655,6 @@ class Scheduler extends SchedulerOptionsBaseWidget { } private showRecurrenceChangeConfirm(isDeleted) { - console.log('ABOBAOBAOB showRecurrenceChangeConfirm'); const title = messageLocalization.format(isDeleted ? 'dxScheduler-confirmRecurrenceDeleteTitle' : 'dxScheduler-confirmRecurrenceEditTitle'); const message = messageLocalization.format(isDeleted ? 'dxScheduler-confirmRecurrenceDeleteMessage' : 'dxScheduler-confirmRecurrenceEditMessage'); const seriesText = messageLocalization.format(isDeleted ? 'dxScheduler-confirmRecurrenceDeleteSeries' : 'dxScheduler-confirmRecurrenceEditSeries'); From bebc5c0630e86d395b1363e2e3d20e65e5147c0c Mon Sep 17 00:00:00 2001 From: Eldar Iusupzhanov Date: Wed, 1 Apr 2026 18:05:25 +0800 Subject: [PATCH 4/4] apply sergei's review --- .../scheduler/__tests__/appointment_tooltip.test.ts | 4 ++-- .../js/__internal/scheduler/__tests__/appointments.test.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/__tests__/appointment_tooltip.test.ts b/packages/devextreme/js/__internal/scheduler/__tests__/appointment_tooltip.test.ts index 5aaef654c88c..39ede355bea2 100644 --- a/packages/devextreme/js/__internal/scheduler/__tests__/appointment_tooltip.test.ts +++ b/packages/devextreme/js/__internal/scheduler/__tests__/appointment_tooltip.test.ts @@ -66,7 +66,7 @@ describe('Appointment tooltip behavior', () => { ]; const { POM, scheduler } = await createScheduler({ - dataSource: data, + dataSource: [...data], views: [{ type: 'month', maxAppointmentsPerCell: 1 }], currentView: 'month', currentDate: new Date(2017, 4, 22), @@ -181,7 +181,7 @@ describe('Appointment tooltip behavior', () => { expect.objectContaining(data[1]), ]); - expect(Boolean(items[1].recurrenceException)).toBe(true); + expect(items[1].recurrenceException).toContain('20170522'); }); it('should delete all occurrences on delete and clicking \'Delete series\'', async () => { diff --git a/packages/devextreme/js/__internal/scheduler/__tests__/appointments.test.ts b/packages/devextreme/js/__internal/scheduler/__tests__/appointments.test.ts index d5474a194e80..86bc90b389ad 100644 --- a/packages/devextreme/js/__internal/scheduler/__tests__/appointments.test.ts +++ b/packages/devextreme/js/__internal/scheduler/__tests__/appointments.test.ts @@ -139,7 +139,7 @@ describe('Appointments', () => { it('should delete appointment on Delete', async () => { const { POM, keydown } = await createScheduler({ dataSource: [{ - text: 'Recurring Appointment', + text: 'Appointment', startDate: new Date(2015, 1, 9, 8), endDate: new Date(2015, 1, 9, 9), }],