Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Scheduler from 'devextreme-testcafe-models/scheduler';
import { Selector } from 'testcafe';
import url from '../../../../helpers/getPageUrl';
import { createWidget } from '../../../../helpers/createWidget';
import { generateAppointmentsWithResources, resources } from '../../helpers/generateAppointmentsWithResources';
Expand Down Expand Up @@ -276,3 +277,89 @@ test('should focus first rendered appointment on tab (standard scrolling)', asyn
await insertStylesheetRulesToPage(cellStyles);
await createWidget('dxScheduler', { ...getConfig(), scrolling: { mode: 'standard' } });
});

const getDeleteFocusConfig = () => ({
dataSource: [
{ text: 'Appointment 1', startDate: new Date(2021, 1, 2, 9), endDate: new Date(2021, 1, 2, 10) },
{ text: 'Appointment 2', startDate: new Date(2021, 1, 2, 10), endDate: new Date(2021, 1, 2, 11) },
{ text: 'Appointment 3', startDate: new Date(2021, 1, 2, 11), endDate: new Date(2021, 1, 2, 12) },
],
views: ['day'],
currentView: 'day',
currentDate: new Date(2021, 1, 2),
startDayHour: 8,
endDayHour: 20,
height: 600,
});

test('should focus next appointment after deleting appointment by Delete key', async (t) => {
const scheduler = new Scheduler(SCHEDULER_SELECTOR);

await t
.click(scheduler.getAppointment('Appointment 2').element)
.pressKey('delete');

await t
.expect(scheduler.getAppointmentCount()).eql(2)
.expect(scheduler.getAppointment('Appointment 3').isFocused).ok();
}).before(async () => {
await createWidget('dxScheduler', getDeleteFocusConfig());
});

test('should focus previous appointment after deleting the last appointment by Delete key', async (t) => {
const scheduler = new Scheduler(SCHEDULER_SELECTOR);

await t
.click(scheduler.getAppointment('Appointment 3').element)
.pressKey('delete');

await t
.expect(scheduler.getAppointmentCount()).eql(2)
.expect(scheduler.getAppointment('Appointment 2').isFocused).ok();
}).before(async () => {
await createWidget('dxScheduler', getDeleteFocusConfig());
});

test('should focus toolbar element when no appointments remain after deleting by Delete key', async (t) => {
const scheduler = new Scheduler(SCHEDULER_SELECTOR);

await t
.click(scheduler.getAppointment('Appointment 1').element)
.pressKey('delete');

await t
.expect(scheduler.getAppointmentCount()).eql(0)
.expect(scheduler.toolbar.element.find(':focus').exists).ok();
}).before(async () => {
await createWidget('dxScheduler', {
...getDeleteFocusConfig(),
dataSource: [
{ text: 'Appointment 1', startDate: new Date(2021, 1, 2, 9), endDate: new Date(2021, 1, 2, 10) },
],
});
});

