Skip to content

Commit

Permalink
feat(month picker): add AKB navigation tests and update README.md #3126
Browse files Browse the repository at this point in the history
  • Loading branch information
SAndreeva committed Feb 12, 2019
1 parent 3d9f3f7 commit 407f5ec
Show file tree
Hide file tree
Showing 6 changed files with 354 additions and 9 deletions.
25 changes: 23 additions & 2 deletions projects/igniteui-angular/src/lib/calendar/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# igxCalendar Component

The **igxCalendar** provides a way for the user to select date(s).
The **igxCalendar** provides a way for the user to select date(s).
A walkthrough of how to get started can be found [here](https://www.infragistics.com/products/ignite-ui-angular/angular/components/calendar.html)

## Dependencies
Expand Down Expand Up @@ -67,16 +67,37 @@ When the **igxCalendar** component is focused:
- `Shift + PageDown` will move to the next year.
- `Home` will focus the first day of the current month that is into view.
- `End` will focus the last day of the current month that is into view.
- `Tab` will navigate through the subheader buttons;

When `prev` or `next` month buttons (in the subheader) are focused:
- `Space` will scroll into view the next or previous month.

When `months` button (in the subheader) is focused:
- `Space` or `Enter` will open the months view.

When `year` button (in the subheader) is focused:
- `Space` or `Enter` will open the decade view.

When a day inside the current month is focused:
- Arrow keys will navigate through the days.
- Arrow keys will allow navigation to previous/next month as well.
- `Enter` will select the currently focused day.

When a month inside the months view is focused:
- Arrow keys will navigate through the months.
- `Home` will focus the first month inside the months view.
- `End` will focus the last month inside the months view.
- `Enter` will select the currently focused month and close the view.

When an year inside the decade view is focused:
- Arrow keys will navigate through the years.
- `Enter` will select the currently focused year and close the view.

## API Summary

### Inputs

- `id: string`
- `id: string`

Unique identifier of the component. If not provided it will be automatically generated.

Expand Down
307 changes: 307 additions & 0 deletions projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1605,6 +1605,313 @@ describe('IgxCalendar', () => {
expect(calendar.value).toEqual([]);
});
});

describe('Advanced KB Navigation', () => {
configureTestSuite();

beforeEach(
async(() => {
TestBed.configureTestingModule({
declarations: [IgxCalendarSampleComponent],
imports: [IgxCalendarModule, FormsModule, NoopAnimationsModule]
}).compileComponents();
})
);

it('AKB - should navigate to the previous/next month via KB.', async () => {
const fixture = TestBed.createComponent(IgxCalendarSampleComponent);
fixture.detectChanges();

const calendar = fixture.componentInstance.calendar;
const dom = fixture.debugElement;

const prev = dom.queryAll(By.css('.igx-calendar-picker__prev'))[0];
prev.nativeElement.focus();

expect(prev.nativeElement).toBe(document.activeElement);

UIInteractions.simulateKeyDownEvent(prev.nativeElement, 'Space');
fixture.detectChanges();

expect(calendar.viewDate.getMonth()).toEqual(4);

const next = dom.queryAll(By.css('.igx-calendar-picker__next'))[0];
next.nativeElement.focus();

expect(next.nativeElement).toBe(document.activeElement);

UIInteractions.simulateKeyDownEvent(next.nativeElement, 'Space');
UIInteractions.simulateKeyDownEvent(next.nativeElement, 'Space');
fixture.detectChanges();

expect(calendar.viewDate.getMonth()).toEqual(6);
});

it('AKB - should open years view, navigate through and select an year via KB.', async () => {
const fixture = TestBed.createComponent(IgxCalendarSampleComponent);
fixture.detectChanges();

const calendar = fixture.componentInstance.calendar;
const dom = fixture.debugElement;

const year = dom.queryAll(By.css('.igx-calendar-picker__date'))[1];
year.nativeElement.focus();

expect(year.nativeElement).toBe(document.activeElement);

UIInteractions.simulateKeyDownEvent(document.activeElement, 'Enter');
fixture.detectChanges();

const years = dom.queryAll(By.css('.igx-calendar__year'));
let currentYear = dom.query(By.css('.igx-calendar__year--current'));

expect(years.length).toEqual(6);
expect(currentYear.nativeElement.textContent.trim()).toMatch('2017');

UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'ArrowDown');
fixture.detectChanges();

currentYear = dom.query(By.css('.igx-calendar__year--current'));
expect(currentYear.nativeElement.textContent.trim()).toMatch('2018');

UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'ArrowUp');
UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'ArrowUp');
fixture.detectChanges();

currentYear = dom.query(By.css('.igx-calendar__year--current'));
expect(currentYear.nativeElement.textContent.trim()).toMatch('2016');

UIInteractions.simulateKeyDownEvent(currentYear.nativeElement, 'Enter');
fixture.detectChanges();

expect(calendar.viewDate.getFullYear()).toEqual(2016);
});

