Skip to content

Commit 1978f2d

Browse files
authored
Scheduler - Appointment Form - Reimplement legacy tests for the new form - Part 2 (DevExpress#31807)
1 parent fc8da8b commit 1978f2d

File tree

11 files changed

+671
-318
lines changed

11 files changed

+671
-318
lines changed
Loading
Loading
Loading

e2e/testcafe-devextreme/tests/scheduler/common/appointmentForm/form.visual.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,32 @@ test.meta({ browserSize: [1500, 1500] })('appointment form readonly state', asyn
194194
},
195195
});
196196
});
197+
198+
test.meta({ browserSize: [450, 1000] })('main form on mobile screen', async (t) => {
199+
const { takeScreenshot, compareResults } = createScreenshotsComparer(t);
200+
201+
const scheduler = new Scheduler(SCHEDULER_SELECTOR);
202+
203+
await scheduler.openAppointmentPopup(t, undefined, false);
204+
205+
await testScreenshot(
206+
t,
207+
takeScreenshot,
208+
'scheduler__appointment__main-form__mobile.png',
209+
);
210+
211+
await t
212+
.expect(compareResults.isValid())
213+
.ok(compareResults.errorMessages());
214+
}).before(async () => createWidget('dxScheduler', {
215+
dataSource: [],
216+
views: ['week'],
217+
currentView: 'week',
218+
currentDate: new Date(2021, 2, 25),
219+
resources: getResources(true),
220+
editing: {
221+
form: {
222+
iconsShowMode: 'both',
223+
},
224+
},
225+
}));

e2e/testcafe-devextreme/tests/scheduler/common/appointmentForm/recurrence-form.visual.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,32 @@ test('recurrence form readonly state', async (t) => {
150150
allowUpdating: false,
151151
},
152152
}));
153+
154+
test.meta({ browserSize: [450, 1000] })('recurrence form on mobile screen', async (t) => {
155+
const { takeScreenshot, compareResults } = createScreenshotsComparer(t);
156+
157+
const scheduler = new Scheduler(SCHEDULER_SELECTOR);
158+
159+
const appointmentPopup = await scheduler.openAppointmentPopup(t, undefined, false);
160+
await appointmentPopup.openRecurrenceForm(t, 'Weekly');
161+
162+
await testScreenshot(
163+
t,
164+
takeScreenshot,
165+
'scheduler__appointment__recurrence-form__mobile.png',
166+
);
167+
168+
await t
169+
.expect(compareResults.isValid())
170+
.ok(compareResults.errorMessages());
171+
}).before(async () => createWidget('dxScheduler', {
172+
dataSource: [],
173+
views: ['week'],
174+
currentView: 'week',
175+
currentDate: new Date(2021, 2, 25),
176+
editing: {
177+
form: {
178+
iconsShowMode: 'both',
179+
},
180+
},
181+
}));

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

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,17 +142,52 @@ export class PopupModel {
142142
return this.element.querySelector('.dx-scheduler-form-day-of-year-group');
143143
}
144144

