Skip to content

Commit fa489fc

Browse files
committed
feat(material/testing): MatChipHarness getAvatar
1 parent b8d83cb commit fa489fc

File tree

11 files changed

+222
-21
lines changed

11 files changed

+222
-21
lines changed

src/material-experimental/mdc-chips/testing/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ ng_test_library(
2323
"//src/cdk/testing",
2424
"//src/cdk/testing/testbed",
2525
"//src/material-experimental/mdc-chips",
26+
"//src/material/icon",
27+
"//src/material/icon/testing",
2628
"@npm//@angular/forms",
2729
],
2830
)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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 {HarnessPredicate, ComponentHarness} from '@angular/cdk/testing';
10+
import {ChipAvatarHarnessFilters} from './chip-harness-filters';
11+
12+
/** Harness for interacting with a standard Material chip avatar in tests. */
13+
export class MatChipAvatarHarness extends ComponentHarness {
14+
static hostSelector = '.mat-mdc-chip-avatar';
15+
16+
/**
17+
* Gets a `HarnessPredicate` that can be used to search for a `MatChipAvatarHarness` that meets
18+
* certain criteria.
19+
* @param options Options for filtering which input instances are considered a match.
20+
* @return a `HarnessPredicate` configured with the given options.
21+
*/
22+
static with(options: ChipAvatarHarnessFilters = {}): HarnessPredicate<MatChipAvatarHarness> {
23+
return new HarnessPredicate(MatChipAvatarHarness, options);
24+
}
25+
}

src/material-experimental/mdc-chips/testing/chip-harness-filters.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {BaseHarnessFilters} from '@angular/cdk/testing';
1111
export interface ChipHarnessFilters extends BaseHarnessFilters {
1212
/** Only find instances whose text matches the given value. */
1313
text?: string | RegExp;
14+
/** Only find instances that have an avatar inside */
15+
hasAvatar?: boolean;
1416
}
1517