it('AKB - should open months view, navigate through and select a month via KB.', async () => {
const fixture = TestBed.createComponent(IgxCalendarSampleComponent);
fixture.detectChanges();

const calendar = fixture.componentInstance.calendar;
const dom = fixture.debugElement;

const month = dom.queryAll(By.css('.igx-calendar-picker__date'))[0];
month.nativeElement.focus();

expect(month.nativeElement).toBe(document.activeElement);

UIInteractions.simulateKeyDownEvent(document.activeElement, 'Enter');
fixture.detectChanges();

const months = dom.queryAll(By.css('.igx-calendar__month'));
let currentMonth = dom.query(By.css('.igx-calendar__month--current'));

expect(months.length).toEqual(11);
expect(currentMonth.nativeElement.textContent.trim()).toMatch('Jun');

UIInteractions.simulateKeyDownEvent(currentMonth.nativeElement, 'Home');
fixture.detectChanges();

currentMonth = dom.query(By.css('.igx-calendar__month--current'));
expect(currentMonth.nativeElement.textContent.trim()).toMatch('Jan');

UIInteractions.simulateKeyDownEvent(currentMonth.nativeElement, 'End');
fixture.detectChanges();

currentMonth = dom.query(By.css('.igx-calendar__month--current'));
expect(currentMonth.nativeElement.textContent.trim()).toMatch('Dec');

UIInteractions.simulateKeyDownEvent(currentMonth.nativeElement, 'ArrowLeft');
fixture.detectChanges();

currentMonth = dom.query(By.css('.igx-calendar__month--current'));
UIInteractions.simulateKeyDownEvent(currentMonth.nativeElement, 'ArrowUp');
fixture.detectChanges();

currentMonth = dom.query(By.css('.igx-calendar__month--current'));
UIInteractions.simulateKeyDownEvent(currentMonth.nativeElement, 'ArrowRight');
fixture.detectChanges();

currentMonth = dom.query(By.css('.igx-calendar__month--current'));
expect(currentMonth.nativeElement.textContent.trim()).toMatch('Sep');

UIInteractions.simulateKeyDownEvent(currentMonth.nativeElement, 'Enter');
fixture.detectChanges();

expect(calendar.viewDate.getMonth()).toEqual(8);
});

it('AKB - should navigate to the first enabled date from the previous month when using "arrow up" key.', async () => {
const fixture = TestBed.createComponent(IgxCalendarSampleComponent);
fixture.detectChanges();

const calendar = fixture.componentInstance.calendar;
const dom = fixture.debugElement;

const dateRangeDescriptors: DateRangeDescriptor[] = [];
const specificDates = [
new Date(2017, 4, 25),
new Date(2017, 4, 11)
];

dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates });

calendar.disabledDates = dateRangeDescriptors;
fixture.detectChanges();
await wait(50);

const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement;

UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home');
fixture.detectChanges();

UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp');
fixture.detectChanges();
await wait(400);

let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 4, 18).getTime());
expect(date.nativeElement).toBe(document.activeElement);

UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp');
UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowUp');
fixture.detectChanges();
await wait(400);

date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 3, 27).getTime());
expect(date.nativeElement).toBe(document.activeElement);
});

