Skip to content

Commit c25e625

Browse files
authored
feat(aria/tabs): add test harnesses (#33079)
* feat(aria/tabs): add test harnesses * fixup! feat(aria/tabs): add test harnesses
1 parent bddfc39 commit c25e625

File tree

8 files changed

+399
-0
lines changed

8 files changed

+399
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
## API Report File for "@angular/aria_tabs_testing"
2+
3+
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
4+
5+
```ts
6+
7+
import { BaseHarnessFilters } from '@angular/cdk/testing';
8+
import { ComponentHarness } from '@angular/cdk/testing';
9+
import { ContentContainerComponentHarness } from '@angular/cdk/testing';
10+
import { HarnessLoader } from '@angular/cdk/testing';
11+
import { HarnessPredicate } from '@angular/cdk/testing';
12+
13+
// @public
14+
export class TabHarness extends ContentContainerComponentHarness {
15+
// (undocumented)
16+
protected getRootHarnessLoader(): Promise<HarnessLoader>;
17+
getTitle(): Promise<string>;
18+
// (undocumented)
19+
static hostSelector: string;
20+
isActive(): Promise<boolean>;
21+
isDisabled(): Promise<boolean>;
22+
isSelected(): Promise<boolean>;
23+
select(): Promise<void>;
24+
static with(options?: TabHarnessFilters): HarnessPredicate<TabHarness>;
25+
}
26+
27+
// @public
28+
export interface TabHarnessFilters extends BaseHarnessFilters {
29+
disabled?: boolean;
30+
selected?: boolean;
31+
title?: string | RegExp;
32+
}
33+
34+
// @public
35+
export class TabsHarness extends ComponentHarness {
36+
getSelectedTab(): Promise<TabHarness | null>;
37+
getTabs(filters?: TabHarnessFilters): Promise<TabHarness[]>;
38+
// (undocumented)
39+
static hostSelector: string;
40+
selectTab(filters?: TabHarnessFilters): Promise<void>;
41+
static with(options?: TabsHarnessFilters): HarnessPredicate<TabsHarness>;
42+
}
43+
44+
// @public
45+
export interface TabsHarnessFilters extends BaseHarnessFilters {
46+
}
47+
48+
// (No @packageDocumentation comment for this package)
49+
50+
```

src/aria/config.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ ARIA_ENTRYPOINTS = [
99
"menu",
1010
"menu/testing",
1111
"tabs",
12+
"tabs/testing",
1213
"toolbar",
1314
"toolbar/testing",
1415
"tree",

src/aria/tabs/testing/BUILD.bazel

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
load("//tools:defaults.bzl", "ng_project", "ng_web_test_suite", "ts_project")
2+
3+
package(default_visibility = ["//visibility:public"])
4+
5+
ts_project(
6+
name = "testing",
7+
srcs = glob(
8+
["**/*.ts"],
9+
exclude = ["**/*.spec.ts"],
10+
),
11+
deps = [
12+
"//src/cdk/testing",
13+
],
14+
)
15+
16+
filegroup(
17+
name = "source-files",
18+
srcs = glob(["**/*.ts"]),
19+
)
20+
21+
ng_project(
22+
name = "unit_tests_lib",
23+
testonly = True,
24+
srcs = glob(["**/*.spec.ts"]),
25+
deps = [
26+
":testing",
27+
"//:node_modules/@angular/common",
28+
"//:node_modules/@angular/core",
29+
"//src/aria/tabs",
30+
"//src/cdk/testing",
31+
"//src/cdk/testing/testbed",
32+
],
33+
)
34+
35+
ng_web_test_suite(
36+
name = "unit_tests",
37+
deps = [":unit_tests_lib"],
38+
)

src/aria/tabs/testing/index.ts

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.dev/license
7+
*/
8+
9+
export * from './public-api';
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
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.dev/license
7+
*/
8+
9+
export * from './tabs-harness';
10+
export * from './tabs-harness-filters';
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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.dev/license
7+
*/
8+
9+
import {BaseHarnessFilters} from '@angular/cdk/testing';
10+
11+
/** A set of criteria that can be used to filter a list of `TabsHarness` instances. */
12+
export interface TabsHarnessFilters extends BaseHarnessFilters {}
13+
14+
/** A set of criteria that can be used to filter a list of `TabHarness` instances. */
15+
export interface TabHarnessFilters extends BaseHarnessFilters {
16+
/** Only find instances whose title matches the given value. */
17+
title?: string | RegExp;
18+
/** Only find instances that are selected. */
19+
selected?: boolean;
20+
/** Only find instances that are disabled. */
21+
disabled?: boolean;
22+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
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.dev/license
7+
*/
8+
9+
import {Component} from '@angular/core';
10+
import {ComponentFixture, TestBed} from '@angular/core/testing';
11+
import {ComponentHarness, HarnessLoader} from '@angular/cdk/testing';
12+
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
13+
import {Tabs, TabList, Tab, TabPanel, TabContent} from '../../tabs';
14+
import {TabsHarness} from './tabs-harness';
15+
16+
class TestContentHarness extends ComponentHarness {
17+
static hostSelector = '.test-content';
18+
async getText(): Promise<string> {
19+
return (await this.host()).text();
20+
}
21+
}
22+
23+
describe('TabsHarness', () => {
24+
let fixture: ComponentFixture<TabsHarnessTest>;
25+
let loader: HarnessLoader;
26+
27+
beforeEach(() => {
28+
fixture = TestBed.createComponent(TabsHarnessTest);
29+
fixture.detectChanges();
30+
loader = TestbedHarnessEnvironment.loader(fixture);
31+
});
32+
33+
it('should load harness with tabs container', async () => {
34+
await expectAsync(loader.getHarness(TabsHarness)).toBeResolved();
35+
});
36+
37+
it('should get tabs', async () => {
38+
const tabs = await loader.getHarness(TabsHarness);
39+
40+
const tabItems = await tabs.getTabs();
41+
42+
expect(tabItems.length).toBe(3);
43+
});
44+
45+
it('should get tab panel content via ContentContainerComponentHarness', async () => {
46+
const tabs = await loader.getHarness(TabsHarness);
47+
const tabItems = await tabs.getTabs();
48+
49+
const contentHarness = await tabItems[0].getHarness(TestContentHarness);
50+
51+
expect(await contentHarness.getText()).toBe('Content 1');
52+
});
53+
54+
it('should get selected tab', async () => {
55+
const tabs = await loader.getHarness(TabsHarness);
56+
57+
const selectedTab = await tabs.getSelectedTab();
58+
59+
expect(await selectedTab?.getTitle()).toBe('Tab 1');
60+
});
61+
62+
it('should switch tabs on click', async () => {
63+
const tabs = await loader.getHarness(TabsHarness);
64+
const tabItems = await tabs.getTabs();
65+
expect(await tabItems[0].isSelected()).toBe(true);
66+
expect(await tabItems[1].isSelected()).toBe(false);
67+
68+
await tabItems[1].select();
69+
70+
expect(await tabItems[0].isSelected()).toBe(false);
71+
expect(await tabItems[1].isSelected()).toBe(true);
72+
});
73+
74+
it('should select tab matching filters', async () => {
75+
const tabs = await loader.getHarness(TabsHarness);
76+
const tabItems = await tabs.getTabs();
77+
78+
expect(await tabItems[0].isSelected()).toBe(true);
79+
expect(await tabItems[1].isSelected()).toBe(false);
80+
81+
await tabs.selectTab({title: 'Tab 2'});
82+
83+
expect(await tabItems[0].isSelected()).toBe(false);
84+
expect(await tabItems[1].isSelected()).toBe(true);
85+
});
86+
87+
it('should check disabled state', async () => {
88+
const tabs = await loader.getHarness(TabsHarness);
89+
const tabItems = await tabs.getTabs();
90+
91+
expect(await tabItems[0].isDisabled()).toBe(false);
92+
expect(await tabItems[2].isDisabled()).toBe(true);
93+
});
94+
95+
it('should check active state', async () => {
96+
const tabs = await loader.getHarness(TabsHarness);
97+
const tabItems = await tabs.getTabs();
98+
99+
expect(await tabItems[0].isActive()).toBe(true);
100+
expect(await tabItems[1].isActive()).toBe(false);
101+
});
102+
103+
it('should filter tabs by title', async () => {
104+
const tabs = await loader.getHarness(TabsHarness);
105+
106+
const filteredTabs = await tabs.getTabs({title: 'Tab 2'});
107+
108+
expect(filteredTabs.length).toBe(1);
109+
expect(await filteredTabs[0].getTitle()).toBe('Tab 2');
110+
});
111+
112+
it('should filter tabs by selected state', async () => {
113+
const tabs = await loader.getHarness(TabsHarness);
114+
115+
const filteredTabs = await tabs.getTabs({selected: true});
116+
117+
expect(filteredTabs.length).toBe(1);
118+
expect(await filteredTabs[0].getTitle()).toBe('Tab 1');
119+
});
120+
121+
it('should filter tabs by disabled state', async () => {
122+
const tabs = await loader.getHarness(TabsHarness);
123+
124+
const filteredTabs = await tabs.getTabs({disabled: true});
125+
126+
expect(filteredTabs.length).toBe(1);
127+
expect(await filteredTabs[0].getTitle()).toBe('Tab 3');
128+
});
129+
});
130+
131+
@Component({
132+
template: `
133+
<div ngTabs>
134+
<ul ngTabList [selectedTab]="'tab1'">
135+
<li ngTab value="tab1">Tab 1</li>
136+
<li ngTab value="tab2">Tab 2</li>
137+
<li ngTab value="tab3" [disabled]="true">Tab 3</li>
138+
</ul>
139+
140+
141+
<div ngTabPanel value="tab1">
142+
<ng-template ngTabContent>
143+
<div class="test-content">Content 1</div>
144+
</ng-template>
145+
</div>
146+
<div ngTabPanel value="tab2">
147+
<ng-template ngTabContent>Content 2</ng-template>
148+
</div>
149+
<div ngTabPanel value="tab3">
150+
<ng-template ngTabContent>Content 3</ng-template>
151+
</div>
152+
</div>
153+
`,
154+
imports: [Tabs, TabList, Tab, TabPanel, TabContent],
155+
})
156+
class TabsHarnessTest {}

0 commit comments

Comments
 (0)