Skip to content

Commit 4ae87f7

Browse files
committed
feat(material-experimental): add option to filter checkbox harnesses by name
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)
1 parent b8c9da6 commit 4ae87f7

File tree

4 files changed

+42
-22
lines changed

4 files changed

+42
-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: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,17 @@ 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 there is no way for
33+
// developers to query the checkbox harness by CSS selector.
34+
.addOption('name', options.name, async (harness, name) => await harness.getName() === name);
3035
}
3136

3237
private _label = this.locatorFor('.mat-checkbox-label');
@@ -64,22 +69,22 @@ export class MatCheckboxHarness extends ComponentHarness {
6469
}
6570

6671
/** Gets a promise for the checkbox's name. */
67-
async getName(): Promise<string | null> {
72+
async getName(): Promise<string|null> {
6873
return (await this._input()).getAttribute('name');
6974
}
7075

7176
/** Gets a promise for the checkbox's value. */
72-
async getValue(): Promise<string | null> {
77+
async getValue(): Promise<string|null> {
7378
return (await this._input()).getAttribute('value');
7479
}
7580

7681
/** Gets a promise for the checkbox's aria-label. */
77-
async getAriaLabel(): Promise<string | null> {
82+
async getAriaLabel(): Promise<string|null> {
7883
return (await this._input()).getAttribute('aria-label');
7984
}
8085

8186
/** Gets a promise for the checkbox's aria-labelledby. */
82-
async getAriaLabelledby(): Promise<string | null> {
87+
async getAriaLabelledby(): Promise<string|null> {
8388
return (await this._input()).getAttribute('aria-labelledby');
8489
}
8590

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,17 @@ 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 there is no way for
33+
// developers to query the checkbox harness by CSS selector.
34+
.addOption('name', options.name, async (harness, name) => await harness.getName() === name);
3035
}
3136

3237
private _label = this.locatorFor('label');
@@ -64,22 +69,22 @@ export class MatCheckboxHarness extends ComponentHarness {
6469
}
6570

6671
/** Gets a promise for the checkbox's name. */
67-
async getName(): Promise<string | null> {
72+
async getName(): Promise<string|null> {
6873
return (await this._input()).getAttribute('name');
6974
}
7075

7176
/** Gets a promise for the checkbox's value. */
72-
async getValue(): Promise<string | null> {
77+
async getValue(): Promise<string|null> {
7378
return (await this._input()).getAttribute('value');
7479
}
7580

7681
/** Gets a promise for the checkbox's aria-label. */
77-
async getAriaLabel(): Promise<string | null> {
82+
async getAriaLabel(): Promise<string|null> {
7883
return (await this._input()).getAttribute('aria-label');
7984
}
8085

8186
/** Gets a promise for the checkbox's aria-labelledby. */
82-
async getAriaLabelledby(): Promise<string | null> {
87+
async getAriaLabelledby(): Promise<string|null> {
8388
return (await this._input()).getAttribute('aria-labelledby');
8489
}
8590

0 commit comments

Comments
 (0)