it('AKB - should navigate to the first enabled date from the previous month when using "arrow left" key.', async () => {
const fixture = TestBed.createComponent(IgxCalendarSampleComponent);
fixture.detectChanges();

const calendar = fixture.componentInstance.calendar;
const dom = fixture.debugElement;

const dateRangeDescriptors: DateRangeDescriptor[] = [];
const specificDates = [
new Date(2017, 4, 27),
new Date(2017, 4, 25)
];

dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates });

calendar.disabledDates = dateRangeDescriptors;
fixture.detectChanges();
await wait(50);

const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement;

UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home');
fixture.detectChanges();

UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft');
UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft');
UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft');
UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft');
UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft');
fixture.detectChanges();
await wait(400);

let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 4, 26).getTime());
expect(date.nativeElement).toBe(document.activeElement);

UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'Home');
fixture.detectChanges();

UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft');
UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowLeft');
fixture.detectChanges();
await wait(400);

date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 3, 29).getTime());
expect(date.nativeElement).toBe(document.activeElement);
});

it('AKB - should navigate to the first enabled date from the next month when using "arrow down" key.', async () => {
const fixture = TestBed.createComponent(IgxCalendarSampleComponent);
fixture.detectChanges();

const calendar = fixture.componentInstance.calendar;
const dom = fixture.debugElement;

const dateRangeDescriptors: DateRangeDescriptor[] = [];
const specificDates = [
new Date(2017, 6, 14),
new Date(2017, 6, 28)
];

dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates });

calendar.disabledDates = dateRangeDescriptors;
fixture.detectChanges();
await wait(50);

const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement;

UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End');
fixture.detectChanges();

UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown');
UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown');
fixture.detectChanges();
await wait(400);

let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 6, 21).getTime());
expect(date.nativeElement).toBe(document.activeElement);

UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown');
UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown');
fixture.detectChanges();
await wait(400);

date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 7, 11).getTime());
expect(date.nativeElement).toBe(document.activeElement);
});

it('AKB - should navigate to the first enabled date from the next month when using "arrow right" key.', async () => {
const fixture = TestBed.createComponent(IgxCalendarSampleComponent);
fixture.detectChanges();

const calendar = fixture.componentInstance.calendar;
const dom = fixture.debugElement;

const dateRangeDescriptors: DateRangeDescriptor[] = [];
const specificDates = [
new Date(2017, 6, 9),
new Date(2017, 6, 10)
];

dateRangeDescriptors.push({ type: DateRangeType.Specific, dateRange: specificDates });

calendar.disabledDates = dateRangeDescriptors;
fixture.detectChanges();
await wait(50);

const calendarNativeElement = dom.query(By.css('.igx-calendar')).nativeElement;

UIInteractions.simulateKeyDownEvent(calendarNativeElement, 'End');
fixture.detectChanges();

UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowDown');
UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight');
UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight');
fixture.detectChanges();
await wait(400);

let date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 6, 11).getTime());
expect(date.nativeElement).toBe(document.activeElement);

date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 7, 5).getTime());
date.nativeElement.focus();

UIInteractions.simulateKeyDownEvent(document.activeElement, 'ArrowRight');
fixture.detectChanges();
await wait(400);

date = calendar.daysView.dates.find(d => getDate(d).getTime() === new Date(2017, 7, 6).getTime());
expect(date.nativeElement).toBe(document.activeElement);
});
});
});

@Component({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
ViewChildren,
QueryList,
HostBinding,
forwardRef,
DoCheck
} from '@angular/core';
import { ICalendarDate, Calendar, WEEKDAYS, isDateInRanges } from '../../calendar';
Expand Down Expand Up @@ -321,7 +320,7 @@ export class IgxDaysViewComponent implements ControlValueAccessor, DoCheck {
/**
* @hidden
*/
@ViewChildren(forwardRef(() => IgxDayItemComponent), { read: IgxDayItemComponent })
@ViewChildren(IgxDayItemComponent, { read: IgxDayItemComponent })
public dates: QueryList<IgxDayItemComponent>;


Expand Down
Loading

0 comments on commit 407f5ec

Please sign in to comment.