Skip to content

Commit 4598616

Browse files
devversionmmalerba
authored andcommitted
feat(material-experimental): add option to filter checkbox har… (#16662)
Adds an option to the checkbox harnesses that allows developers to filter harnesses by checkbox names. This is helpful because developers can not filter checkboxes by name using CSS selectors because the `name` input binding is not bound to the host DOM element. Similar to #16609 (comment) (cherry picked from commit 2cbabf0)
1 parent 0ec2e56 commit 4598616

File tree

4 files changed

+44
-22
lines changed

4 files changed

+44
-22
lines changed

src/material-experimental/mdc-checkbox/harness/checkbox-harness-filters.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
*/
88

99
export type CheckboxHarnessFilters = {
10-
label?: string | RegExp
10+
label?: string|RegExp;
11+
name?: string;
1112
};

src/material-experimental/mdc-checkbox/harness/checkbox-harness.spec.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ let checkboxHarness: typeof MatCheckboxHarness;
1515
describe('MatCheckboxHarness', () => {
1616
describe('non-MDC-based', () => {
1717
beforeEach(async () => {
18-
await TestBed.configureTestingModule({
19-
imports: [MatCheckboxModule, ReactiveFormsModule],
20-
declarations: [CheckboxHarnessTest],
21-
}).compileComponents();
18+
await TestBed
19+
.configureTestingModule({
20+
imports: [MatCheckboxModule, ReactiveFormsModule],
21+
declarations: [CheckboxHarnessTest],
22+
})
23+
.compileComponents();
2224

2325
fixture = TestBed.createComponent(CheckboxHarnessTest);
2426
fixture.detectChanges();
@@ -31,10 +33,12 @@ describe('MatCheckboxHarness', () => {
3133

3234
describe('MDC-based', () => {
3335
beforeEach(async () => {
34-
await TestBed.configureTestingModule({
35-
imports: [MatMdcCheckboxModule, ReactiveFormsModule],
36-
declarations: [CheckboxHarnessTest],
37-
}).compileComponents();
36+
await TestBed
37+
.configureTestingModule({
38+
imports: [MatMdcCheckboxModule, ReactiveFormsModule],
39+
declarations: [CheckboxHarnessTest],
40+
})
41+
.compileComponents();
3842

3943
fixture = TestBed.createComponent(CheckboxHarnessTest);
4044
fixture.detectChanges();
@@ -61,6 +65,12 @@ function runTests() {
6165
expect(await checkboxes[0].getLabelText()).toBe('First');
6266
});
6367

68+
it('should load checkbox with name', async () => {
69+
const checkboxes = await loader.getAllHarnesses(checkboxHarness.with({name: 'first-name'}));
70+
expect(checkboxes.length).toBe(1);
71+
expect(await checkboxes[0].getLabelText()).toBe('First');
72+
});
73+
6474
it('should load checkbox with regex label match', async () => {
6575
const checkboxes = await loader.getAllHarnesses(checkboxHarness.with({label: /^s/i}));
6676
expect(checkboxes.length).toBe(1);
@@ -199,4 +209,3 @@ class CheckboxHarnessTest {
199209
ctrl = new FormControl(true);
200210
disabled = true;
201211
}
202-

src/material-experimental/mdc-checkbox/harness/checkbox-harness.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,18 @@ export class MatCheckboxHarness extends ComponentHarness {
2121
* Gets a `HarnessPredicate` that can be used to search for a checkbox with specific attributes.
2222
* @param options Options for narrowing the search:
2323
* - `label` finds a checkbox with specific label text.
24+
* - `name` finds a checkbox with specific name.
2425
* @return a `HarnessPredicate` configured with the given options.
2526
*/
2627
static with(options: CheckboxHarnessFilters = {}): HarnessPredicate<MatCheckboxHarness> {
2728
return new HarnessPredicate(MatCheckboxHarness)
28-
.addOption('label', options.label,
29-
(harness, label) => HarnessPredicate.stringMatches(harness.getLabelText(), label));
29+
.addOption(
30+
'label', options.label,
31+
(harness, label) => HarnessPredicate.stringMatches(harness.getLabelText(), label))
32+
// We want to provide a filter option for "name" because the name of the checkbox is
33+
// only set on the underlying input. This means that it's not possible for developers
34+
// to retrieve the harness of a specific checkbox with name through a CSS selector.
35+
.addOption('name', options.name, async (harness, name) => await harness.getName() === name);
3036
}
3137

3238
private _label = this.locatorFor('.mat-checkbox-label');
@@ -64,22 +70,22 @@ export class MatCheckboxHarness extends ComponentHarness {
6470
}
6571

6672
/** Gets a promise for the checkbox's name. */
67-
async getName(): Promise<string | null> {
73+
async getName(): Promise<string|null> {
6874
return (await this._input()).getAttribute('name');
6975
}
7076

7177
/** Gets a promise for the checkbox's value. */
72-
async getValue(): Promise<string | null> {
78+
async getValue(): Promise<string|null> {
7379
return (await this._input()).getAttribute('value');
7480
}
7581

7682
/** Gets a promise for the checkbox's aria-label. */
77-
async getAriaLabel(): Promise<string | null> {
83+
async getAriaLabel(): Promise<string|null> {
7884
return (await this._input()).getAttribute('aria-label');
7985
}
8086

8187
/** Gets a promise for the checkbox's aria-labelledby. */
82-
async getAriaLabelledby(): Promise<string | null> {
88+
async getAriaLabelledby(): Promise<string|null> {
8389
return (await this._input()).getAttribute('aria-labelledby');
8490
}
8591

src/material-experimental/mdc-checkbox/harness/mdc-checkbox-harness.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,18 @@ export class MatCheckboxHarness extends ComponentHarness {
2121
* Gets a `HarnessPredicate` that can be used to search for a checkbox with specific attributes.
2222
* @param options Options for narrowing the search:
2323
* - `label` finds a checkbox with specific label text.
24+
* - `name` finds a checkbox with specific name.
2425
* @return a `HarnessPredicate` configured with the given options.
2526
*/
2627
static with(options: CheckboxHarnessFilters = {}): HarnessPredicate<MatCheckboxHarness> {
2728
return new HarnessPredicate(MatCheckboxHarness)
28-
.addOption('label', options.label,
29-
(harness, label) => HarnessPredicate.stringMatches(harness.getLabelText(), label));
29+
.addOption(
30+
'label', options.label,
31+
(harness, label) => HarnessPredicate.stringMatches(harness.getLabelText(), label))
32+
// We want to provide a filter option for "name" because the name of the checkbox is
33+
// only set on the underlying input. This means that it's not possible for developers
34+
// to retrieve the harness of a specific checkbox with name through a CSS selector.
35+
.addOption('name', options.name, async (harness, name) => await harness.getName() === name);
3036
}
3137

3238
private _label = this.locatorFor('label');
@@ -64,22 +70,22 @@ export class MatCheckboxHarness extends ComponentHarness {
6470
}
6571

6672
/** Gets a promise for the checkbox's name. */
67-
async getName(): Promise<string | null> {
73+
async getName(): Promise<string|null> {
6874
return (await this._input()).getAttribute('name');
6975
}
7076

7177
/** Gets a promise for the checkbox's value. */
72-
async getValue(): Promise<string | null> {
78+
async getValue(): Promise<string|null> {
7379
return (await this._input()).getAttribute('value');
7480
}
7581

7682
/** Gets a promise for the checkbox's aria-label. */
77-
async getAriaLabel(): Promise<string | null> {
83+
async getAriaLabel(): Promise<string|null> {
7884
return (await this._input()).getAttribute('aria-label');
7985
}
8086

8187
/** Gets a promise for the checkbox's aria-labelledby. */
82-
async getAriaLabelledby(): Promise<string | null> {
88+
async getAriaLabelledby(): Promise<string|null> {
8389
return (await this._input()).getAttribute('aria-labelledby');
8490
}
8591

0 commit comments

Comments
 (0)