igniteui-angular-sovn
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
1,109 lines (895 loc) • 100 kB
text/typescript
import { TestBed, fakeAsync, tick, waitForAsync, ComponentFixture } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { IgxGridComponent } from './grid.component';
import { wait, UIInteractions } from '../../test-utils/ui-interactions.spec';
import { IgxStringFilteringOperand, IgxNumberFilteringOperand } from '../../data-operations/filtering-condition';
import { configureTestSuite } from '../../test-utils/configure-suite';
import {
RowSelectionComponent,
SelectionWithScrollsComponent,
SingleRowSelectionComponent,
RowSelectionWithoutPrimaryKeyComponent,
SelectionWithTransactionsComponent,
GridCustomSelectorsComponent
} from '../../test-utils/grid-samples.spec';
import { GridFunctions, GridSelectionFunctions } from '../../test-utils/grid-functions.spec';
import { SampleTestData } from '../../test-utils/sample-test-data.spec';
import { GridSelectionMode } from '../common/enums';
import { FilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree';
import { FilteringLogic } from '../../data-operations/filtering-expression.interface';
import { SortingDirection } from '../../data-operations/sorting-strategy';
import { IRowSelectionEventArgs } from '../public_api';
const DEBOUNCETIME = 30;
const SCROLL_DEBOUNCETIME = 100;
describe('IgxGrid - Row Selection #grid', () => {
configureTestSuite();
beforeAll(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
NoopAnimationsModule,
RowSelectionComponent,
SelectionWithScrollsComponent,
RowSelectionWithoutPrimaryKeyComponent,
SingleRowSelectionComponent,
SelectionWithTransactionsComponent,
GridCustomSelectorsComponent
]
}).compileComponents();
}));
describe('Base tests', () => {
let fix: ComponentFixture<RowSelectionComponent>;
let grid: IgxGridComponent;
const gridData = SampleTestData.foodProductDataExtended();
beforeEach(() => {
fix = TestBed.createComponent(RowSelectionComponent);
fix.detectChanges();
grid = fix.componentInstance.grid;
});
it('Should have checkbox on each row', async () => {
// There can be no virtual scrolling on this grid with its preset height
grid.height = '300px';
fix.detectChanges();
GridSelectionFunctions.verifyHeaderRowHasCheckbox(fix);
GridSelectionFunctions.verifySelectionCheckBoxesAlignment(grid);
for (const row of grid.rowList.toArray()) {
GridSelectionFunctions.verifyRowHasCheckbox(row.nativeElement);
}
GridFunctions.scrollTop(grid, 500);
await wait(SCROLL_DEBOUNCETIME);
fix.detectChanges();
// Verify the grid has scrolled
expect(grid.rowList.first.cells.first.value).not.toBe(1);
GridSelectionFunctions.verifySelectionCheckBoxesAlignment(grid);
for (const row of grid.rowList.toArray()) {
GridSelectionFunctions.verifyRowHasCheckbox(row.nativeElement);
}
});
it('Should persist through scrolling vertical', async () => {
// There can be no virtual scrolling on this grid with its preset height
grid.height = '300px';
fix.detectChanges();
const selectedRow = grid.gridAPI.get_row_by_index(0);
expect(selectedRow).toBeDefined();
GridSelectionFunctions.verifyRowSelected(selectedRow, false);
selectedRow.onRowSelectorClick(UIInteractions.getMouseEvent('click'));
await wait();
fix.detectChanges();
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, true);
GridSelectionFunctions.verifyRowSelected(selectedRow);
expect(grid.selectedRows).toEqual([1]);
GridFunctions.scrollTop(grid, 500);
await wait(SCROLL_DEBOUNCETIME);
fix.detectChanges();
expect(grid.selectedRows).toEqual([1]);
GridSelectionFunctions.verifyRowSelected(grid.rowList.first, false);
GridFunctions.scrollTop(grid, 0);
await wait(SCROLL_DEBOUNCETIME);
fix.detectChanges();
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, true);
GridSelectionFunctions.verifyRowSelected(selectedRow);
expect(grid.selectedRows).toEqual([1]);
});
it('Should have correct checkboxes position when scroll left', (async () => {
grid.width = '300px';
fix.detectChanges();
GridSelectionFunctions.verifySelectionCheckBoxesAlignment(grid);
GridFunctions.scrollLeft(grid, 1000);
await wait(SCROLL_DEBOUNCETIME);
fix.detectChanges();
GridSelectionFunctions.verifySelectionCheckBoxesAlignment(grid);
GridFunctions.scrollLeft(grid, 0);
await wait(SCROLL_DEBOUNCETIME);
fix.detectChanges();
GridSelectionFunctions.verifySelectionCheckBoxesAlignment(grid);
}));
it('Header checkbox should select/deselect all rows', () => {
const allRows = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
const allRowsArray = [gridData[0], gridData[1], gridData[2], gridData[3], gridData[4], gridData[5], gridData[6], gridData[7], gridData[8], gridData[9],
gridData[10], gridData[11], gridData[12], gridData[13], gridData[14], gridData[15], gridData[16], gridData[17], gridData[18]];
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
GridSelectionFunctions.clickHeaderRowCheckbox(fix);
fix.detectChanges();
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, true);
GridSelectionFunctions.verifyRowsArraySelected(grid.rowList.toArray());
expect(grid.selectedRows).toEqual(allRows);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(1);
let args: IRowSelectionEventArgs = {
added: allRowsArray,
cancel: false,
event: jasmine.anything() as any,
newSelection: allRowsArray,
oldSelection: [],
removed: [],
allRowsSelected: true,
owner: grid
};
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
GridSelectionFunctions.clickHeaderRowCheckbox(fix);
fix.detectChanges();
expect(grid.selectedRows).toEqual([]);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, false);
GridSelectionFunctions.verifyRowsArraySelected(grid.rowList.toArray(), false);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(2);
args = {
oldSelection: allRowsArray,
newSelection: [],
added: [],
removed: allRowsArray,
event: jasmine.anything() as any,
cancel: false,
allRowsSelected: false,
owner: grid
};
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
});
it('Header checkbox should deselect all rows - scenario when clicking first row, while header checkbox is clicked', () => {
const firstRow = grid.gridAPI.get_row_by_index(0);
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
GridSelectionFunctions.clickHeaderRowCheckbox(fix);
fix.detectChanges();
expect(firstRow.selected).toBeTruthy();
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, true);
GridSelectionFunctions.clickRowCheckbox(firstRow);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, false);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, true);
GridSelectionFunctions.clickRowCheckbox(firstRow);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, true);
GridSelectionFunctions.clickHeaderRowCheckbox(fix);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, false);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(4);
});
it('Checkbox should select/deselect row', () => {
const firstRow = grid.gridAPI.get_row_by_index(0);
const secondRow = grid.gridAPI.get_row_by_index(1);
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
GridSelectionFunctions.clickRowCheckbox(firstRow);
fix.detectChanges();
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(1);
let args: IRowSelectionEventArgs = {
added: [gridData[0]],
cancel: false,
event: jasmine.anything() as any,
newSelection: [gridData[0]],
oldSelection: [],
removed: [],
allRowsSelected: false,
owner: grid
};
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
expect(grid.selectedRows).toEqual([1]);
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(secondRow, false);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, true);
GridSelectionFunctions.clickRowCheckbox(secondRow);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(secondRow);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, true);
expect(grid.selectedRows).toEqual([1, 2]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(2);
args = {
added: [gridData[1]],
cancel: false,
event: jasmine.anything() as any,
newSelection: [gridData[0], gridData[1]],
oldSelection: [gridData[0]],
removed: [],
allRowsSelected: false,
owner: grid
};
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
GridSelectionFunctions.clickRowCheckbox(firstRow);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, false);
GridSelectionFunctions.verifyRowSelected(secondRow);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, true);
expect(grid.selectedRows).toEqual([2]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(3);
args = {
added: [],
cancel: false,
event: jasmine.anything() as any,
newSelection: [gridData[1]],
oldSelection: [gridData[0], gridData[1]],
removed: [gridData[0]],
allRowsSelected: false,
owner: grid
};
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
GridSelectionFunctions.clickRowCheckbox(secondRow);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, false);
GridSelectionFunctions.verifyRowSelected(secondRow, false);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix);
expect(grid.selectedRows).toEqual([]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(4);
args = {
added: [],
cancel: false,
event: jasmine.anything() as any,
newSelection: [],
oldSelection: [gridData[1]],
removed: [gridData[1]],
allRowsSelected: false,
owner: grid
};
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
});
it('Should select the row with mouse click ', () => {
expect(grid.selectRowOnClick).toBe(true);
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
const firstRow = grid.gridAPI.get_row_by_index(1);
const secondRow = grid.gridAPI.get_row_by_index(2);
const mockEvent = new MouseEvent('click');
firstRow.nativeElement.dispatchEvent(mockEvent);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
expect(grid.selectedRows).toEqual([2]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(1);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith({
added: [gridData[1]],
cancel: false,
event: mockEvent,
newSelection: [gridData[1]],
oldSelection: [],
removed: [],
allRowsSelected: false,
owner: grid
});
// Click again on same row
UIInteractions.simulateClickEvent(firstRow.nativeElement);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(1);
// Click on a different row
secondRow.nativeElement.dispatchEvent(mockEvent);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, false);
GridSelectionFunctions.verifyRowSelected(secondRow);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, true);
expect(grid.selectedRows).toEqual([3]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(2);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith({
added: [gridData[2]],
cancel: false,
event: mockEvent,
newSelection: [gridData[2]],
oldSelection: [gridData[1]],
removed: [gridData[1]],
allRowsSelected: false,
owner: grid
});
});
it('Should select the row only on checkbox click when selectRowOnClick has value false', () => {
grid.selectRowOnClick = false;
fix.detectChanges();
expect(grid.selectRowOnClick).toBe(false);
grid.hideRowSelectors = false;
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
const firstRow = grid.gridAPI.get_row_by_index(1);
const secondRow = grid.gridAPI.get_row_by_index(2);
// Click on the first row checkbox
GridSelectionFunctions.clickRowCheckbox(firstRow);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
expect(grid.selectedRows).toEqual([2]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(1);
// Click on the second row
UIInteractions.simulateClickEvent(secondRow.nativeElement);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(secondRow, false);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, true);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(1);
});
it('Should select multiple rows with clicking and holding Ctrl', () => {
expect(grid.selectRowOnClick).toBe(true);
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
const firstRow = grid.gridAPI.get_row_by_index(2);
const secondRow = grid.gridAPI.get_row_by_index(0);
UIInteractions.simulateClickEvent(firstRow.nativeElement);
fix.detectChanges();
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(1);
GridSelectionFunctions.verifyRowSelected(firstRow);
// Click on a different row
UIInteractions.simulateClickEvent(secondRow.nativeElement, false, true);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(secondRow);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, true);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(2);
});
it('Should deselect selected row with clicking and holding Ctrl', () => {
expect(grid.selectRowOnClick).toBe(true);
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
const firstRow = grid.gridAPI.get_row_by_index(2);
const secondRow = grid.gridAPI.get_row_by_index(0);
UIInteractions.simulateClickEvent(firstRow.nativeElement);
fix.detectChanges();
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(1);
GridSelectionFunctions.verifyRowSelected(firstRow);
// Click again on this row holding Ctrl
UIInteractions.simulateClickEvent(firstRow.nativeElement, false, true);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, false);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(2);
// Click on the first and second row
UIInteractions.simulateClickEvent(firstRow.nativeElement);
fix.detectChanges();
UIInteractions.simulateClickEvent(secondRow.nativeElement, false, true);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(secondRow);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(4);
// Click again on the second row
UIInteractions.simulateClickEvent(secondRow.nativeElement, false, true);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(secondRow, false);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, true);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(5);
});
it('Should NOT select rows with clicking and holding Ctrl when selectRowOnClick has false value', () => {
grid.selectRowOnClick = false;
grid.hideRowSelectors = false;
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
const firstRow = grid.gridAPI.get_row_by_index(2);
const secondRow = grid.gridAPI.get_row_by_index(0);
const thirdRow = grid.gridAPI.get_row_by_index(4);
// Click on the first row checkbox
GridSelectionFunctions.clickRowCheckbox(firstRow);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(1);
// Click on the second row checkbox
GridSelectionFunctions.clickRowCheckbox(secondRow);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(secondRow);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(2);
// Click + Ctrl on the third row
UIInteractions.simulateClickEvent(thirdRow.nativeElement);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(secondRow);
GridSelectionFunctions.verifyRowSelected(thirdRow, false);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(2);
});
it('Should select multiple rows with clicking Space on a cell', (async () => {
grid.tbody.nativeElement.focus();
fix.detectChanges();
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
const firstRow = grid.gridAPI.get_row_by_index(0);
const secondRow = grid.gridAPI.get_row_by_index(1);
let cell = grid.gridAPI.get_cell_by_index(0, 'ProductName');
UIInteractions.simulateClickAndSelectEvent(cell);
await wait(DEBOUNCETIME);
fix.detectChanges();
GridSelectionFunctions.verifyCellSelected(cell);
GridSelectionFunctions.verifyRowSelected(firstRow);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(1);
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(secondRow, false);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, true);
UIInteractions.triggerKeyDownEvtUponElem('arrowdown', cell.nativeElement, true);
await wait(DEBOUNCETIME);
fix.detectChanges();
cell = grid.gridAPI.get_cell_by_index(1, 'ProductName');
GridSelectionFunctions.verifyCellSelected(cell);
GridSelectionFunctions.verifyRowSelected(firstRow);
// Click Space on the cell
GridFunctions.simulateGridContentKeydown(fix, 'space');
await wait(DEBOUNCETIME);
fix.detectChanges();
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(2);
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(secondRow);
// Click again Space on the cell
GridFunctions.simulateGridContentKeydown(fix, 'space');
fix.detectChanges();
await wait(DEBOUNCETIME);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(3);
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(secondRow, false);
}));
it('Should select multiple rows with Shift + Click', () => {
expect(grid.selectRowOnClick).toBe(true);
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
const firstRow = grid.gridAPI.get_row_by_index(1);
const secondRow = grid.gridAPI.get_row_by_index(4);
const mockEvent = new MouseEvent('click', { shiftKey: true });
UIInteractions.simulateClickEvent(firstRow.nativeElement);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
// Click on other row holding Shift key
secondRow.nativeElement.dispatchEvent(mockEvent);
fix.detectChanges();
expect(grid.selectedRows).toEqual([2, 3, 4, 5]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(2);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith({
added: [gridData[2], gridData[3], gridData[4]],
cancel: false,
event: mockEvent,
newSelection: [gridData[1], gridData[2], gridData[3], gridData[4]],
oldSelection: [gridData[1]],
removed: [],
allRowsSelected: false,
owner: grid
});
for (let index = 1; index < 5; index++) {
const row = grid.gridAPI.get_row_by_index(index);
GridSelectionFunctions.verifyRowSelected(row);
}
});
it('Should NOT select multiple rows with Shift + Click when selectRowOnClick has false value', () => {
grid.selectRowOnClick = false;
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
// Shift + Click
const firstRow = grid.gridAPI.get_row_by_index(1);
const secondRow = grid.gridAPI.get_row_by_index(4);
UIInteractions.simulateClickEvent(firstRow.nativeElement, false, false);
fix.detectChanges();
expect(grid.selectedRows).toEqual([]);
GridSelectionFunctions.verifyRowSelected(firstRow, false);
// Click on other row holding Shift key
UIInteractions.simulateClickEvent(secondRow.nativeElement, true, false);
fix.detectChanges();
expect(grid.selectedRows).toEqual([]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(0);
GridSelectionFunctions.verifyRowSelected(secondRow, false);
for (let index = 1; index < 4; index++) {
const row = grid.gridAPI.get_row_by_index(index);
GridSelectionFunctions.verifyRowSelected(row, false);
}
});
it('Should hide/show checkboxes when change hideRowSelectors', () => {
const firstRow = grid.gridAPI.get_row_by_index(1);
expect(grid.hideRowSelectors).toBe(false);
firstRow.onRowSelectorClick(UIInteractions.getMouseEvent('click'));
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
grid.hideRowSelectors = true;
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, true, false);
GridSelectionFunctions.verifyHeaderRowHasCheckbox(fix, false, false);
GridSelectionFunctions.verifyRowHasCheckbox(firstRow.nativeElement, false, false);
grid.hideRowSelectors = false;
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, true);
GridSelectionFunctions.verifyHeaderRowHasCheckbox(fix);
GridSelectionFunctions.verifyRowHasCheckbox(firstRow.nativeElement);
});
it('Should be able to change RowSelection to none', () => {
const firstRow = grid.gridAPI.get_row_by_index(0);
expect(grid.rowSelection).toEqual(GridSelectionMode.multiple);
grid.selectRows([1]);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
grid.rowSelection = GridSelectionMode.none;
fix.detectChanges();
expect(grid.rowSelection).toEqual(GridSelectionMode.none);
GridSelectionFunctions.verifyRowSelected(firstRow, false, false);
GridSelectionFunctions.verifyHeaderRowHasCheckbox(fix, false, false);
GridSelectionFunctions.verifyRowHasCheckbox(firstRow.nativeElement, false, false);
// Click on a row
firstRow.onRowSelectorClick(UIInteractions.getMouseEvent('click'));
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, false, false);
});
it('Should be able to change RowSelection to single', () => {
const firstRow = grid.gridAPI.get_row_by_index(0);
const secondRow = grid.gridAPI.get_row_by_index(1);
expect(grid.rowSelection).toEqual(GridSelectionMode.multiple);
grid.selectRows([1]);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
grid.rowSelection = GridSelectionMode.single;
fix.detectChanges();
expect(grid.rowSelection).toEqual(GridSelectionMode.single);
GridSelectionFunctions.verifyRowSelected(firstRow, false);
GridSelectionFunctions.verifyHeaderRowHasCheckbox(fix, false);
GridSelectionFunctions.verifyRowHasCheckbox(firstRow.nativeElement);
GridSelectionFunctions.verifySelectionCheckBoxesAlignment(grid);
// Click on a row
UIInteractions.simulateClickEvent(firstRow.nativeElement);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
// Click on another row holding Ctrl
UIInteractions.simulateClickEvent(secondRow.nativeElement, false, true);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(secondRow);
GridSelectionFunctions.verifyRowSelected(firstRow, false);
});
it('Should be able to cancel rowSelectionChanging event', () => {
const firstRow = grid.gridAPI.get_row_by_index(0);
grid.rowSelectionChanging.subscribe((e: IRowSelectionEventArgs) => {
e.cancel = true;
});
// Click on a row
UIInteractions.simulateClickEvent(firstRow.nativeElement);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, false);
// Click on a row checkbox
GridSelectionFunctions.clickRowCheckbox(firstRow);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, false);
// Click on header checkbox
GridSelectionFunctions.clickHeaderRowCheckbox(fix);
fix.detectChanges();
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix);
GridSelectionFunctions.verifyRowSelected(firstRow, false);
// Select rows from API
grid.selectRows([2, 3]);
fix.detectChanges();
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, true);
GridSelectionFunctions.verifyRowSelected(grid.gridAPI.get_row_by_index(1));
GridSelectionFunctions.verifyRowSelected(grid.gridAPI.get_row_by_index(2));
// Click on header checkbox
GridSelectionFunctions.clickHeaderRowCheckbox(fix);
fix.detectChanges();
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, true);
GridSelectionFunctions.verifyRowSelected(firstRow, false);
GridSelectionFunctions.verifyRowSelected(grid.gridAPI.get_row_by_index(1));
GridSelectionFunctions.verifyRowSelected(grid.gridAPI.get_row_by_index(2));
// Select all rows from API
grid.selectAllRows();
fix.detectChanges();
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, true);
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(grid.gridAPI.get_row_by_index(1));
GridSelectionFunctions.verifyRowSelected(grid.gridAPI.get_row_by_index(2));
// Click on header checkbox
GridSelectionFunctions.clickHeaderRowCheckbox(fix);
fix.detectChanges();
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, true);
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(grid.gridAPI.get_row_by_index(1));
GridSelectionFunctions.verifyRowSelected(grid.gridAPI.get_row_by_index(2));
});
it('Should be able to programmatically overwrite the selection using rowSelectionChanging event', () => {
const firstRow = grid.gridAPI.get_row_by_index(0);
const secondRow = grid.gridAPI.get_row_by_index(1);
const thirdRow = grid.gridAPI.get_row_by_index(2);
grid.rowSelectionChanging.subscribe((e: IRowSelectionEventArgs) => {
if (e.added.length > 0 && (e.added[0].ProductID) % 2 === 0) {
e.newSelection = e.oldSelection || [];
}
});
GridSelectionFunctions.verifyRowsArraySelected([firstRow, secondRow, thirdRow], false);
GridSelectionFunctions.clickRowCheckbox(firstRow);
fix.detectChanges();
expect(firstRow.selected).toBeTruthy();
expect(secondRow.selected).toBeFalsy();
expect(thirdRow.selected).toBeFalsy();
GridSelectionFunctions.clickRowCheckbox(firstRow);
GridSelectionFunctions.clickRowCheckbox(secondRow);
fix.detectChanges();
expect(firstRow.selected).toBeFalsy();
expect(secondRow.selected).toBeFalsy();
GridSelectionFunctions.verifyRowsArraySelected([firstRow, secondRow, thirdRow], false);
});
it('ARIA support', () => {
const firstRow = grid.gridAPI.get_row_by_index(0).nativeElement;
const headerCheckbox = GridSelectionFunctions.getRowCheckboxInput(GridSelectionFunctions.getHeaderRow(fix));
expect(firstRow.getAttribute('aria-selected')).toMatch('false');
expect(headerCheckbox.getAttribute('aria-checked')).toMatch('false');
expect(headerCheckbox.getAttribute('aria-label')).toMatch('Select all');
GridSelectionFunctions.clickHeaderRowCheckbox(fix);
fix.detectChanges();
expect(firstRow.getAttribute('aria-selected')).toMatch('true');
expect(headerCheckbox.getAttribute('aria-checked')).toMatch('true');
expect(headerCheckbox.getAttribute('aria-label')).toMatch('Deselect all');
GridSelectionFunctions.clickHeaderRowCheckbox(fix);
fix.detectChanges();
expect(firstRow.getAttribute('aria-selected')).toMatch('false');
expect(headerCheckbox.getAttribute('aria-checked')).toMatch('false');
expect(headerCheckbox.getAttribute('aria-label')).toMatch('Select all');
});
it('ARIA support when there is filtered data', async () => {
grid.filter('ProductName', 'Ca', IgxStringFilteringOperand.instance().condition('contains'), true);
fix.detectChanges();
const firstRow = grid.gridAPI.get_row_by_index(0).nativeElement;
const headerCheckbox = GridSelectionFunctions.getRowCheckboxInput(GridSelectionFunctions.getHeaderRow(fix));
expect(firstRow.getAttribute('aria-selected')).toMatch('false');
expect(headerCheckbox.getAttribute('aria-checked')).toMatch('false');
expect(headerCheckbox.getAttribute('aria-label')).toMatch('Select all filtered');
grid.onHeaderSelectorClick(UIInteractions.getMouseEvent('click'));
fix.detectChanges();
expect(firstRow.getAttribute('aria-selected')).toMatch('true');
expect(headerCheckbox.getAttribute('aria-checked')).toMatch('true');
expect(headerCheckbox.getAttribute('aria-label')).toMatch('Deselect all filtered');
grid.onHeaderSelectorClick(UIInteractions.getMouseEvent('click'));
await wait();
fix.detectChanges();
expect(firstRow.getAttribute('aria-selected')).toMatch('false');
expect(headerCheckbox.getAttribute('aria-checked')).toMatch('false');
expect(headerCheckbox.getAttribute('aria-label')).toMatch('Select all filtered');
grid.clearFilter();
fix.detectChanges();
expect(firstRow.getAttribute('aria-selected')).toMatch('false');
expect(headerCheckbox.getAttribute('aria-checked')).toMatch('false');
expect(headerCheckbox.getAttribute('aria-label')).toMatch('Select all');
});
});
describe('RowSelection none', () => {
let fix: ComponentFixture<SelectionWithScrollsComponent>;
let grid: IgxGridComponent;
beforeEach(() => {
fix = TestBed.createComponent(SelectionWithScrollsComponent);
fix.detectChanges();
grid = fix.componentInstance.grid;
});
it('Change RowSelection to multiple ', fakeAsync(() => {
GridSelectionFunctions.verifyHeaderRowHasCheckbox(fix, false, false);
GridSelectionFunctions.verifyRowHasCheckbox(grid.gridAPI.get_row_by_index(0).nativeElement, false, false);
grid.selectRows([475]);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(grid.gridAPI.get_row_by_index(0), true, false);
grid.rowSelection = GridSelectionMode.multiple;
fix.detectChanges();
tick(100);
fix.detectChanges();
GridSelectionFunctions.verifySelectionCheckBoxesAlignment(grid);
GridSelectionFunctions.verifyRowSelected(grid.gridAPI.get_row_by_index(0), false, false);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix);
GridSelectionFunctions.verifyHeaderRowHasCheckbox(fix);
GridSelectionFunctions.verifyRowHasCheckbox(grid.gridAPI.get_row_by_index(0).nativeElement);
}));
});
describe('RowSelection single', () => {
let fix: ComponentFixture<SingleRowSelectionComponent>;
let grid: IgxGridComponent;
const gridData = SampleTestData.foodProductDataExtended();
beforeEach(() => {
fix = TestBed.createComponent(SingleRowSelectionComponent);
fix.detectChanges();
grid = fix.componentInstance.grid;
});
it('Header checkbox should NOT select/deselect all rows when selectionMode is single', () => {
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
GridSelectionFunctions.clickHeaderRowCheckbox(fix);
fix.detectChanges();
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, false);
GridSelectionFunctions.verifyRowsArraySelected([]);
expect(grid.selectedRows).toEqual([]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(0);
GridSelectionFunctions.clickHeaderRowCheckbox(fix);
fix.detectChanges();
expect(grid.selectedRows).toEqual([]);
GridSelectionFunctions.verifyHeaderRowCheckboxState(fix, false, false);
GridSelectionFunctions.verifyRowsArraySelected([]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(0);
});
it('Should have checkbox on each row and do not have header checkbox', () => {
GridSelectionFunctions.verifyHeaderRowHasCheckbox(fix, false);
GridSelectionFunctions.verifySelectionCheckBoxesAlignment(grid);
for (const row of grid.rowList.toArray()) {
GridSelectionFunctions.verifyRowHasCheckbox(row.nativeElement);
}
});
it('Should be able to select only one row when click on a checkbox', () => {
const firstRow = grid.gridAPI.get_row_by_index(0);
const secondRow = grid.gridAPI.get_row_by_index(1);
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
GridSelectionFunctions.clickRowCheckbox(firstRow);
fix.detectChanges();
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(1);
let args: IRowSelectionEventArgs = {
added: [gridData[0]],
cancel: false,
event: jasmine.anything() as any,
newSelection: [gridData[0]],
oldSelection: [],
removed: [],
allRowsSelected: false,
owner: grid
};
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
expect(grid.selectedRows).toEqual([1]);
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(secondRow, false);
// Click other row checkbox
GridSelectionFunctions.clickRowCheckbox(secondRow);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, false);
GridSelectionFunctions.verifyRowSelected(secondRow);
expect(grid.selectedRows).toEqual([2]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(2);
args = {
added: [gridData[1]],
cancel: false,
event: jasmine.anything() as any,
newSelection: [gridData[1]],
oldSelection: [gridData[0]],
removed: [gridData[0]],
allRowsSelected: false,
owner: grid
};
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
});
it('Should NOT select a row on click when selectRowOnClick has false value', () => {
grid.selectRowOnClick = false;
grid.tbody.nativeElement.focus();
fix.detectChanges();
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
const firstRow = grid.gridAPI.get_row_by_index(0);
const cell = grid.gridAPI.get_cell_by_index(0, 0);
UIInteractions.simulateClickEvent(cell.nativeElement);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, false);
expect(grid.selectedRows).toEqual([]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(0);
});
it('Should not select multiple rows with clicking and holding Ctrl', () => {
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
const firstRow = grid.gridAPI.get_row_by_index(2);
const secondRow = grid.gridAPI.get_row_by_index(0);
UIInteractions.simulateClickEvent(firstRow.nativeElement);
fix.detectChanges();
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(1);
expect(grid.selectedRows).toEqual([3]);
GridSelectionFunctions.verifyRowSelected(firstRow);
// Click on a different row holding Ctrl
UIInteractions.simulateClickEvent(secondRow.nativeElement, false, true);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, false);
GridSelectionFunctions.verifyRowSelected(secondRow);
expect(grid.selectedRows).toEqual([1]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(2);
});
it('Should deselect a selected row with clicking and holding Ctrl', () => {
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
const firstRow = grid.gridAPI.get_row_by_index(2);
UIInteractions.simulateClickEvent(firstRow.nativeElement);
fix.detectChanges();
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(1);
expect(grid.selectedRows).toEqual([3]);
GridSelectionFunctions.verifyRowSelected(firstRow);
// Click on the same row holding Ctrl
UIInteractions.simulateClickEvent(firstRow.nativeElement, false, true);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, false);
expect(grid.selectedRows.length).toEqual(0);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(2);
});
it('Should not select a row with clicking and holding Ctrl when selectRowOnClick has false value', () => {
grid.selectRowOnClick = false;
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
const firstRow = grid.gridAPI.get_row_by_index(2);
const secondRow = grid.gridAPI.get_row_by_index(0);
UIInteractions.simulateClickEvent(firstRow.nativeElement);
fix.detectChanges();
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(0);
expect(grid.selectedRows).toEqual([]);
GridSelectionFunctions.verifyRowSelected(firstRow, false);
// Click on a different row holding Ctrl
UIInteractions.simulateClickEvent(secondRow.nativeElement, false, true);
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, false);
GridSelectionFunctions.verifyRowSelected(secondRow, false);
expect(grid.selectedRows).toEqual([]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(0);
});
it('Should not select multiple rows with clicking Space on a cell', (async () => {
grid.tbody.nativeElement.focus();
fix.detectChanges();
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
const firstRow = grid.gridAPI.get_row_by_index(0);
const secondRow = grid.gridAPI.get_row_by_index(1);
let cell = grid.gridAPI.get_cell_by_index(0, 'ProductName');
UIInteractions.simulateClickAndSelectEvent(cell);
fix.detectChanges();
await wait(DEBOUNCETIME);
GridSelectionFunctions.verifyCellSelected(cell);
GridSelectionFunctions.verifyRowSelected(firstRow);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(1);
expect(grid.selectedRows).toEqual([1]);
GridSelectionFunctions.verifyRowSelected(firstRow);
GridSelectionFunctions.verifyRowSelected(secondRow, false);
UIInteractions.triggerKeyDownEvtUponElem('arrowdown', grid.tbody.nativeElement, true);
fix.detectChanges();
await wait(DEBOUNCETIME);
// Click Space on the cell
cell = grid.gridAPI.get_cell_by_index(1, 'ProductName');
UIInteractions.triggerKeyDownEvtUponElem('space', grid.tbody.nativeElement, true);
fix.detectChanges();
await wait(DEBOUNCETIME);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(2);
expect(grid.selectedRows).toEqual([2]);
GridSelectionFunctions.verifyRowSelected(firstRow, false);
GridSelectionFunctions.verifyRowSelected(secondRow);
// Click again Space on the cell
UIInteractions.triggerKeyDownEvtUponElem('space', grid.tbody.nativeElement, true);
fix.detectChanges();
await wait(DEBOUNCETIME);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(3);
expect(grid.selectedRows).toEqual([]);
GridSelectionFunctions.verifyRowSelected(firstRow, false);
GridSelectionFunctions.verifyRowSelected(secondRow, false);
}));
it('Should not select multiple rows with Shift + Click', () => {
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
const firstRow = grid.gridAPI.get_row_by_index(1);
const secondRow = grid.gridAPI.get_row_by_index(4);
const mockEvent = new MouseEvent('click', { shiftKey: true });
UIInteractions.simulateClickEvent(firstRow.nativeElement);
fix.detectChanges();
expect(grid.selectedRows).toEqual([2]);
GridSelectionFunctions.verifyRowSelected(firstRow);
// Click on other row holding Shift key
secondRow.nativeElement.dispatchEvent(mockEvent);
fix.detectChanges();
expect(grid.selectedRows).toEqual([5]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(2);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith({
added: [gridData[4]],
cancel: false,
event: mockEvent,
newSelection: [gridData[4]],
oldSelection: [gridData[1]],
removed: [gridData[1]],
allRowsSelected: false,
owner: grid
});
GridSelectionFunctions.verifyRowSelected(secondRow);
for (let index = 1; index < 4; index++) {
const row = grid.gridAPI.get_row_by_index(index);
GridSelectionFunctions.verifyRowSelected(row, false);
}
});
it('Should not select row with Shift + Click when selectRowOnClick has false value ', () => {
grid.selectRowOnClick = false;
spyOn(grid.rowSelectionChanging, 'emit').and.callThrough();
// Shift + Click
const firstRow = grid.gridAPI.get_row_by_index(1);
const secondRow = grid.gridAPI.get_row_by_index(4);
UIInteractions.simulateClickEvent(firstRow.nativeElement, false, false);
fix.detectChanges();
expect(grid.selectedRows).toEqual([]);
GridSelectionFunctions.verifyRowSelected(firstRow, false);
// Click on other row holding Shift key
UIInteractions.simulateClickEvent(secondRow.nativeElement, true, false);
fix.detectChanges();
expect(grid.selectedRows).toEqual([]);
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledTimes(0);
GridSelectionFunctions.verifyRowSelected(secondRow, false);
for (let index = 1; index < 4; index++) {
const row = grid.gridAPI.get_row_by_index(index);
GridSelectionFunctions.verifyRowSelected(row, false);
}
});
it('Should hide/show checkboxes when change hideRowSelectors', () => {
const firstRow = grid.gridAPI.get_row_by_index(1);
expect(grid.hideRowSelectors).toBe(false);
firstRow.onRowSelectorClick(UIInteractions.getMouseEvent('click'));
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow);
grid.hideRowSelectors = true;
fix.detectChanges();
GridSelectionFunctions.verifyRowSelected(firstRow, true, fals