1618
export interface ChipInputHarnessFilters extends BaseHarnessFilters {
@@ -34,3 +36,5 @@ export interface ChipRowHarnessFilters extends ChipHarnessFilters {}
3436
export interface ChipSetHarnessFilters extends BaseHarnessFilters {}
3537

3638
export interface ChipRemoveHarnessFilters extends BaseHarnessFilters {}
39+
40+
export interface ChipAvatarHarnessFilters extends BaseHarnessFilters {}

src/material-experimental/mdc-chips/testing/chip-harness.spec.ts

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import {HarnessLoader, parallel} from '@angular/cdk/testing';
22
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
33
import {Component} from '@angular/core';
44
import {ComponentFixture, TestBed} from '@angular/core/testing';
5+
import {MatIconModule} from '@angular/material/icon';
6+
import {MatIconHarness} from '@angular/material/icon/testing';
57
import {MatChipsModule} from '../index';
68
import {MatChipHarness} from './chip-harness';
79

@@ -12,7 +14,7 @@ describe('MatChipHarness', () => {
1214

1315
beforeEach(async () => {
1416
await TestBed.configureTestingModule({
15-
imports: [MatChipsModule],
17+
imports: [MatChipsModule, MatIconModule],
1618
declarations: [ChipHarnessTest],
1719
}).compileComponents();
1820

@@ -55,13 +57,49 @@ describe('MatChipHarness', () => {
5557
expect(await harness.getRemoveButton()).toBeTruthy();
5658
});
5759

60+
it('should find chips with avatar', async () => {
61+
const chips = await loader.getAllHarnesses(MatChipHarness.with({
62+
hasAvatar: true
63+
}));
64+
expect(chips.length).toBe(1);
65+
});
66+
67+
it('should find chips without avatar', async () => {
68+
const chips = await loader.getAllHarnesses(MatChipHarness.with({
69+
hasAvatar: false
70+
}));
71+
expect(chips.length).toBe(4);
72+
});
73+
74+
it('should find avatar in chip', async () => {
75+
const chip = await loader.getHarness(MatChipHarness.with({
76+
hasAvatar: true
77+
}));
78+
const avatar = await chip.getAvatar();
79+
expect(avatar).toBeTruthy();
80+
const avatarHost = await avatar?.host();
81+
expect(await avatarHost?.getAttribute('aria-label')).toBe('Coronavirus');
82+
});
83+
84+
it('should find icon in chip', async () => {
85+
const chip = await loader.getHarness(MatChipHarness.with({
86+
selector: '.mat-chip--with-icon-avatar'
87+
}));
88+
expect(chip).toBeTruthy();
89+
const icon = await chip.getHarness(MatIconHarness);
90+
expect(icon).toBeTruthy();
91+
expect(await icon.getName()).toBe('coronavirus');
92+
});
5893
});
5994

6095
@Component({
6196
template: `
6297
<mat-basic-chip>Basic Chip</mat-basic-chip>
6398
<mat-chip>Chip <span matChipTrailingIcon>trailing_icon</span></mat-chip>
64-
<mat-chip><mat-chip-avatar>B</mat-chip-avatar>Chip with avatar</mat-chip>
99+
<mat-chip class="mat-chip--with-icon-avatar">
100+
<mat-icon matChipAvatar aria-label="Coronavirus" aria-hidden="false">coronavirus</mat-icon>
101+
Chip with avatar
102+
</mat-chip>
65103
<mat-chip
66104
class="has-remove-button"
67105
disabled>Disabled Chip <span matChipRemove>remove_icon</span>

src/material-experimental/mdc-chips/testing/chip-harness.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {ComponentHarness, HarnessPredicate, TestKey} from '@angular/cdk/testing';
10-
import {ChipHarnessFilters, ChipRemoveHarnessFilters} from './chip-harness-filters';
9+
import {ContentContainerComponentHarness, HarnessPredicate, TestKey} from '@angular/cdk/testing';
10+
import {MatChipAvatarHarness} from './chip-avatar-harness';
11+
import {
12+
ChipAvatarHarnessFilters,
13+
ChipHarnessFilters,
14+
ChipRemoveHarnessFilters
15+
} from './chip-harness-filters';
1116
import {MatChipRemoveHarness} from './chip-remove-harness';
1217

1318
/** Harness for interacting with a mat-chip in tests. */
14-
export class MatChipHarness extends ComponentHarness {
19+
export class MatChipHarness extends ContentContainerComponentHarness {
1520
static hostSelector = '.mat-mdc-basic-chip, .mat-mdc-chip';
1621

1722
/**
@@ -22,6 +27,11 @@ export class MatChipHarness extends ComponentHarness {
2227
static with<T extends typeof MatChipHarness>(this: T, options: ChipHarnessFilters = {}):
2328
HarnessPredicate<InstanceType<T>> {
2429
return new HarnessPredicate(MatChipHarness, options)
30+
.addOption(
31+
'hasAvatar',
32+
options.hasAvatar,
33+
async (harness, hasAvatar) => (await harness.hasAvatar()) === hasAvatar
34+
)
2535
.addOption('text', options.text, (harness, label) => {
2636
return HarnessPredicate.stringMatches(harness.getText(), label);
2737
}) as unknown as HarnessPredicate<InstanceType<T>>;
@@ -52,4 +62,19 @@ export class MatChipHarness extends ComponentHarness {
5262
async getRemoveButton(filter: ChipRemoveHarnessFilters = {}): Promise<MatChipRemoveHarness> {
5363
return this.locatorFor(MatChipRemoveHarness.with(filter))();
5464
}
65+
66+
/**
67+
* Whether the chip has an avatar
68+
*/
69+
async hasAvatar() {
70+
return (await this.host()).hasClass('mat-mdc-chip-with-avatar');
71+
}
72+
73+
/**
74+
* Gets the avatar inside a chip.
75+
* @param filter Optionally filters which avatars are included.
76+
*/
77+
async getAvatar(filter: ChipAvatarHarnessFilters = {}): Promise<MatChipAvatarHarness | null> {
78+
return this.locatorForOptional(MatChipAvatarHarness.with(filter))();
79+
}
5580
}

src/material/chips/testing/BUILD.bazel

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ ng_test_library(
2929
"//src/cdk/testing/testbed",
3030
"//src/material/chips",
3131
"//src/material/form-field",
32+
"//src/material/icon",
33+
"//src/material/icon/testing",
3234
"@npm//@angular/platform-browser",
3335
],
3436
)
@@ -43,6 +45,8 @@ ng_test_library(
4345
":harness_tests_lib",
4446
":testing",
4547
"//src/material/chips",
48+
"//src/material/icon",
49+
"//src/material/icon/testing",
4650
],
4751
)
4852

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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 {HarnessPredicate, ComponentHarness} from '@angular/cdk/testing';
10+
import {ChipAvatarHarnessFilters} from './chip-harness-filters';
11+
12+
/** Harness for interacting with a standard Material chip avatar in tests. */
13+
export class MatChipAvatarHarness extends ComponentHarness {
14+
static hostSelector = '.mat-chip-avatar';
15+
16+
/**
17+
* Gets a `HarnessPredicate` that can be used to search for a `MatChipAvatarHarness` that meets
18+
* certain criteria.
19+
* @param options Options for filtering which input instances are considered a match.
20+
* @return a `HarnessPredicate` configured with the given options.
21+
*/
22+
static with(options: ChipAvatarHarnessFilters = {}): HarnessPredicate<MatChipAvatarHarness> {
23+
return new HarnessPredicate(MatChipAvatarHarness, options);
24+
}
25+
}

src/material/chips/testing/chip-harness-filters.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {BaseHarnessFilters} from '@angular/cdk/testing';
1111
export interface ChipHarnessFilters extends BaseHarnessFilters {
1212
/** Only find instances whose text matches the given value. */
1313
text?: string | RegExp;
14+
/** Only find instances that have an avatar inside */
15+
hasAvatar?: boolean;
1416
/**
1517
* Only find chip instances whose selected state matches the given value.
1618
* @deprecated Use `MatChipOptionHarness` together with `ChipOptionHarnessFilters`.
@@ -41,3 +43,6 @@ export interface ChipInputHarnessFilters extends BaseHarnessFilters {
4143

4244
/** A set of criteria that can be used to filter a list of `MatChipRemoveHarness` instances. */
4345
export interface ChipRemoveHarnessFilters extends BaseHarnessFilters {}
46+
47+
/** A set of criteria that can be used to filter a list of `MatChipAvatarHarness` instances. */
48+
export interface ChipAvatarHarnessFilters extends BaseHarnessFilters {}

src/material/chips/testing/chip-harness.ts

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {ComponentHarness, HarnessPredicate, TestKey} from '@angular/cdk/testing';
10-
import {ChipHarnessFilters, ChipRemoveHarnessFilters} from './chip-harness-filters';
9+
import {ContentContainerComponentHarness, HarnessPredicate, TestKey} from '@angular/cdk/testing';
10+
import {MatChipAvatarHarness} from './chip-avatar-harness';
11+
import {
12+
ChipAvatarHarnessFilters,
13+
ChipHarnessFilters,
14+
ChipRemoveHarnessFilters
15+
} from './chip-harness-filters';
1116
import {MatChipRemoveHarness} from './chip-remove-harness';
1217

1318
/** Harness for interacting with a standard selectable Angular Material chip in tests. */
14-
export class MatChipHarness extends ComponentHarness {
19+
export class MatChipHarness extends ContentContainerComponentHarness {
1520
/** The selector for the host element of a `MatChip` instance. */
1621
static hostSelector = '.mat-chip';
1722

@@ -26,7 +31,9 @@ export class MatChipHarness extends ComponentHarness {
2631
.addOption('text', options.text,
2732
(harness, label) => HarnessPredicate.stringMatches(harness.getText(), label))
2833
.addOption('selected', options.selected,
29-
async (harness, selected) => (await harness.isSelected()) === selected);
34+
async (harness, selected) => (await harness.isSelected()) === selected)
35+
.addOption('hasAvatar', options.hasAvatar,
36+
async (harness, hasAvatar) => (await harness.hasAvatar()) === hasAvatar);
3037
}
3138

3239
/** Gets the text of the chip. */
@@ -88,9 +95,24 @@ export class MatChipHarness extends ComponentHarness {
8895

8996
/**
9097
* Gets the remove button inside of a chip.
91-
* @param filter Optionally filters which chips are included.
98+
* @param filter Optionally filters which remove buttons are included.
9299
*/
93100
async getRemoveButton(filter: ChipRemoveHarnessFilters = {}): Promise<MatChipRemoveHarness> {
94101
return this.locatorFor(MatChipRemoveHarness.with(filter))();
95102
}
103+
104+
/**
105+
* Whether the chip has an avatar
106+
*/
107+
async hasAvatar() {
108+
return (await this.host()).hasClass('mat-chip-with-avatar');
109+
}
110+
111+
/**
112+
* Gets the avatar inside a chip.
113+
* @param filter Optionally filters which avatars are included.
114+
*/
115+
async getAvatar(filter: ChipAvatarHarnessFilters = {}): Promise<MatChipAvatarHarness | null> {
116+
return this.locatorForOptional(MatChipAvatarHarness.with(filter))();
117+
}
96118
}
Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import {MatChipsModule} from '@angular/material/chips';
22
import {runHarnessTests} from '@angular/material/chips/testing/shared.spec';
3+
import {MatIconModule} from '@angular/material/icon';
4+
import {MatIconHarness} from '@angular/material/icon/testing';
35
import {MatChipListHarness} from './chip-list-harness';
46
import {MatChipHarness} from './chip-harness';
57
import {MatChipInputHarness} from './chip-input-harness';
@@ -8,6 +10,15 @@ import {MatChipListboxHarness} from './chip-listbox-harness';
810
import {MatChipOptionHarness} from './chip-option-harness';
911

1012
describe('Non-MDC-based MatChipListHarness', () => {
11-
runHarnessTests(MatChipsModule, MatChipListHarness, MatChipListboxHarness, MatChipHarness,
12-
MatChipOptionHarness, MatChipInputHarness, MatChipRemoveHarness);
13+
runHarnessTests(
14+
MatChipsModule,
15+
MatChipListHarness,
16+
MatChipListboxHarness,
17+
MatChipHarness,
18+
MatChipOptionHarness,
19+
MatChipInputHarness,
20+
MatChipRemoveHarness,
21+
MatIconModule,
22+
MatIconHarness
23+
);
1324
});

0 commit comments

Comments
 (0)