igniteui-angular-sovn
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
1,025 lines (812 loc) • 42.2 kB
text/typescript
import { TestBed } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { IgxGridComponent } from './grid.component';
import { IGridCellEventArgs, IActiveNodeChangeEventArgs } from '../common/events';
import { DefaultSortingStrategy, SortingDirection } from '../../data-operations/sorting-strategy';
import { UIInteractions, wait } from '../../test-utils/ui-interactions.spec';
import { clearGridSubs, setupGridScrollDetection } from '../../test-utils/helper-utils.spec';
import { configureTestSuite } from '../../test-utils/configure-suite';
import {
VirtualGridComponent,
NoScrollsComponent,
IgxGridGroupByComponent
} from '../../test-utils/grid-samples.spec';
import { GridFunctions, GridSelectionFunctions } from '../../test-utils/grid-functions.spec';
import { DebugElement, QueryList } from '@angular/core';
import { IgxGridGroupByRowComponent } from './groupby-row.component';
import { CellType } from '../common/grid.interface';
const DEBOUNCETIME = 30;
describe('IgxGrid - Keyboard navigation #grid', () => {
describe('in not virtualized grid', () => {
let fix;
let grid: IgxGridComponent;
let gridContent: DebugElement;
configureTestSuite((() => {
return TestBed.configureTestingModule({
imports: [NoScrollsComponent, NoopAnimationsModule]
});
}));
beforeEach(() => {
fix = TestBed.createComponent(NoScrollsComponent);
fix.detectChanges();
grid = fix.componentInstance.grid;
gridContent = GridFunctions.getGridContent(fix);
});
it('should move selected cell with arrow keys', () => {
let selectedCell: CellType;
grid.selected.subscribe((event: IGridCellEventArgs) => {
selectedCell = event.cell;
});
// Focus and select first cell
GridFunctions.focusFirstCell(fix, grid);
UIInteractions.triggerEventHandlerKeyDown('arrowdown', gridContent);
fix.detectChanges();
expect(selectedCell.value).toEqual(2);
expect(selectedCell.column.field).toMatch('ID');
UIInteractions.triggerEventHandlerKeyDown('arrowright', gridContent);
fix.detectChanges();
expect(selectedCell.value).toEqual('Gilberto Todd');
expect(selectedCell.column.field).toMatch('Name');
UIInteractions.triggerEventHandlerKeyDown('arrowup', gridContent);
fix.detectChanges();
expect(selectedCell.value).toEqual('Casey Houston');
expect(selectedCell.column.field).toMatch('Name');
UIInteractions.triggerEventHandlerKeyDown('arrowleft', gridContent);
fix.detectChanges();
expect(selectedCell.value).toEqual(1);
expect(selectedCell.column.field).toMatch('ID');
});
it('should jump to first/last cell with Ctrl', () => {
let selectedCell: CellType;
grid.selected.subscribe((event: IGridCellEventArgs) => {
selectedCell = event.cell;
});
GridFunctions.focusFirstCell(fix, grid);
UIInteractions.triggerEventHandlerKeyDown('arrowright', gridContent, false, false, true);
fix.detectChanges();
expect(selectedCell.value).toEqual('Company A');
expect(selectedCell.column.field).toMatch('Company');
UIInteractions.triggerEventHandlerKeyDown('arrowleft', gridContent, false, false, true);
fix.detectChanges();
expect(selectedCell.value).toEqual(1);
expect(selectedCell.column.field).toMatch('ID');
});
it('should allow vertical keyboard navigation in pinned area.', () => {
grid.getColumnByName('Name').pinned = true;
fix.detectChanges();
let selectedCell;
grid.selected.subscribe((event: IGridCellEventArgs) => {
selectedCell = event.cell;
});
GridFunctions.focusFirstCell(fix, grid);
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('arrowdown', gridContent);
fix.detectChanges();
expect(selectedCell.value).toEqual('Gilberto Todd');
expect(selectedCell.column.field).toMatch('Name');
UIInteractions.triggerEventHandlerKeyDown('arrowup', gridContent);
fix.detectChanges();
expect(selectedCell.value).toEqual('Casey Houston');
expect(selectedCell.column.field).toMatch('Name');
});
it('Should emit when activeNode ref is changed', () => {
spyOn(grid.activeNodeChange, 'emit').and.callThrough();
const args: IActiveNodeChangeEventArgs = {
row: 0,
column: 0,
level: 0,
tag: 'dataCell'
};
gridContent.triggerEventHandler('focus', null);
fix.detectChanges();
expect(grid.activeNodeChange.emit).toHaveBeenCalledWith(args);
UIInteractions.triggerEventHandlerKeyDown('arrowright', gridContent);
fix.detectChanges();
args.column += 1;
expect(grid.activeNodeChange.emit).toHaveBeenCalledWith(args);
UIInteractions.triggerEventHandlerKeyDown('arrowright', gridContent);
fix.detectChanges();
args.column += 1;
expect(grid.activeNodeChange.emit).toHaveBeenCalledWith(args);
UIInteractions.triggerEventHandlerKeyDown('arrowdown', gridContent);
fix.detectChanges();
args.row += 1;
expect(grid.activeNodeChange.emit).toHaveBeenCalledWith(args);
UIInteractions.triggerEventHandlerKeyDown('arrowleft', gridContent);
fix.detectChanges();
args.column -= 1;
expect(grid.activeNodeChange.emit).toHaveBeenCalledWith(args);
expect(grid.activeNodeChange.emit).toHaveBeenCalledTimes(5);
});
it('should emit activeNodeChange once when you click over the same element', () => {
spyOn(grid.activeNodeChange, 'emit').and.callThrough();
gridContent.triggerEventHandler('focus', null);
fix.detectChanges();
const activeNode = grid.navigation.activeNode;
const cell = grid.gridAPI.get_cell_by_index(activeNode.row, activeNode.column);
UIInteractions.simulateMouseEvent('mousedown', cell.nativeElement, 0, 0);
fix.detectChanges();
expect(grid.activeNodeChange.emit).toHaveBeenCalledTimes(1);
});
it('should allow horizontal keyboard navigation between start pinned area and unpinned area.', () => {
grid.getColumnByName('Name').pinned = true;
grid.getColumnByName('Company').pinned = true;
fix.detectChanges();
let selectedCell;
grid.selected.subscribe((event: IGridCellEventArgs) => {
selectedCell = event.cell;
});
GridFunctions.focusFirstCell(fix, grid);
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('arrowright', gridContent);
fix.detectChanges();
expect(selectedCell.value).toEqual('Company A');
expect(selectedCell.column.field).toMatch('Company');
UIInteractions.triggerEventHandlerKeyDown('arrowright', gridContent);
fix.detectChanges();
expect(selectedCell.value).toEqual(1);
expect(selectedCell.column.field).toMatch('ID');
UIInteractions.triggerEventHandlerKeyDown('arrowleft', gridContent);
fix.detectChanges();
expect(selectedCell.value).toEqual('Company A');
expect(selectedCell.column.field).toMatch('Company');
});
});
describe('in virtualized grid', () => {
let fix;
let grid: IgxGridComponent;
let gridContent: DebugElement;
configureTestSuite((() => {
return TestBed.configureTestingModule({
imports: [NoopAnimationsModule, VirtualGridComponent]
});
}));
beforeEach(() => {
fix = TestBed.createComponent(VirtualGridComponent);
fix.detectChanges();
grid = fix.componentInstance.grid;
setupGridScrollDetection(fix, grid);
fix.detectChanges();
gridContent = GridFunctions.getGridContent(fix);
});
afterEach(() => {
clearGridSubs();
});
it('should focus the first cell when focus the grid body', async () => {
GridFunctions.getGridHeader(grid).nativeElement.focus();
fix.detectChanges();
const cols = [];
for (let i = 0; i < 10; i++) {
cols.push({ field: 'col' + i });
}
fix.componentInstance.columns = cols;
fix.componentInstance.data = fix.componentInstance.generateData(100);
await wait(DEBOUNCETIME);
fix.detectChanges();
grid.headerContainer.getScroll().scrollLeft = 1000;
await wait(100);
fix.detectChanges();
grid.verticalScrollContainer.getScroll().scrollTop = 200;
await wait(200);
fix.detectChanges();
gridContent.triggerEventHandler('focus', null);
await wait(400);
fix.detectChanges();
const cell = grid.gridAPI.get_cell_by_index(4, 'col5');
expect(cell).toBeDefined();
GridSelectionFunctions.verifyCellActive(cell);
GridSelectionFunctions.verifyCellSelected(cell);
});
it('should allow navigating down', async () => {
GridFunctions.focusFirstCell(fix, grid);
await wait();
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('arrowdown', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('arrowdown', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('arrowdown', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(fix.componentInstance.selectedCell.row.index).toEqual(3);
});
it('should allow navigating up', async () => {
grid.verticalScrollContainer.scrollTo(104);
await wait();
fix.detectChanges();
const cell = grid.gridAPI.get_cell_by_index(100, 'value');
UIInteractions.simulateClickAndSelectEvent(cell);
await wait();
fix.detectChanges();
expect(fix.componentInstance.selectedCell.row.index).toEqual(100);
// Navigate to the 94th row
UIInteractions.triggerEventHandlerKeyDown('arrowup', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('arrowup', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('arrowup', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(fix.componentInstance.selectedCell.row.index).toEqual(97);
});
it('should allow horizontal navigation', async () => {
const cols = [];
for (let i = 0; i < 10; i++) {
cols.push({ field: 'col' + i });
}
fix.componentInstance.columns = cols;
fix.componentInstance.data = fix.componentInstance.generateData(1000);
await wait(DEBOUNCETIME);
fix.detectChanges();
GridFunctions.focusFirstCell(fix, grid);
await wait();
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('ArrowRight', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('ArrowRight', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('ArrowRight', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(fix.componentInstance.selectedCell.column.index).toEqual(3);
UIInteractions.triggerEventHandlerKeyDown('ArrowLeft', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(fix.componentInstance.selectedCell.column.index).toEqual(2);
});
it('should allow horizontal navigation in virtualized grid with pinned cols.', async () => {
const cols = [];
for (let i = 0; i < 10; i++) {
cols.push({ field: 'col' + i });
}
fix.componentInstance.columns = cols;
fix.detectChanges();
fix.componentInstance.data = fix.componentInstance.generateData(1000);
fix.detectChanges();
grid.pinColumn('col1');
grid.pinColumn('col3');
await wait(DEBOUNCETIME);
fix.detectChanges();
GridFunctions.focusFirstCell(fix, grid);
await wait(DEBOUNCETIME);
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('ArrowRight', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('ArrowRight', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(fix.componentInstance.selectedCell.column.visibleIndex).toEqual(2);
// Verify columns
let cells = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray();
expect(cells.length).toEqual(5);
expect(cells[0].column.field).toEqual('col1');
expect(cells[1].column.field).toEqual('col3');
expect(cells[3].column.field).toEqual('col2');
expect(cells[4].column.field).toEqual('col4');
UIInteractions.triggerEventHandlerKeyDown('ArrowLeft', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('ArrowLeft', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(fix.componentInstance.selectedCell.column.visibleIndex).toEqual(0);
cells = (grid.gridAPI.get_row_by_index(0).cells as QueryList<CellType>).toArray();
expect(cells.length).toEqual(5);
expect(cells[0].column.field).toEqual('col1');
expect(cells[1].column.field).toEqual('col3');
expect(cells[2].column.field).toEqual('col0');
expect(cells[3].column.field).toEqual('col2');
});
it('should scroll into view the not fully visible cells when navigating down', async () => {
fix.componentInstance.columns = fix.componentInstance.generateCols(100);
fix.componentInstance.data = fix.componentInstance.generateData(1000);
fix.detectChanges();
const rows = GridFunctions.getRows(fix);
const cell = grid.gridAPI.get_cell_by_index(3, '1');
const bottomRowHeight = rows[4].nativeElement.offsetHeight;
const displayContainer = GridFunctions.getGridDisplayContainer(fix).nativeElement;
const bottomCellVisibleHeight = displayContainer.parentElement.offsetHeight % bottomRowHeight;
UIInteractions.simulateClickAndSelectEvent(cell);
await wait();
fix.detectChanges();
expect(fix.componentInstance.selectedCell.value).toEqual(30);
expect(fix.componentInstance.selectedCell.column.field).toMatch('1');
UIInteractions.triggerEventHandlerKeyDown('arrowdown', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(parseInt(displayContainer.style.top, 10)).toBeLessThanOrEqual(-1 * (grid.rowHeight - bottomCellVisibleHeight));
expect(displayContainer.parentElement.scrollTop).toEqual(0);
expect(fix.componentInstance.selectedCell.value).toEqual(40);
expect(fix.componentInstance.selectedCell.column.field).toMatch('1');
});
it('should scroll into view the not fully visible cells when navigating up', async () => {
fix.componentInstance.columns = fix.componentInstance.generateCols(100);
fix.componentInstance.data = fix.componentInstance.generateData(1000);
fix.detectChanges();
const displayContainer = GridFunctions.getGridDisplayContainer(fix).nativeElement;
fix.componentInstance.scrollTop(25);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(displayContainer.style.top).toEqual('-25px');
const cell = grid.gridAPI.get_cell_by_index(1, '1');
UIInteractions.simulateClickAndSelectEvent(cell);
await wait();
fix.detectChanges();
expect(fix.componentInstance.selectedCell.value).toEqual(10);
expect(fix.componentInstance.selectedCell.column.field).toMatch('1');
UIInteractions.triggerEventHandlerKeyDown('arrowup', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
fix.detectChanges();
expect(displayContainer.style.top).toEqual('0px');
expect(fix.componentInstance.selectedCell.value).toEqual(0);
expect(fix.componentInstance.selectedCell.column.field).toMatch('1');
});
it('should allow navigating first/last cell in column with down/up and Ctrl key.', async () => {
let cell = grid.gridAPI.get_cell_by_index(1, 'value');
UIInteractions.simulateClickAndSelectEvent(cell);
await wait();
fix.detectChanges();
UIInteractions.triggerKeyDownEvtUponElem('arrowdown', cell.nativeElement, true, false, false, true);
await wait(100);
fix.detectChanges();
let cell2 = grid.getCellByColumn(999, 'value');
GridSelectionFunctions.verifyGridCellSelected(fix, cell2);
cell = grid.gridAPI.get_cell_by_index(998, 'other');
UIInteractions.simulateClickAndSelectEvent(cell);
await wait();
fix.detectChanges();
UIInteractions.triggerKeyDownEvtUponElem('arrowup', cell.nativeElement, true, false, false, true);
await wait(100);
fix.detectChanges();
cell2 = grid.getCellByColumn(0, 'other');
GridSelectionFunctions.verifyGridCellSelected(fix, cell2);
});
it('should allow navigating first/last cell in column with home/end and Cntr key.', async () => {
fix.componentInstance.columns = fix.componentInstance.generateCols(50);
fix.componentInstance.data = fix.componentInstance.generateData(500);
fix.detectChanges();
grid.verticalScrollContainer.addScrollTop(5000);
await wait(100);
fix.detectChanges();
let cell = grid.gridAPI.get_cell_by_index(101, '2');
UIInteractions.simulateClickAndSelectEvent(cell);
await wait();
fix.detectChanges();
UIInteractions.triggerKeyDownEvtUponElem('home', cell.nativeElement, true, false, false, true);
await wait(150);
fix.detectChanges();
let cell2 = grid.getCellByColumn(0, '0');
GridSelectionFunctions.verifyGridCellSelected(fix, cell2);
expect(grid.verticalScrollContainer.getScroll().scrollTop).toEqual(0);
cell = grid.gridAPI.get_cell_by_index(4, '2');
UIInteractions.simulateClickAndSelectEvent(cell);
await wait();
fix.detectChanges();
UIInteractions.triggerKeyDownEvtUponElem('end', cell.nativeElement, true, false, false, true);
await wait(200);
fix.detectChanges();
cell2 = grid.getCellByColumn(499, '49');
GridSelectionFunctions.verifyGridCellSelected(fix, cell2);
});
it('should scroll into view the not fully visible cells when navigating left', async () => {
grid.tbody.nativeElement.focus();
fix.detectChanges();
fix.componentInstance.columns = fix.componentInstance.generateCols(100);
fix.componentInstance.data = fix.componentInstance.generateData(1000);
fix.detectChanges();
const rowDisplayContainer = GridFunctions.getRowDisplayContainer(fix, 1).nativeElement;
fix.componentInstance.scrollLeft(50);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(rowDisplayContainer.style.left).toEqual('-50px');
const curCell = grid.gridAPI.get_cell_by_index(1, '1');
UIInteractions.simulateClickAndSelectEvent(curCell);
await wait();
fix.detectChanges();
expect(fix.componentInstance.selectedCell.value).toEqual(10);
expect(fix.componentInstance.selectedCell.column.field).toMatch('1');
UIInteractions.triggerKeyDownEvtUponElem('arrowleft', grid.tbody.nativeElement, true);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(rowDisplayContainer.style.left).toEqual('0px');
expect(fix.componentInstance.selectedCell.value).toEqual(0);
expect(fix.componentInstance.selectedCell.column.field).toMatch('0');
});
it('should scroll into view the not fully visible cells when navigating right', async () => {
grid.tbody.nativeElement.focus();
fix.detectChanges();
fix.componentInstance.columns = fix.componentInstance.generateCols(100);
fix.componentInstance.data = fix.componentInstance.generateData(1000);
fix.detectChanges();
const rowDisplayContainer = GridFunctions.getRowDisplayContainer(fix, 1).nativeElement;
expect(rowDisplayContainer.style.left).toEqual('0px');
const curCell = grid.gridAPI.get_cell_by_index(1, '2');
UIInteractions.simulateClickAndSelectEvent(curCell);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(fix.componentInstance.selectedCell.value).toEqual(20);
expect(fix.componentInstance.selectedCell.column.field).toMatch('2');
UIInteractions.triggerKeyDownEvtUponElem('arrowright', grid.tbody.nativeElement, true);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(fix.componentInstance.selectedCell.value).toEqual(30);
expect(fix.componentInstance.selectedCell.column.field).toMatch('3');
expect(parseInt(rowDisplayContainer.style.left, 10)).toBeLessThanOrEqual(-40);
});
it('should scroll first row into view when pressing arrow up', (async () => {
grid.reflow();
fix.componentInstance.scrollTop(25);
await wait(DEBOUNCETIME);
fix.detectChanges();
let scrollContainer = grid.verticalScrollContainer.dc.instance._viewContainer;
let scrollContainerOffset = scrollContainer.element.nativeElement.offsetTop;
expect(scrollContainerOffset).toEqual(-25);
const cell = grid.gridAPI.get_cell_by_index(1, 'value');
UIInteractions.simulateClickAndSelectEvent(cell);
await wait();
fix.detectChanges();
expect(fix.componentInstance.selectedCell.value).toEqual(10);
expect(fix.componentInstance.selectedCell.column.field).toMatch('value');
UIInteractions.triggerEventHandlerKeyDown('arrowup', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
scrollContainer = grid.verticalScrollContainer.dc.instance._viewContainer;
scrollContainerOffset = scrollContainer.element.nativeElement.offsetTop;
expect(scrollContainerOffset).toEqual(0);
expect(fix.componentInstance.selectedCell.value).toEqual(0);
expect(fix.componentInstance.selectedCell.column.field).toMatch('value');
}));
it('should allow pageup/pagedown navigation when the grid is focused', async () => {
fix.componentInstance.columns = fix.componentInstance.generateCols(25);
fix.componentInstance.data = fix.componentInstance.generateData(25);
fix.detectChanges();
GridFunctions.focusFirstCell(fix, grid);
await wait();
fix.detectChanges();
// testing the pagedown key
UIInteractions.triggerEventHandlerKeyDown('PageDown', gridContent);
grid.cdr.detectChanges();
await wait();
let currScrollTop = grid.verticalScrollContainer.getScroll().scrollTop;
expect(currScrollTop).toEqual(grid.verticalScrollContainer.igxForContainerSize);
// testing the pageup key
UIInteractions.triggerEventHandlerKeyDown('PageUp', gridContent);
grid.cdr.detectChanges();
await wait();
currScrollTop = grid.headerContainer.getScroll().scrollTop;
expect(currScrollTop).toEqual(0);
});
it('Custom KB navigation: should be able to scroll to a random cell in the grid', async () => {
fix.componentInstance.columns = fix.componentInstance.generateCols(25);
fix.componentInstance.data = fix.componentInstance.generateData(25);
fix.detectChanges();
GridFunctions.focusFirstCell(fix, grid);
grid.navigateTo(15, 1, (args) => {
args.target.activate(null);
});
fix.detectChanges();
await wait(200);
fix.detectChanges();
const target = grid.gridAPI.get_cell_by_index(15, '1');
expect(target).toBeDefined();
GridSelectionFunctions.verifyCellSelected(target);
GridSelectionFunctions.verifyCellActive(target);
});
it('Custom KB navigation: should be able to scroll horizontally and vertically to a cell in the grid', async () => {
fix.componentInstance.columns = fix.componentInstance.generateCols(100);
fix.componentInstance.data = fix.componentInstance.generateData(100);
fix.detectChanges();
await wait(DEBOUNCETIME);
GridFunctions.focusFirstCell(fix, grid);
grid.navigateTo(50, 50, (args) => {
args.target.activate(null);
});
await wait(DEBOUNCETIME);
fix.detectChanges();
await wait(DEBOUNCETIME);
fix.detectChanges();
const target = grid.gridAPI.get_cell_by_index(50, '50');
expect(target).toBeDefined();
GridSelectionFunctions.verifyCellSelected(target);
GridSelectionFunctions.verifyCellActive(target);
});
it('Custom KB navigation: gridKeydown should be emitted', async () => {
fix.componentInstance.columns = fix.componentInstance.generateCols(25);
fix.componentInstance.data = fix.componentInstance.generateData(25);
fix.detectChanges();
const gridKeydown = spyOn<any>(grid.gridKeydown, 'emit').and.callThrough();
const cell = grid.gridAPI.get_cell_by_index(1, '2');
UIInteractions.simulateClickAndSelectEvent(cell);
fix.detectChanges();
UIInteractions.triggerKeyDownEvtUponElem('arrowup', cell.nativeElement, true);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(gridKeydown).toHaveBeenCalledTimes(1);
expect(gridKeydown).toHaveBeenCalledWith({
targetType: 'dataCell', target: cell, cancel: false, event: new KeyboardEvent('keydown')
});
});
});
describe('Group By navigation ', () => {
configureTestSuite((() => {
return TestBed.configureTestingModule({
imports: [IgxGridGroupByComponent, NoopAnimationsModule]
});
}));
let fix;
let grid: IgxGridComponent;
let gridContent;
beforeEach(() => {
fix = TestBed.createComponent(IgxGridGroupByComponent);
fix.detectChanges();
grid = fix.componentInstance.grid;
gridContent = GridFunctions.getGridContent(fix);
setupGridScrollDetection(fix, grid);
fix.detectChanges();
});
afterEach(() => {
clearGridSubs();
});
it('should focus the first cell when focus the grid body and there is a grouped column', async () => {
GridFunctions.getGridHeader(grid).nativeElement.focus();
fix.detectChanges();
grid.columnWidth = '200px';
await wait();
fix.detectChanges();
grid.headerContainer.getScroll().scrollLeft = 1000;
await wait(100);
fix.detectChanges();
grid.verticalScrollContainer.getScroll().scrollTop = 200;
await wait(100);
fix.detectChanges();
gridContent.triggerEventHandler('focus', null);
await wait(200);
fix.detectChanges();
expect(grid.verticalScrollContainer.getScroll().scrollTop).toBeGreaterThanOrEqual(100);
});
it('should toggle expand/collapse state of group row with ArrowRight/ArrowLeft key.', () => {
const gRow = grid.groupsRowList.toArray()[0];
const gRowElement = GridFunctions.getGroupedRows(fix)[0];
gRowElement.triggerEventHandler('pointerdown', {});
fix.detectChanges();
expect(gRow.expanded).toBe(true);
UIInteractions.triggerEventHandlerKeyDown('arrowleft', gridContent, true);
fix.detectChanges();
expect(gRow.expanded).toBe(false);
UIInteractions.triggerEventHandlerKeyDown('arrowright', gridContent, true);
fix.detectChanges();
expect(gRow.expanded).toBe(true);
});
it('should toggle expand/collapse state of group row with ArrowUp/ArrowDown key.', () => {
const gRow = grid.groupsRowList.toArray()[0];
const gRowElement = GridFunctions.getGroupedRows(fix)[0];
gRowElement.triggerEventHandler('pointerdown', {});
fix.detectChanges();
expect(gRow.expanded).toBe(true);
UIInteractions.triggerEventHandlerKeyDown('ArrowUp', gridContent, true);
fix.detectChanges();
expect(gRow.expanded).toBe(false);
UIInteractions.triggerEventHandlerKeyDown('ArrowDown', gridContent, true);
fix.detectChanges();
expect(gRow.expanded).toBe(true);
});
it(`focus should stay over the group row when expanding/collapsing
with keyboard and the grid is scrolled to the bottom`, (async () => {
grid.verticalScrollContainer.scrollTo(grid.dataView.length - 1);
await wait(DEBOUNCETIME);
fix.detectChanges();
let groupedRowsCount = grid.groupsRowList.length;
let groupRow = grid.groupsRowList.toArray()[groupedRowsCount - 1];
const groupRowElement = GridFunctions.getGroupedRows(fix)[groupedRowsCount - 1];
groupRowElement.triggerEventHandler('pointerdown', null);
fix.detectChanges();
GridFunctions.verifyGroupRowIsFocused(groupRow);
UIInteractions.triggerEventHandlerKeyDown('ArrowLeft', gridContent, true);
await wait(DEBOUNCETIME);
fix.detectChanges();
groupedRowsCount = grid.groupsRowList.length;
groupRow = grid.groupsRowList.toArray()[groupedRowsCount - 1];
expect(groupRow.index).toEqual(11);
expect(groupRow.expanded).toBeFalsy();
GridFunctions.verifyGroupRowIsFocused(groupRow);
}));
it(`should be able to navigate down to the next row when expand the last group row
and grid is scrolled to bottom`, (async () => {
grid.verticalScrollContainer.scrollTo(grid.dataView.length - 1);
await wait(100);
fix.detectChanges();
grid.groupsRowList.last.toggle();
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(grid.groupsRowList.last.expanded).toBeFalsy();
grid.groupsRowList.last.toggle();
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(grid.groupsRowList.last.expanded).toBeTruthy();
const groupRowIndex = grid.groupsRowList.last.index;
grid.groupsRowList.last.nativeElement.dispatchEvent(new Event('pointerdown'));
await wait();
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('arrowDown', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
const cell = grid.gridAPI.get_cell_by_index(groupRowIndex + 1, 'Downloads');
GridSelectionFunctions.verifyCellSelected(cell);
}));
it('should allow keyboard navigation through group rows.', (async () => {
fix.componentInstance.width = '400px';
fix.componentInstance.height = '300px';
await wait();
fix.detectChanges();
grid.groupBy({
fieldName: 'Released', dir: SortingDirection.Desc,
ignoreCase: false, strategy: DefaultSortingStrategy.instance()
});
await wait();
fix.detectChanges();
let row = grid.gridAPI.get_row_by_index(1);
row.nativeElement.dispatchEvent(new Event('pointerdown'));
await wait();
fix.detectChanges();
UIInteractions.triggerEventHandlerKeyDown('arrowDown', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
row = grid.gridAPI.get_row_by_index(2);
expect((row.cells as QueryList<CellType>).toArray()[0].selected).toBe(true);
UIInteractions.triggerEventHandlerKeyDown('arrowUp', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
row = grid.gridAPI.get_row_by_index(1);
expect(row.focused).toBeTrue();
}));
it('should persist last selected cell column index when navigate through group rows.', async () => {
fix.componentInstance.width = '400px';
fix.componentInstance.height = '300px';
grid.columnWidth = '200px';
await wait(DEBOUNCETIME);
fix.detectChanges();
grid.groupBy({
fieldName: 'Released', dir: SortingDirection.Desc,
ignoreCase: false, strategy: DefaultSortingStrategy.instance()
});
fix.detectChanges();
grid.headerContainer.getScroll().scrollLeft = 1000;
await wait(DEBOUNCETIME);
const cell = grid.gridAPI.get_cell_by_index(2, 'Released');
UIInteractions.simulateClickAndSelectEvent(cell);
await wait();
fix.detectChanges();
let row;
for (let index = 2; index < 9; index++) {
row = grid.gridAPI.get_row_by_index(index);
if (!(row instanceof IgxGridGroupByRowComponent)) {
const selectedCell = grid.selectedCells[0];
expect(selectedCell.row.index).toEqual(index);
expect(selectedCell.column.field).toEqual('Released');
}
UIInteractions.triggerEventHandlerKeyDown('arrowDown', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
}
let cell2 = grid.getCellByColumn(9, 'Released');
expect(cell2.selected).toBe(true);
for (let index = 9; index > 1; index--) {
row = grid.gridAPI.get_row_by_index(index);
if (!(row instanceof IgxGridGroupByRowComponent)) {
const selectedCell = grid.selectedCells[0];
expect(selectedCell.row.index).toEqual(index);
expect(selectedCell.column.field).toEqual('Released');
}
UIInteractions.triggerEventHandlerKeyDown('arrowUp', gridContent);
await wait(DEBOUNCETIME);
fix.detectChanges();
}
row = grid.gridAPI.get_row_by_index(1);
expect(row instanceof IgxGridGroupByRowComponent).toBe(true);
expect(row.focused).toBe(true);
cell2 = grid.getCellByColumn(2, 'Released');
expect(cell2.selected).toBe(true);
});
it('should focus grouped row when press arrow keys up or down', (async () => {
grid.tbody.nativeElement.focus();
fix.detectChanges();
let cell = grid.gridAPI.get_cell_by_index(1, 'ID');
UIInteractions.simulateClickAndSelectEvent(cell);
await wait();
fix.detectChanges();
expect(cell.selected).toBe(true);
UIInteractions.triggerKeyDownEvtUponElem('ArrowUp', grid.tbody.nativeElement, true);
await wait();
fix.detectChanges();
let groupRow = grid.groupsRowList.toArray()[0];
cell = grid.gridAPI.get_cell_by_index(1, 'ID');
GridFunctions.verifyGroupRowIsFocused(groupRow);
cell = grid.gridAPI.get_cell_by_index(2, 'ProductName');
UIInteractions.simulateClickAndSelectEvent(cell);
await wait();
fix.detectChanges();
expect(cell.active).toBe(true);
expect(cell.selected).toBe(true);
UIInteractions.triggerKeyDownEvtUponElem('ArrowDown', grid.tbody.nativeElement, true);
await wait();
fix.detectChanges();
groupRow = grid.groupsRowList.toArray()[1];
GridFunctions.verifyGroupRowIsFocused(groupRow);
expect(cell.selected).toBe(true);
}));
it('should keep selected cell when expand/collapse grouped row ', (async () => {
grid.tbody.nativeElement.focus();
fix.detectChanges();
const cell = grid.gridAPI.get_cell_by_index(2, 'Released');
UIInteractions.simulateClickAndSelectEvent(cell);
await wait();
fix.detectChanges();
UIInteractions.triggerKeyDownEvtUponElem('ArrowDown', grid.tbody.nativeElement, true);
await wait();
fix.detectChanges();
const groupRow = grid.groupsRowList.toArray()[1];
GridFunctions.verifyGroupRowIsFocused(groupRow);
expect(cell.selected).toBe(true);
UIInteractions.triggerKeyDownEvtUponElem('ArrowUp', groupRow.nativeElement, true, true);
await wait();
fix.detectChanges();
expect(cell.selected).toBe(true);
expect(groupRow.expanded).toBe(false);
UIInteractions.triggerKeyDownEvtUponElem('ArrowDown', groupRow.nativeElement, true, true);
await wait();
fix.detectChanges();
expect(cell.selected).toBe(true);
expect(groupRow.expanded).toBe(true);
}));
it('Custom KB navigation: should be able to scroll to a random row and pass a cb', async () => {
fix.componentInstance.width = '600px';
fix.componentInstance.height = '500px';
grid.columnWidth = '200px';
await wait(DEBOUNCETIME);
fix.detectChanges();
grid.navigateTo(9, -1, (args) => {
args.target.nativeElement.dispatchEvent(new Event('pointerdown'));
});
await wait(100);
fix.detectChanges();
await wait(100);
fix.detectChanges();
const target = grid.rowList.find(r => r.index === 9);
expect(target).toBeDefined();
GridFunctions.verifyGroupRowIsFocused(target);
});
it('Custom KB navigation: gridKeydown should be emitted for ', async () => {
fix.componentInstance.width = '600px';
fix.componentInstance.height = '500px';
grid.columnWidth = '200px';
await wait(DEBOUNCETIME);
fix.detectChanges();
const rowEl = grid.rowList.find(r => r.index === 0);
UIInteractions.simulateClickAndSelectEvent(rowEl);
fix.detectChanges();
const gridKeydown = spyOn<any>(grid.gridKeydown, 'emit').and.callThrough();
UIInteractions.triggerKeyDownEvtUponElem('Enter', rowEl.nativeElement, true);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(gridKeydown).toHaveBeenCalledTimes(1);
expect(gridKeydown).toHaveBeenCalledWith({
targetType: 'groupRow', target: rowEl, cancel: false, event: new KeyboardEvent('keydown')
});
UIInteractions.triggerKeyDownEvtUponElem('ArrowDown', rowEl.nativeElement, true);
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(gridKeydown).toHaveBeenCalledTimes(2);
expect(gridKeydown).toHaveBeenCalledWith({
targetType: 'groupRow', target: rowEl, cancel: false, event: new KeyboardEvent('keydown')
});
});
});
});