test('should focus next occurrence after deleting recurring occurrence via dialog', async (t) => {
const scheduler = new Scheduler(SCHEDULER_SELECTOR);

await t
.click(scheduler.getAppointment('Recurring Appointment', 2).element)
.pressKey('delete')
.click(Selector('.dx-dialog-button').withText('Delete appointment'));

await t
.expect(scheduler.getAppointmentCount()).eql(4)
.expect(scheduler.getAppointment('Recurring Appointment', 2).isFocused).ok();
}).before(async () => {
await createWidget('dxScheduler', {
...getDeleteFocusConfig(),
views: ['week'],
currentView: 'week',
dataSource: [{
text: 'Recurring Appointment',
startDate: new Date(2021, 1, 1, 9),
endDate: new Date(2021, 1, 1, 10),
recurrenceRule: 'FREQ=DAILY;COUNT=5',
}],
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -325,5 +325,120 @@ describe('Appointments', () => {
expect(POM.getAppointments().length).toBe(initialCount - 1);
});
});

describe('Focus after Delete', () => {
it('should focus next appointment after deleting via Delete key', async () => {
const { POM, keydown } = await createScheduler({
dataSource: [...dataSource],
currentView: 'day',
currentDate: new Date(2015, 1, 9),
});

const appointment = POM.getAppointment('Appointment 2');

appointment.element?.focus();
keydown(appointment.element as Element, 'Delete');
await new Promise(process.nextTick);

expect(POM.getAppointments().length).toBe(2);
expect(POM.getAppointment('Appointment 3').isFocused()).toBe(true);
});

it('should focus previous appointment after deleting the last one', async () => {
const { POM, keydown } = await createScheduler({
dataSource: [...dataSource],
currentView: 'day',
currentDate: new Date(2015, 1, 9),
});

const appointment = POM.getAppointment('Appointment 3');

appointment.element?.focus();
keydown(appointment.element as Element, 'Delete');
await new Promise(process.nextTick);

expect(POM.getAppointments().length).toBe(2);
expect(POM.getAppointment('Appointment 2').isFocused()).toBe(true);
});

it('should focus toolbar element when no appointments remain after delete', async () => {
const { POM, keydown } = await createScheduler({
dataSource: [dataSource[0]],
currentView: 'day',
currentDate: new Date(2015, 1, 9),
});

const appointment = POM.getAppointment('Appointment 1');

appointment.element?.focus();
keydown(appointment.element as Element, 'Delete');
await new Promise(process.nextTick);

expect(POM.getAppointments().length).toBe(0);
expect(POM.toolbar.element.contains(document.activeElement)).toBe(true);
});

it('should focus workspace when no appointments remain after delete and toolbar is hidden', async () => {
const { POM, keydown } = await createScheduler({
dataSource: [dataSource[0]],
currentView: 'day',
currentDate: new Date(2015, 1, 9),
toolbar: { items: [] },
});

const appointment = POM.getAppointment('Appointment 1');

appointment.element?.focus();
keydown(appointment.element as Element, 'Delete');
await new Promise(process.nextTick);

expect(POM.getAppointments().length).toBe(0);
expect(document.activeElement).toBe(POM.getWorkspace());
});

it('should keep focus on appointment when deleting is canceled', async () => {
const { POM, keydown } = await createScheduler({
dataSource: [...dataSource],
currentView: 'day',
currentDate: new Date(2015, 1, 9),
onAppointmentDeleting: (e) => {
e.cancel = true;
},
});

const appointment = POM.getAppointment('Appointment 2');

appointment.element?.focus();
keydown(appointment.element as Element, 'Delete');
await new Promise(process.nextTick);

expect(POM.getAppointments().length).toBe(3);
expect(document.activeElement).toBe(appointment.element);
});

it('should focus next occurrence after deleting recurring occurrence via dialog', 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();
await new Promise(process.nextTick);

expect(POM.getAppointments().length).toBe(initialCount - 1);
expect(POM.getAppointments()[2].isFocused()).toBe(true);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -930,5 +930,121 @@ describe('New Appointments', () => {

expect(POM.getAppointments().length).toBe(1);
});

describe('Focus after delete', () => {
const dataSource = [
{ text: 'Appointment 1', startDate: new Date(2015, 1, 9, 8), endDate: new Date(2015, 1, 9, 9) },
{ text: 'Appointment 2', startDate: new Date(2015, 1, 9, 10), endDate: new Date(2015, 1, 9, 11) },
{ text: 'Appointment 3', startDate: new Date(2015, 1, 9, 12), endDate: new Date(2015, 1, 9, 13) },
];

it('should focus next appointment after deleting via Delete key', async () => {
const { POM } = await createScheduler({
dataSource: [...dataSource],
currentView: 'day',
currentDate: new Date(2015, 1, 9),
});

const appointment = POM.getAppointment('Appointment 2');
appointment.element?.focus();
fireEvent.keyDown(appointment.element as Element, { key: 'Delete' });
await new Promise(process.nextTick);

expect(POM.getAppointments().length).toBe(2);
expect(document.activeElement).toBe(POM.getAppointment('Appointment 3').element);
});

it('should focus previous appointment after deleting the last one', async () => {
const { POM } = await createScheduler({
dataSource: [...dataSource],
currentView: 'day',
currentDate: new Date(2015, 1, 9),
});

const appointment = POM.getAppointment('Appointment 3');
appointment.element?.focus();
fireEvent.keyDown(appointment.element as Element, { key: 'Delete' });
await new Promise(process.nextTick);

expect(POM.getAppointments().length).toBe(2);
expect(document.activeElement).toBe(POM.getAppointment('Appointment 2').element);
});

it('should focus toolbar element when no appointments remain after delete', async () => {
const { POM } = await createScheduler({
dataSource: [dataSource[0]],
currentView: 'day',
currentDate: new Date(2015, 1, 9),
});

const appointment = POM.getAppointment('Appointment 1');
appointment.element?.focus();
fireEvent.keyDown(appointment.element as Element, { key: 'Delete' });
await new Promise(process.nextTick);

expect(POM.getAppointments().length).toBe(0);
expect(POM.toolbar.element.contains(document.activeElement)).toBe(true);
});

it('should focus workspace when no appointments remain after delete and toolbar is hidden', async () => {
const { POM } = await createScheduler({
dataSource: [dataSource[0]],
currentView: 'day',
currentDate: new Date(2015, 1, 9),
toolbar: { items: [] },
});

const appointment = POM.getAppointment('Appointment 1');
appointment.element?.focus();
fireEvent.keyDown(appointment.element as Element, { key: 'Delete' });
await new Promise(process.nextTick);

expect(POM.getAppointments().length).toBe(0);
expect(document.activeElement).toBe(POM.getWorkspace());
});

it('should keep focus on appointment when deleting is canceled', async () => {
const { POM } = await createScheduler({
dataSource: [...dataSource],
currentView: 'day',
currentDate: new Date(2015, 1, 9),
onAppointmentDeleting: (e) => {
e.cancel = true;
},
});

const appointment = POM.getAppointment('Appointment 2');
appointment.element?.focus();
fireEvent.keyDown(appointment.element as Element, { key: 'Delete' });
await new Promise(process.nextTick);

expect(POM.getAppointments().length).toBe(3);
expect(document.activeElement).toBe(appointment.element);
});

it('should focus next occurrence after deleting recurring occurrence via dialog', async () => {
const { POM } = 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();
fireEvent.keyDown(appointment.element, { key: 'Delete' });
POM.popup.deleteAppointmentButton.click();
await new Promise(process.nextTick);

expect(POM.getAppointments().length).toBe(initialCount - 1);
expect(document.activeElement).toBe(POM.getAppointments()[2].element);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ class SchedulerAppointments extends CollectionWidget<any> {
}

this._attachAppointmentsEvents();
this._kbn.onItemsRendered();
break;
case 'fixedContainer':
case 'allDayContainer':
Expand Down
Loading
Loading