145-
getInput = (editorName: string): dxElementWrapper | undefined => {
145+
getInput = (editorName: string): dxElementWrapper => {
146146
const editor = this.form.getEditor(editorName);
147-
return editor?.$element().find('input.dx-texteditor-input');
147+
148+
const textInput = editor?.$element().find('.dx-texteditor-input');
149+
150+
if (textInput?.length) {
151+
return textInput;
152+
}
153+
154+
const input = editor?.$element().find('input');
155+
156+
if (input?.length) {
157+
return input;
158+
}
159+
160+
throw new Error(`Input element of editor with name "${editorName}" not found`);
161+
};
162+
163+
getInputValue = (editorName: string): string => {
164+
const $input = this.getInput(editorName);
165+
return $input.val() as unknown as string;
166+
};
167+
168+
setInputValue = (editorName: string, value: string | Date | boolean | null): void => {
169+
this.form.getEditor(editorName)?.option('value', value);
148170
};
149171

150-
getInputValue = (editorName: string): string | undefined => {
151-
const result = this.getInput(editorName)?.val();
152-
return result as string | undefined;
172+
isInputVisible = (editorName: string): boolean => {
173+
const editor = this.form.getEditor(editorName);
174+
175+
if (!editor) {
176+
return false;
177+
}
178+
179+
return editor.$element().is(':visible');
153180
};
154181

155-
isInputVisible = (editorName: string): boolean => this.getInput(editorName)?.length === 1;
182+
getWeekDaysSelection = (): boolean[] => {
183+
const buttons = this.element.querySelectorAll('.dx-scheduler-days-of-week-buttons .dx-button');
184+
185+
if (buttons.length === 0) {
186+
throw new Error('Week day buttons not found');
187+
}
188+
189+
return Array.from(buttons).map((button) => button.classList.contains('dx-button-mode-contained'));
190+
};
156191

157192
getLabelIdByText = (labelText: string): string => {
158193
const labels = Array.from(this.element.querySelectorAll('label'));
@@ -252,7 +287,7 @@ export class PopupModel {
252287
getTitle = (): HTMLElement | null => document.querySelector('.dx-popup-title .dx-toolbar-label');
253288

254289
getSaveButton = (): HTMLButtonElement => {
255-
const saveButton = this.element.querySelector('.dx-button.dx-popup-done') as HTMLButtonElement;
290+
const saveButton = this.element.querySelector('.dx-button[aria-label="Save"]') as HTMLButtonElement;
256291
if (!saveButton) {
257292
throw new Error('Done button not found');
258293
}
@@ -268,7 +303,7 @@ export class PopupModel {
268303
};
269304

270305
getCancelButton = (): HTMLButtonElement => {
271-
const cancelButton = this.element.querySelector('.dx-button.dx-popup-cancel') as HTMLButtonElement;
306+
const cancelButton = this.element.querySelector('.dx-button[aria-label="Cancel"]') as HTMLButtonElement;
272307
if (!cancelButton) {
273308
throw new Error('Cancel button not found');
274309
}
@@ -340,6 +375,7 @@ export class PopupModel {
340375

341376
if (originalOnValueChanged) {
342377
originalOnValueChanged({
378+
component: repeatEditor,
343379
value,
344380
previousValue,
345381
event: new Event('change'),

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,31 @@ export class SchedulerModel {
5353
return getTexts(cells);
5454
}
5555

56+
getDateTableCell(rowIndex = 0, cellIndex = 0): HTMLElement {
57+
const rowSelector = `.dx-scheduler-date-table-row:nth-child(${rowIndex + 1})`;
58+
const cellSelector = `.dx-scheduler-date-table-cell:nth-child(${cellIndex + 1})`;
59+
const selector = `${rowSelector} ${cellSelector}`;
60+
61+
const result = this.container.querySelector(selector);
62+
63+
if (!result) {
64+
throw new Error(`Date cell in row ${rowIndex} and column ${cellIndex} not found`);
65+
}
66+
67+
return result as HTMLElement;
68+
}
69+
70+
getAllDayTableCell(cellIndex = 0): HTMLElement {
71+
const cellSelector = `.dx-scheduler-all-day-table-cell:nth-child(${cellIndex + 1})`;
72+
const result = this.container.querySelector(cellSelector);
73+
74+
if (!result) {
75+
throw new Error(`All-day cell in column ${cellIndex} not found`);
76+
}
77+
78+
return result as HTMLElement;
79+
}
80+
5681
getHeaderPanelContent(): string[] {
5782
const cells = this.container.querySelectorAll('.dx-scheduler-header-panel-cell');
5883
return getTexts(cells);
@@ -80,6 +105,10 @@ export class SchedulerModel {
80105
return new PopupModel(popupElement);
81106
}
82107

108+
isPopupVisible(): boolean {
109+
return this.getPopups().length > 0;
110+
}
111+
83112
getPopups = (): NodeListOf<Element> => document.querySelectorAll(`.dx-overlay-wrapper.${APPOINTMENT_POPUP_CLASS}, .dx-overlay-wrapper.${POPUP_DIALOG_CLASS}`);
84113

85114
getLoadPanel = (): HTMLElement | null => document.querySelector('.dx-loadpanel');
@@ -98,6 +127,24 @@ export class SchedulerModel {
98127

99128
return appointment;
100129
}
130+
131+
dblClickDateTableCell(rowIndex = 0, cellIndex = 0): void {
132+
const cellElement = this.getDateTableCell(rowIndex, cellIndex);
133+
134+
cellElement.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true }));
135+
cellElement.click();
136+
cellElement.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true }));
137+
cellElement.click();
138+
}
139+
140+
dblClickAllDayTableCell(cellIndex = 0): void {
141+
const cellElement = this.getAllDayTableCell(cellIndex);
142+
143+
cellElement.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true }));
144+
cellElement.click();
145+
cellElement.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true }));
146+
cellElement.click();
147+
}
101148
}
102149

103150
export const createSchedulerModel = (container: HTMLDivElement): SchedulerModel => {

0 commit comments

Comments
 (0)