UNPKG

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
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