Skip to content

Commit ee50445

Browse files
authored
refactor(material/tree): add unit tests for opt-out (#28237)
Add unit tests to cover the use of LegacyTreeKeyManager, which opts out of updated focus management behavior.
1 parent ab5cb56 commit ee50445

File tree

4 files changed

+127
-6
lines changed

4 files changed

+127
-6
lines changed

src/cdk/tree/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ ng_test_library(
3333
),
3434
deps = [
3535
":tree",
36+
"//src/cdk/a11y",
3637
"//src/cdk/bidi",
3738
"//src/cdk/collections",
3839
"//src/cdk/keycodes",
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import {Component, ElementRef, QueryList, ViewChild, ViewChildren} from '@angular/core';
2+
import {ComponentFixture, TestBed} from '@angular/core/testing';
3+
import {of} from 'rxjs';
4+
import {CdkTreeModule} from './tree-module';
5+
import {NOOP_TREE_KEY_MANAGER_FACTORY_PROVIDER} from '@angular/cdk/a11y';
6+
7+
describe('CdkTree when provided LegacyTreeKeyManager', () => {
8+
let fixture: ComponentFixture<SimpleCdkTreeApp>;
9+
10+
beforeEach(() => {
11+
TestBed.configureTestingModule({
12+
imports: [CdkTreeModule],
13+
declarations: [SimpleCdkTreeApp],
14+
providers: [NOOP_TREE_KEY_MANAGER_FACTORY_PROVIDER],
15+
}).compileComponents();
16+
17+
fixture = TestBed.createComponent(SimpleCdkTreeApp);
18+
fixture.detectChanges();
19+
});
20+
21+
describe('with default node options', () => {
22+
it('renders nodes with tabindex attribute of -1', () => {
23+
const treeItems = fixture.componentInstance.treeNodes;
24+
25+
expect(treeItems.map(x => `${x.nativeElement.getAttribute('tabindex')}`).join(', '))
26+
.withContext('tabindex of tree nodes')
27+
.toEqual('-1, -1');
28+
});
29+
});
30+
31+
describe('when focusing the second node', () => {
32+
beforeEach(() => {
33+
const treeItems = fixture.componentInstance.treeNodes;
34+
35+
treeItems.get(1)!.nativeElement.focus();
36+
fixture.detectChanges();
37+
});
38+
39+
it('does not change tabindex of nodes', () => {
40+
const treeItems = fixture.componentInstance.treeNodes;
41+
42+
expect(treeItems.map(x => `${x.nativeElement.getAttribute('tabindex')}`).join(', '))
43+
.withContext('tabindex of tree nodes')
44+
.toEqual('-1, -1');
45+
});
46+
});
47+
48+
describe('when clicking the second node', () => {
49+
beforeEach(() => {
50+
const treeItems = fixture.componentInstance.treeNodes;
51+
52+
treeItems.get(1)!.nativeElement.click();
53+
fixture.detectChanges();
54+
});
55+
56+
it('does not change active element', () => {
57+
expect(document.activeElement).toEqual(document.body);
58+
});
59+
60+
it('does not change tabindex of nodes', () => {
61+
const treeItems = fixture.componentInstance.treeNodes;
62+
63+
expect(treeItems.map(x => `${x.nativeElement.getAttribute('tabindex')}`).join(', '))
64+
.withContext('tabindex of tree nodes')
65+
.toEqual('-1, -1');
66+
});
67+
});
68+
});
69+
70+
class MinimalTestData {
71+
constructor(public name: string) {}
72+
children: MinimalTestData[] = [];
73+
}
74+
75+
@Component({
76+
template: `
77+
<cdk-tree #tree [dataSource]="dataSource" [childrenAccessor]="getChildren">
78+
<cdk-tree-node #node *cdkTreeNodeDef="let node">
79+
{{node.name}}
80+
</cdk-tree-node>
81+
</cdk-tree>
82+
`,
83+
})
84+
class SimpleCdkTreeApp {
85+
isExpandable = (node: MinimalTestData) => node.children.length > 0;
86+
getChildren = (node: MinimalTestData) => node.children;
87+
88+
dataSource = of([new MinimalTestData('apple'), new MinimalTestData('banana')]);
89+
90+
@ViewChild('tree', {read: ElementRef}) tree: ElementRef<HTMLElement>;
91+
@ViewChildren('node') treeNodes: QueryList<ElementRef<HTMLElement>>;
92+
}

src/material/tree/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ ng_test_library(
5151
deps = [
5252
":tree",
5353
"//src/cdk/a11y",
54+
"//src/cdk/keycodes",
55+
"//src/cdk/testing/private",
5456
"//src/cdk/tree",
5557
"@npm//rxjs",
5658
],

src/material/tree/tree-using-legacy-key-manager.spec.ts

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import {Component, ElementRef, QueryList, ViewChild, ViewChildren} from '@angular/core';
22
import {of} from 'rxjs';
3-
import {MatTree} from './tree';
43
import {ComponentFixture, TestBed} from '@angular/core/testing';
54
import {MatTreeModule} from './tree-module';
65
import {NOOP_TREE_KEY_MANAGER_FACTORY_PROVIDER} from '@angular/cdk/a11y';
6+
import {DOWN_ARROW} from '@angular/cdk/keycodes';
7+
import {createKeyboardEvent} from '@angular/cdk/testing/private';
78

89
describe('MatTree when provided LegacyTreeKeyManager', () => {
910
let fixture: ComponentFixture<SimpleMatTreeApp>;
@@ -19,7 +20,7 @@ describe('MatTree when provided LegacyTreeKeyManager', () => {
1920
fixture.detectChanges();
2021
});
2122

22-
describe('when nodes do not have a tabindex set', () => {
23+
describe('when nodes have default options', () => {
2324
it('Should render tabindex attribute of 0', () => {
2425
const treeItems = fixture.componentInstance.treeNodes;
2526

@@ -30,10 +31,12 @@ describe('MatTree when provided LegacyTreeKeyManager', () => {
3031
});
3132

3233
describe('when nodes have TabIndex Input binding of 42', () => {
33-
it('Should render tabindex attribute of 42.', () => {
34+
beforeEach(() => {
3435
fixture.componentInstance.tabIndexInputBinding = 42;
3536
fixture.detectChanges();
37+
});
3638

39+
it('Should render tabindex attribute of 42.', () => {
3740
const treeItems = fixture.componentInstance.treeNodes;
3841

3942
expect(treeItems.map(x => `${x.nativeElement.getAttribute('tabindex')}`).join(', '))
@@ -43,17 +46,40 @@ describe('MatTree when provided LegacyTreeKeyManager', () => {
4346
});
4447

4548
describe('when nodes have tabindex attribute binding of 2', () => {
46-
it('should render tabindex attribute of 2', () => {
49+
beforeEach(() => {
4750
fixture.componentInstance.tabindexAttributeBinding = '2';
4851
fixture.detectChanges();
52+
});
4953

54+
it('should render tabindex attribute of 2', () => {
5055
const treeItems = fixture.componentInstance.treeNodes;
5156

5257
expect(treeItems.map(x => `${x.nativeElement.getAttribute('tabindex')}`).join(', '))
5358
.withContext('tabindex of tree nodes')
5459
.toEqual('2, 2, 2');
5560
});
5661
});
62+
63+
describe('when pressing down arrow key', () => {
64+
beforeEach(() => {
65+
const treeElement = fixture.componentInstance.tree.nativeElement;
66+
67+
treeElement.dispatchEvent(createKeyboardEvent('keydown', DOWN_ARROW, 'down'));
68+
fixture.detectChanges();
69+
});
70+
71+
it('should not change the active element', () => {
72+
expect(document.activeElement).toEqual(document.body);
73+
});
74+
75+
it('should not change the tabindex of tree nodes', () => {
76+
const treeItems = fixture.componentInstance.treeNodes;
77+
78+
expect(treeItems.map(x => `${x.nativeElement.getAttribute('tabindex')}`).join(', '))
79+
.withContext('tabindex of tree nodes')
80+
.toEqual('0, 0, 0');
81+
});
82+
});
5783
});
5884

5985
class MinimalTestData {
@@ -63,7 +89,7 @@ class MinimalTestData {
6389

6490
@Component({
6591
template: `
66-
<mat-tree [dataSource]="dataSource" [childrenAccessor]="getChildren">
92+
<mat-tree #tree [dataSource]="dataSource" [childrenAccessor]="getChildren">
6793
<mat-tree-node #node *matTreeNodeDef="let node"
6894
[tabIndex]="tabIndexInputBinding" tabindex="{{tabindexAttributeBinding}}">
6995
{{node.name}}
@@ -86,6 +112,6 @@ class SimpleMatTreeApp {
86112
/** Value passed to tabindex attribute binding of each tree node. Null by default. */
87113
tabindexAttributeBinding: string | null = null;
88114

89-
@ViewChild(MatTree) tree: MatTree<MinimalTestData>;
115+
@ViewChild('tree', {read: ElementRef}) tree: ElementRef<HTMLElement>;
90116
@ViewChildren('node') treeNodes: QueryList<ElementRef<HTMLElement>>;
91117
}

0 commit comments

Comments
 (0)