@@ -6,18 +6,25 @@ import { IgxPivotGridMultipleRowComponent, IgxPivotGridTestBaseComponent } from
66import { UIInteractions , wait } from '../../test-utils/ui-interactions.spec' ;
77import { IgxPivotGridComponent } from './pivot-grid.component' ;
88import { IgxPivotRowDimensionHeaderComponent } from './pivot-row-dimension-header.component' ;
9+ import { DebugElement } from '@angular/core' ;
10+ import { IgxPivotHeaderRowComponent } from './pivot-header-row.component' ;
11+ import { PivotRowLayoutType } from 'igniteui-angular' ;
912
1013const DEBOUNCE_TIME = 250 ;
1114const PIVOT_TBODY_CSS_CLASS = '.igx-grid__tbody' ;
1215const PIVOT_ROW_DIMENSION_CONTENT = 'igx-pivot-row-dimension-content' ;
1316const PIVOT_HEADER_ROW = 'igx-pivot-header-row' ;
1417const HEADER_CELL_CSS_CLASS = '.igx-grid-th' ;
1518const ACTIVE_CELL_CSS_CLASS = '.igx-grid-th--active' ;
19+ const CSS_CLASS_ROW_DIMENSION_CONTAINER = '.igx-grid__tbody-pivot-dimension'
20+ const CSS_CLASS_TBODY_CONTENT = '.igx-grid__tbody-content' ;
1621
1722describe ( 'IgxPivotGrid - Keyboard navigation #pivotGrid' , ( ) => {
1823 describe ( 'General Keyboard Navigation' , ( ) => {
1924 let fixture : ComponentFixture < IgxPivotGridMultipleRowComponent > ;
2025 let pivotGrid : IgxPivotGridComponent ;
26+ let rowDimension : DebugElement ;
27+ let headerRow : DebugElement ;
2128
2229 beforeEach ( waitForAsync ( ( ) => {
2330 TestBed . configureTestingModule ( {
@@ -28,10 +35,14 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
2835 } ) . compileComponents ( ) ;
2936 } ) ) ;
3037
31- beforeEach ( fakeAsync ( ( ) => {
38+ beforeEach ( fakeAsync ( async ( ) => {
3239 fixture = TestBed . createComponent ( IgxPivotGridMultipleRowComponent ) ;
3340 fixture . detectChanges ( ) ;
3441 pivotGrid = fixture . componentInstance . pivotGrid ;
42+ await fixture . whenStable ( ) ;
43+ rowDimension = fixture . debugElement . query (
44+ By . css ( CSS_CLASS_ROW_DIMENSION_CONTAINER ) ) ;
45+ headerRow = fixture . debugElement . query ( By . directive ( IgxPivotHeaderRowComponent ) ) ;
3546 } ) ) ;
3647
3748 it ( 'should allow navigating between row headers' , ( ) => {
@@ -43,24 +54,32 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
4354 fixture . detectChanges ( ) ;
4455
4556 GridFunctions . verifyHeaderIsFocused ( firstCell . parent ) ;
46- let activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
57+ // for the row dimensions headers, the active descendant is set on the div having
58+ // tabindex="0" and class '.igx-grid__tbody-pivot-dimension';
59+ GridFunctions . verifyPivotElementActiveDescendant ( rowDimension , firstCell . nativeElement . id ) ;
60+ expect ( firstCell . nativeElement . getAttribute ( 'role' ) ) . toBe ( 'rowheader' ) ;
61+ let activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
4762 expect ( activeCells . length ) . toBe ( 1 ) ;
4863
4964 UIInteractions . triggerKeyDownEvtUponElem ( 'ArrowRight' , firstCell . nativeElement ) ;
5065 fixture . detectChanges ( ) ;
5166 GridFunctions . verifyHeaderIsFocused ( secondCell . parent ) ;
67+ GridFunctions . verifyPivotElementActiveDescendant ( rowDimension , secondCell . nativeElement . id ) ;
68+ expect ( firstCell . nativeElement . getAttribute ( 'role' ) ) . toBe ( 'rowheader' ) ;
5269 activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
5370 expect ( activeCells . length ) . toBe ( 1 ) ;
5471
5572 // should do nothing if wrong key is pressed
5673 UIInteractions . simulateClickAndSelectEvent ( firstCell ) ;
5774 fixture . detectChanges ( ) ;
5875 GridFunctions . verifyHeaderIsFocused ( firstCell . parent ) ;
76+ GridFunctions . verifyPivotElementActiveDescendant ( rowDimension , firstCell . nativeElement . id ) ;
5977 activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
6078 expect ( activeCells . length ) . toBe ( 1 ) ;
6179 UIInteractions . triggerKeyDownEvtUponElem ( 'h' , firstCell . nativeElement ) ;
6280 fixture . detectChanges ( ) ;
6381 GridFunctions . verifyHeaderIsFocused ( firstCell . parent ) ;
82+ GridFunctions . verifyPivotElementActiveDescendant ( rowDimension , firstCell . nativeElement . id ) ;
6483 } ) ;
6584
6685 it ( 'should not go outside of the boundaries of the row dimensions content' , ( ) => {
@@ -75,6 +94,7 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
7594 fixture . detectChanges ( ) ;
7695
7796 GridFunctions . verifyHeaderIsFocused ( firstCell . parent ) ;
97+ GridFunctions . verifyPivotElementActiveDescendant ( rowDimension , firstCell . nativeElement . id ) ;
7898 let activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
7999 expect ( activeCells . length ) . toBe ( 1 ) ;
80100
@@ -85,6 +105,7 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
85105 fixture . detectChanges ( ) ;
86106
87107 GridFunctions . verifyHeaderIsFocused ( thirdCell . parent ) ;
108+ GridFunctions . verifyPivotElementActiveDescendant ( rowDimension , thirdCell . nativeElement . id ) ;
88109 activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
89110 expect ( activeCells . length ) . toBe ( 1 ) ;
90111 } ) ;
@@ -100,12 +121,14 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
100121 UIInteractions . triggerKeyDownEvtUponElem ( 'End' , firstCell . nativeElement ) ;
101122 fixture . detectChanges ( ) ;
102123 GridFunctions . verifyHeaderIsFocused ( thirdCell . parent ) ;
124+ GridFunctions . verifyPivotElementActiveDescendant ( rowDimension , thirdCell . nativeElement . id ) ;
103125 let activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
104126 expect ( activeCells . length ) . toBe ( 1 ) ;
105127
106128 UIInteractions . triggerKeyDownEvtUponElem ( 'Home' , thirdCell . nativeElement ) ;
107129 fixture . detectChanges ( ) ;
108130 GridFunctions . verifyHeaderIsFocused ( firstCell . parent ) ;
131+ GridFunctions . verifyPivotElementActiveDescendant ( rowDimension , firstCell . nativeElement . id ) ;
109132 activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
110133 expect ( activeCells . length ) . toBe ( 1 ) ;
111134 } ) ;
@@ -124,6 +147,7 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
124147 By . directive ( IgxPivotRowDimensionHeaderComponent ) ) ;
125148 const lastCell = allGroups [ allGroups . length - 1 ] ;
126149 GridFunctions . verifyHeaderIsFocused ( lastCell . parent ) ;
150+ GridFunctions . verifyPivotElementActiveDescendant ( rowDimension , lastCell . nativeElement . id ) ;
127151 const activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
128152 expect ( activeCells . length ) . toBe ( 1 ) ;
129153 } ) ;
@@ -143,6 +167,7 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
143167 By . directive ( IgxPivotRowDimensionHeaderComponent ) ) ;
144168 const firstCell = allGroups [ 0 ] ;
145169 GridFunctions . verifyHeaderIsFocused ( firstCell . parent ) ;
170+ GridFunctions . verifyPivotElementActiveDescendant ( rowDimension , firstCell . nativeElement . id ) ;
146171 let activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
147172 expect ( activeCells . length ) . toBe ( 1 ) ;
148173
@@ -156,6 +181,7 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
156181 By . directive ( IgxPivotRowDimensionHeaderComponent ) ) ;
157182 const secondCell = allGroups . filter ( x => x . componentInstance . column . field === 'ProductCategory' ) [ 1 ] ;
158183 GridFunctions . verifyHeaderIsFocused ( secondCell . parent ) ;
184+ GridFunctions . verifyPivotElementActiveDescendant ( rowDimension , secondCell . nativeElement . id ) ;
159185 activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
160186 expect ( activeCells . length ) . toBe ( 1 ) ;
161187
@@ -170,7 +196,9 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
170196 firstHeader = fixture . debugElement . queryAll (
171197 By . css ( `${ PIVOT_HEADER_ROW } ${ HEADER_CELL_CSS_CLASS } ` ) ) [ 0 ] ;
172198 GridFunctions . verifyHeaderIsFocused ( firstHeader . parent ) ;
173- let activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
199+ // for the column headers, the active descendant is set on the header row element
200+ GridFunctions . verifyPivotElementActiveDescendant ( headerRow , firstHeader . nativeElement . id ) ;
201+ let activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
174202 expect ( activeCells . length ) . toBe ( 1 ) ;
175203
176204 UIInteractions . triggerKeyDownEvtUponElem ( 'ArrowRight' , pivotGrid . theadRow . nativeElement ) ;
@@ -179,6 +207,7 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
179207 const secondHeader = fixture . debugElement . queryAll (
180208 By . css ( `${ PIVOT_HEADER_ROW } ${ HEADER_CELL_CSS_CLASS } ` ) ) [ 1 ] ;
181209 GridFunctions . verifyHeaderIsFocused ( secondHeader . parent ) ;
210+ GridFunctions . verifyPivotElementActiveDescendant ( headerRow , secondHeader . nativeElement . id ) ;
182211 activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
183212 expect ( activeCells . length ) . toBe ( 1 ) ;
184213 } ) ;
@@ -193,6 +222,7 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
193222 By . css ( `${ PIVOT_HEADER_ROW } ${ HEADER_CELL_CSS_CLASS } ` ) ) [ 0 ] ;
194223
195224 GridFunctions . verifyHeaderIsFocused ( firstHeader . parent ) ;
225+ GridFunctions . verifyPivotElementActiveDescendant ( headerRow , firstHeader . nativeElement . id ) ;
196226 let activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
197227 expect ( activeCells . length ) . toBe ( 1 ) ;
198228
@@ -204,6 +234,7 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
204234 By . css ( `${ PIVOT_HEADER_ROW } ${ HEADER_CELL_CSS_CLASS } ` ) ) ;
205235 const lastHeader = allHeaders [ allHeaders . length - 1 ] ;
206236 GridFunctions . verifyHeaderIsFocused ( lastHeader . parent ) ;
237+ GridFunctions . verifyPivotElementActiveDescendant ( headerRow , lastHeader . nativeElement . id ) ;
207238 activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
208239 expect ( activeCells . length ) . toBe ( 1 ) ;
209240 } ) ;
@@ -222,20 +253,58 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
222253 firstHeader = fixture . debugElement . queryAll (
223254 By . css ( `${ PIVOT_HEADER_ROW } ${ HEADER_CELL_CSS_CLASS } ` ) ) [ 0 ] ;
224255 GridFunctions . verifyHeaderIsFocused ( firstHeader . parent ) ;
225- let activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
256+ GridFunctions . verifyPivotElementActiveDescendant ( headerRow , firstHeader . nativeElement . id ) ;
257+ let activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
226258 expect ( activeCells . length ) . toBe ( 1 ) ;
227259
228260 UIInteractions . triggerKeyDownEvtUponElem ( 'ArrowRight' , firstHeader . nativeElement ) ;
229261 fixture . detectChanges ( ) ;
230262 const secondHeader = fixture . debugElement . queryAll (
231263 By . css ( `${ PIVOT_HEADER_ROW } ${ HEADER_CELL_CSS_CLASS } ` ) ) [ 1 ] ;
232264 GridFunctions . verifyHeaderIsFocused ( secondHeader . parent ) ;
265+ GridFunctions . verifyPivotElementActiveDescendant ( headerRow , secondHeader . nativeElement . id ) ;
266+ activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
267+ expect ( activeCells . length ) . toBe ( 1 ) ;
268+ } ) ;
269+
270+ it ( 'should navigate properly among row dimension column headers for horizontal row layout' , ( ) => {
271+ pivotGrid . pivotUI = {
272+ ...pivotGrid . pivotUI ,
273+ rowLayout : PivotRowLayoutType . Horizontal ,
274+ showRowHeaders : true
275+ } ;
276+ fixture . detectChanges ( ) ;
277+
278+ let firstHeader = fixture . debugElement . queryAll (
279+ By . css ( `${ PIVOT_HEADER_ROW } ${ HEADER_CELL_CSS_CLASS } ` ) ) [ 0 ] ;
280+ UIInteractions . simulateClickAndSelectEvent ( firstHeader ) ;
281+ fixture . detectChanges ( ) ;
282+
283+ firstHeader = fixture . debugElement . queryAll (
284+ By . css ( `${ PIVOT_HEADER_ROW } ${ HEADER_CELL_CSS_CLASS } ` ) ) [ 0 ] ;
285+ GridFunctions . verifyHeaderIsFocused ( firstHeader . parent ) ;
286+ // for the row dimensions column headers in horizontal layout,
287+ // the active descendant is set on the header row element.
288+ GridFunctions . verifyPivotElementActiveDescendant ( headerRow , firstHeader . nativeElement . id ) ;
289+ expect ( firstHeader . nativeElement . getAttribute ( 'role' ) ) . toBe ( 'columnheader' ) ;
290+ let activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
291+ expect ( activeCells . length ) . toBe ( 1 ) ;
292+
293+ UIInteractions . triggerKeyDownEvtUponElem ( 'ArrowRight' , pivotGrid . theadRow . nativeElement ) ;
294+ fixture . detectChanges ( ) ;
295+
296+ const secondHeader = fixture . debugElement . queryAll (
297+ By . css ( `${ PIVOT_HEADER_ROW } ${ HEADER_CELL_CSS_CLASS } ` ) ) [ 1 ] ;
298+ GridFunctions . verifyHeaderIsFocused ( secondHeader . parent ) ;
299+ GridFunctions . verifyPivotElementActiveDescendant ( headerRow , secondHeader . nativeElement . id ) ;
300+ expect ( firstHeader . nativeElement . getAttribute ( 'role' ) ) . toBe ( 'columnheader' ) ;
233301 activeCells = fixture . debugElement . queryAll ( By . css ( `${ ACTIVE_CELL_CSS_CLASS } ` ) ) ;
234302 expect ( activeCells . length ) . toBe ( 1 ) ;
235303 } ) ;
236304
237305 it ( 'should allow navigating within the cells of the body' , async ( ) => {
238306 const cell = pivotGrid . rowList . first . cells . first ;
307+ const tBodyContent = fixture . debugElement . query ( By . css ( CSS_CLASS_TBODY_CONTENT ) ) ;
239308 GridFunctions . focusFirstCell ( fixture , pivotGrid ) ;
240309 fixture . detectChanges ( ) ;
241310 expect ( pivotGrid . navigation . activeNode . row ) . toBeUndefined ( ) ;
@@ -248,8 +317,11 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
248317 fixture . detectChanges ( ) ;
249318 expect ( pivotGrid . navigation . activeNode . row ) . toBeDefined ( ) ;
250319 expect ( pivotGrid . navigation . activeNode . column ) . toBeDefined ( ) ;
320+ // The activedescendant attribute for cells in the grid body
321+ // is set on the tbody content div with tabindex='0'
322+ GridFunctions . verifyPivotElementActiveDescendant ( tBodyContent , cell . nativeElement . id ) ;
251323
252- let activeCells = fixture . debugElement . queryAll ( By . css ( `.igx-grid__td--active` ) ) ;
324+ let activeCells = fixture . debugElement . queryAll ( By . css ( `.igx-grid__td--active` ) ) ;
253325 expect ( activeCells . length ) . toBe ( 1 ) ;
254326 expect ( cell . column . field ) . toEqual ( 'Stanley-UnitsSold' ) ;
255327
@@ -261,6 +333,7 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
261333 activeCells = fixture . debugElement . queryAll ( By . css ( `.igx-grid__td--active` ) ) ;
262334 expect ( activeCells . length ) . toBe ( 1 ) ;
263335 expect ( activeCells [ 0 ] . componentInstance . column . field ) . toEqual ( 'Stanley-UnitPrice' )
336+ GridFunctions . verifyPivotElementActiveDescendant ( tBodyContent , activeCells [ 0 ] . nativeElement . id ) ;
264337 } ) ;
265338 } ) ;
266339 describe ( 'Row Dimension Expand/Collapse Keyboard Interactions' , ( ) => {
@@ -282,7 +355,7 @@ describe('IgxPivotGrid - Keyboard navigation #pivotGrid', () => {
282355
283356 it ( 'should allow row dimension expand(Alt + ArrowDown/ArrowRight) and collapse(Alt + ArrowUp/ArrowLeft)' , async ( ) => {
284357 const rowDimension = fixture . debugElement . queryAll (
285- By . css ( `.igx-grid__tbody-pivot-dimension` ) ) ;
358+ By . css ( CSS_CLASS_ROW_DIMENSION_CONTAINER ) ) ;
286359 let allHeaders = fixture . debugElement . queryAll (
287360 By . directive ( IgxPivotRowDimensionHeaderComponent ) ) ;
288361
0 commit comments