Skip to content

Commit 5db5e68

Browse files
authored
Scheduler: move testcafe status tests to jest (DevExpress#31361)
1 parent f9693d5 commit 5db5e68

File tree

4 files changed

+168
-120
lines changed

4 files changed

+168
-120
lines changed

e2e/testcafe-devextreme/tests/scheduler/common/a11y/status.ts

Lines changed: 0 additions & 120 deletions
This file was deleted.

packages/devextreme/js/__internal/scheduler/__tests__/__mock__/model/scheduler.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { ToolbarModel } from '@ts/scheduler/__tests__/__mock__/model/toolbar';
2+
13
import { APPOINTMENT_POPUP_CLASS } from '../../../appointment_popup/m_popup';
24
import { POPUP_DIALOG_CLASS } from '../../../m_scheduler';
35
import type { AppointmentModel } from './appointment';
@@ -19,6 +21,14 @@ export class SchedulerModel {
1921
return this.getPopup();
2022
}
2123

24+
get toolbar(): ToolbarModel {
25+
return new ToolbarModel(this.container.querySelector('.dx-scheduler-header'));
26+
}
27+
28+
getStatusContent(): string {
29+
return this.container.querySelector('.dx-scheduler-a11y-status-container')?.textContent ?? '';
30+
}
31+
2232
getAppointment(text?: string): AppointmentModel<HTMLDivElement | null> {
2333
if (!text) {
2434
return createAppointmentModel(this.container.querySelector('.dx-scheduler-appointment'));
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export class ToolbarModel {
2+
element: HTMLDivElement | null;
3+
4+
constructor(element: HTMLDivElement | null) {
5+
this.element = element;
6+
}
7+
8+
getPrevButton(): HTMLDivElement | null | undefined {
9+
return this.element?.querySelector('.dx-scheduler-navigator-previous');
10+
}
11+
12+
getNextButton(): HTMLDivElement | null | undefined {
13+
return this.element?.querySelector('.dx-scheduler-navigator-next');
14+
}
15+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import {
2+
describe, expect, it,
3+
} from '@jest/globals';
4+
5+
import { createScheduler } from './__mock__/create_scheduler';
6+
import { setupSchedulerTestEnvironment } from './__mock__/m_mock_scheduler';
7+
import type { SchedulerModel } from './__mock__/model/scheduler';
8+
9+
const today = '2025-04-30T15:00:00.000Z';
10+
const appointments = [
11+
{
12+
startDate: '2025-04-25T21:30:00.000Z',
13+
endDate: '2025-04-25T23:30:00.000Z',
14+
recurrenceRule: 'FREQ=HOURLY;INTERVAL=15;COUNT=15',
15+
}, {
16+
startDate: '2025-04-30T15:00:00.000Z',
17+
endDate: '2025-04-30T16:00:00.000Z',
18+
}, {
19+
startDate: '2025-04-26T00:30:00.000Z',
20+
endDate: '2025-04-26T02:30:00.000Z',
21+
recurrenceRule: 'FREQ=HOURLY;INTERVAL=15;COUNT=15',
22+
}, {
23+
startDate: '2025-05-02T15:00:00.000Z',
24+
endDate: '2025-05-02T16:00:00.000Z',
25+
},
26+
];
27+
28+
const statusCheckEql = (scheduler: SchedulerModel, status: string): void => {
29+
expect(scheduler.container.getAttribute('aria-label')).toMatch(new RegExp(status));
30+
expect(scheduler.getStatusContent()).toMatch(new RegExp(status));
31+
};
32+
33+
const options = [
34+
['agenda', 'Agenda view: from April 30, 2025 to May 6, 2025', [0, 9, 19]],
35+
['day', 'Day view: April 30, 2025', [0, 3, 5]],
36+
['month', 'Month view: from March 2025 to May 2025', [0, 17, 35]],
37+
['timelineDay', 'Timeline Day view: April 30, 2025', [0, 3, 5]],
38+
['timelineMonth', 'Timeline Month view: April 2025', [0, 11, 21]],
39+
['timelineWeek', 'Timeline Week view: from April 27, 2025 to May 3, 2025', [0, 12, 25]],
40+
['timelineWorkWeek', 'Timeline Work Week view: from April 28, 2025 to May 2, 2025', [0, 9, 18]],
41+
['week', 'Week view: from April 27, 2025 to May 3, 2025', [0, 13, 27]],
42+
['workWeek', 'Work Week view: from April 28, 2025 to May 2, 2025', [0, 10, 20]],
43+
['Two Weeks', 'Two Weeks view: from April 27, 2025 to May 10, 2025', [0, 14, 29]],
44+
] as const;
45+
const indicatorOnView = 'The current time indicator is visible in the view';
46+
const indicatorNotOnView = 'The current time indicator is not visible on the screen';
47+
48+
describe('Scheduler Status', () => {
49+
options.forEach(([currentView, title, counts]) => {
50+
counts.forEach((appointmentsCount, index) => {
51+
const schedulerConfig = {
52+
timeZone: 'America/Los_Angeles',
53+
dataSource: appointments.slice(0, 2 * index),
54+
views: [
55+
'agenda', 'day', 'month', 'timelineDay', 'timelineMonth', 'timelineWeek', 'timelineWorkWeek', 'week', 'workWeek', {
56+
name: 'Two Weeks',
57+
type: 'week',
58+
intervalCount: 2,
59+
},
60+
],
61+
currentView,
62+
indicatorTime: today,
63+
currentDate: today,
64+
};
65+
// TODO(2): use `appointmentsCount` here
66+
const generalStatus = `Scheduler. ${title} with ${index === 0 ? 0 : '\\d*'} appointments`;
67+
68+
it(`should have correct status message [view=${currentView}, count=${appointmentsCount}, indicator=false]`, async () => {
69+
setupSchedulerTestEnvironment();
70+
const { POM } = await createScheduler({
71+
...schedulerConfig,
72+
showCurrentTimeIndicator: false,
73+
});
74+
statusCheckEql(POM, generalStatus);
75+
});
76+
77+
it(`should have correct status message [view=${currentView}, count=${appointmentsCount}, indicator=true]`, async () => {
78+
setupSchedulerTestEnvironment();
79+
const { POM } = await createScheduler({
80+
...schedulerConfig,
81+
showCurrentTimeIndicator: true,
82+
});
83+
84+
POM.toolbar.getNextButton()?.click();
85+
statusCheckEql(POM, currentView === 'month' ? indicatorOnView : indicatorNotOnView);
86+
87+
POM.toolbar.getPrevButton()?.click();
88+
statusCheckEql(POM, `${generalStatus}. ${indicatorOnView}`);
89+
90+
POM.toolbar.getPrevButton()?.click();
91+
statusCheckEql(POM, indicatorNotOnView);
92+
});
93+
});
94+
});
95+
96+
[
97+
['timelineWeek', 'Scheduler. Timeline Week view: from April 27, 2025 to May 3, 2025 with 5 appointments'],
98+
['week', 'Scheduler. Week view: from April 27, 2025 to May 3, 2025 with 5 appointments'],
99+
['workWeek', 'Scheduler. Work Week view: from April 28, 2025 to May 2, 2025 with 4 appointments'],
100+
].forEach(([currentView, title]) => {
101+
it(`should have correct status message if the appointments are partial [view=${currentView}]`, async () => {
102+
setupSchedulerTestEnvironment();
103+
const { POM } = await createScheduler({
104+
timeZone: 'America/Los_Angeles',
105+
dataSource: [{
106+
startDate: '2025-04-29T23:18:00.000Z',
107+
endDate: '2025-04-30T16:12:00.000Z',
108+
}, {
109+
startDate: '2025-04-26T23:18:00.000Z',
110+
endDate: '2025-04-27T12:12:00.000Z',
111+
recurrenceRule: 'FREQ=DAILY;INTERVAL=2;COUNT=5',
112+
}],
113+
views: [currentView],
114+
currentView,
115+
indicatorTime: today,
116+
currentDate: today,
117+
});
118+
119+
statusCheckEql(POM, title);
120+
});
121+
});
122+
123+
it('should have correct status message if the appointments are partial [view=month]', async () => {
124+
setupSchedulerTestEnvironment();
125+
const { POM } = await createScheduler({
126+
timeZone: 'America/Los_Angeles',
127+
dataSource: [{
128+
startDate: '2025-04-04T23:18:00.000Z',
129+
endDate: '2025-04-08T16:12:00.000Z',
130+
}, {
131+
startDate: '2025-04-04T23:18:00.000Z',
132+
endDate: '2025-04-08T12:12:00.000Z',
133+
recurrenceRule: 'FREQ=WEEKLY;INTERVAL=2;COUNT=2',
134+
}],
135+
views: ['month'],
136+
currentView: 'month',
137+
indicatorTime: today,
138+
currentDate: today,
139+
});
140+
141+
statusCheckEql(POM, 'Scheduler. Month view: from March 2025 to May 2025 with 3 appointments');
142+
});
143+
});

0 commit comments

Comments
 (0)