Skip to content

Commit f69302b

Browse files
committed
feat(material-experimental): add test harness for tabs
Resolves COMP-193.
1 parent e6afdbb commit f69302b

File tree

4 files changed

+239
-0
lines changed

4 files changed

+239
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package(default_visibility = ["//visibility:public"])
2+
3+
load("//tools:defaults.bzl", "ng_test_library", "ng_web_test_suite", "ts_library")
4+
5+
ts_library(
6+
name = "harness",
7+
srcs = glob(
8+
["**/*.ts"],
9+
exclude = ["**/*.spec.ts"],
10+
),
11+
deps = [
12+
"//src/cdk-experimental/testing",
13+
"//src/cdk/coercion",
14+
],
15+
)
16+
17+
ng_test_library(
18+
name = "harness_tests",
19+
srcs = glob(["**/*.spec.ts"]),
20+
deps = [
21+
":harness",
22+
"//src/cdk-experimental/testing",
23+
"//src/cdk-experimental/testing/testbed",
24+
"//src/material/tabs",
25+
"@npm//@angular/platform-browser",
26+
],
27+
)
28+
29+
ng_web_test_suite(
30+
name = "tests",
31+
deps = [":harness_tests"],
32+
)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
export type TabGroupHarnessFilters = {};
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import {HarnessLoader} from '@angular/cdk-experimental/testing';
2+
import {TestbedHarnessEnvironment} from '@angular/cdk-experimental/testing/testbed';
3+
import {Component} from '@angular/core';
4+
import {ComponentFixture, TestBed} from '@angular/core/testing';
5+
import {MatTabsModule} from '@angular/material/tabs';
6+
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
7+
import {MatTabGroupHarness} from './tab-group-harness';
8+
9+
let fixture: ComponentFixture<TabGroupHarnessTest>;
10+
let loader: HarnessLoader;
11+
let tabGroupHarness: typeof MatTabGroupHarness;
12+
13+
describe('MatTabGroupHarness', () => {
14+
describe('non-MDC-based', () => {
15+
beforeEach(async () => {
16+
await TestBed
17+
.configureTestingModule({
18+
imports: [MatTabsModule, NoopAnimationsModule],
19+
declarations: [TabGroupHarnessTest],
20+
})
21+
.compileComponents();
22+
23+
fixture = TestBed.createComponent(TabGroupHarnessTest);
24+
fixture.detectChanges();
25+
loader = TestbedHarnessEnvironment.loader(fixture);
26+
tabGroupHarness = MatTabGroupHarness;
27+
});
28+
29+
runTests();
30+
});
31+
32+
describe(
33+
'MDC-based',
34+
() => {
35+
// TODO: run tests for MDC based tab-group once implemented.
36+
});
37+
});
38+
39+
/** Shared tests to run on both the original and MDC-based tab-group's. */
40+
function runTests() {
41+
it('should load harness for tab-group', async () => {
42+
const tabGroups = await loader.getAllHarnesses(tabGroupHarness);
43+
expect(tabGroups.length).toBe(1);
44+
});
45+
46+
it('should be able to get tabs of tab-group', async () => {
47+
const tabGroup = await loader.getHarness(tabGroupHarness);
48+
const tabs = await tabGroup.getTabs();
49+
expect(tabs.length).toBe(3);
50+
});
51+
52+
it('should be able to get label of tabs', async () => {
53+
const tabGroup = await loader.getHarness(tabGroupHarness);
54+
const tabs = await tabGroup.getTabs();
55+
expect(await tabs[0].getLabel()).toBe('First');
56+
expect(await tabs[1].getLabel()).toBe('Second');
57+
expect(await tabs[2].getLabel()).toBe('Third');
58+
});
59+
60+
it('should be able to get aria-label of tabs', async () => {
61+
const tabGroup = await loader.getHarness(tabGroupHarness);
62+
const tabs = await tabGroup.getTabs();
63+
expect(await tabs[0].getAriaLabel()).toBe('First tab');
64+
expect(await tabs[1].getAriaLabel()).toBe('Second tab');
65+
expect(await tabs[2].getAriaLabel()).toBe(null);
66+
});
67+
68+
it('should be able to get aria-labelledby of tabs', async () => {
69+
const tabGroup = await loader.getHarness(tabGroupHarness);
70+
const tabs = await tabGroup.getTabs();
71+
expect(await tabs[0].getAriaLabelledby()).toBe(null);
72+
expect(await tabs[1].getAriaLabelledby()).toBe(null);
73+
expect(await tabs[2].getAriaLabelledby()).toBe('tabLabelId');
74+
});
75+
76+
it('should be able to get content element of active tab', async () => {
77+
const tabGroup = await loader.getHarness(tabGroupHarness);
78+
const tabs = await tabGroup.getTabs();
79+
expect(await (await tabs[0].getContentElement()).text()).toBe('Content 1');
80+
});
81+
82+
it('should be able to get content element of active tab', async () => {
83+
const tabGroup = await loader.getHarness(tabGroupHarness);
84+
const tabs = await tabGroup.getTabs();
85+
expect(await (await tabs[0].getContentElement()).text()).toBe('Content 1');
86+
});
87+
88+
it('should be able to get disabled state of tab', async () => {
89+
const tabGroup = await loader.getHarness(tabGroupHarness);
90+
const tabs = await tabGroup.getTabs();
91+
expect(await tabs[0].isDisabled()).toBe(false);
92+
expect(await tabs[1].isDisabled()).toBe(false);
93+
expect(await tabs[2].isDisabled()).toBe(false);
94+
95+
fixture.componentInstance.isDisabled = true;
96+
fixture.detectChanges();
97+
98+
expect(await tabs[0].isDisabled()).toBe(false);
99+
expect(await tabs[1].isDisabled()).toBe(false);
100+
expect(await tabs[2].isDisabled()).toBe(true);
101+
});
102+
103+
it('should be able to select specific tab', async () => {
104+
const tabGroup = await loader.getHarness(tabGroupHarness);
105+
const tabs = await tabGroup.getTabs();
106+
expect(await tabs[0].isSelected()).toBe(true);
107+
expect(await tabs[1].isSelected()).toBe(false);
108+
expect(await tabs[2].isSelected()).toBe(false);
109+
110+
await tabs[1].select();
111+
expect(await tabs[0].isSelected()).toBe(false);
112+
expect(await tabs[1].isSelected()).toBe(true);
113+
expect(await tabs[2].isSelected()).toBe(false);
114+
115+
// Should not be able to select third tab if disabled.
116+
fixture.componentInstance.isDisabled = true;
117+
fixture.detectChanges();
118+
119+
await tabs[2].select();
120+
expect(await tabs[0].isSelected()).toBe(false);
121+
expect(await tabs[1].isSelected()).toBe(true);
122+
expect(await tabs[2].isSelected()).toBe(false);
123+
124+
// Should be able to select third tab if not disabled.
125+
fixture.componentInstance.isDisabled = false;
126+
fixture.detectChanges();
127+
await tabs[2].select();
128+
expect(await tabs[0].isSelected()).toBe(false);
129+
expect(await tabs[1].isSelected()).toBe(false);
130+
expect(await tabs[2].isSelected()).toBe(true);
131+
});
132+
}
133+
134+
@Component({
135+
template: `
136+
<mat-tab-group>
137+
<mat-tab label="First" aria-label="First tab">Content 1</mat-tab>
138+
<mat-tab label="Second" aria-label="Second tab">Content 2</mat-tab>
139+
<mat-tab label="Third" aria-labelledby="tabLabelId" [disabled]="isDisabled">
140+
<ng-template matTabLabel>Third</ng-template>
141+
Content 3
142+
</mat-tab>
143+
</mat-tab-group>
144+
`
145+
})
146+
class TabGroupHarnessTest {
147+
isDisabled = false;
148+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {ComponentHarness, HarnessPredicate} from '@angular/cdk-experimental/testing';
10+
import {TabGroupHarnessFilters} from './tab-group-harness-filters';
11+
import {MatTabHarness} from './tab-harness';
12+
13+
/**
14+
* Harness for interacting with a standard mat-tab-group in tests.
15+
* @dynamic
16+
*/
17+
export class MatTabGroupHarness extends ComponentHarness {
18+
static hostSelector = '.mat-tab-group';
19+
20+
/**
21+
* Gets a `HarnessPredicate` that can be used to search for a radio-button with
22+
* specific attributes.
23+
* @param options Options for narrowing the search
24+
* @return a `HarnessPredicate` configured with the given options.
25+
*/
26+
static with(options: TabGroupHarnessFilters = {}): HarnessPredicate<MatTabGroupHarness> {
27+
return new HarnessPredicate(MatTabGroupHarness);
28+
}
29+
30+
private _tabs = this.locatorForAll(MatTabHarness);
31+
32+
/** Gets all tabs of the tab group. */
33+
async getTabs(): Promise<MatTabHarness[]> {
34+
return this._tabs();
35+
}
36+
37+
/** Gets the selected tab of the tab group. */
38+
async getSelectedTab(): Promise<MatTabHarness> {
39+
const tabs = await this.getTabs();
40+
const isSelected = await Promise.all(tabs.map(t => t.isSelected()));
41+
for (let i = 0; i < tabs.length; i++) {
42+
if (isSelected[i]) {
43+
return tabs[i];
44+
}
45+
}
46+
throw new Error('No selected tab could be found.');
47+
}
48+
}
49+
50+

0 commit comments

Comments
 (0)