Skip to content

Commit fe0e963

Browse files
devversionjelbourn
authored andcommitted
fix(material/input): input harness not matching matNativeControl (#18221)
* fix(material/input): input harness selector not matching `matNativeControl` The input harness currently only matches `[matInput]`, but does not match `[matNativeControl]` usages. Since both names, resolve to the same directive, we should ensure that the harness works for both possible usages. * fixup! fix(material/input): input harness selector not matching `matNativeControl` Address feedback * fixup! fixup! fix(material/input): input harness selector not matching `matNativeControl` Address feedback
1 parent 44c1a11 commit fe0e963

File tree

2 files changed

+54
-11
lines changed

2 files changed

+54
-11
lines changed

src/material/input/testing/input-harness.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ import {InputHarnessFilters} from './input-harness-filters';
1212

1313
/** Harness for interacting with a standard Material inputs in tests. */
1414
export class MatInputHarness extends MatFormFieldControlHarness {
15-
static hostSelector = '[matInput]';
15+
// TODO: We do not want to handle `select` elements with `matNativeControl` because
16+
// not all methods of this harness work reasonably for native select elements.
17+
// For more details. See: https://github.com/angular/components/pull/18221.
18+
static hostSelector = '[matInput], input[matNativeControl], textarea[matNativeControl]';
1619

1720
/**
1821
* Gets a `HarnessPredicate` that can be used to search for a `MatInputHarness` that meets

src/material/input/testing/shared.spec.ts

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export function runHarnessTests(
2828

2929
it('should load all input harnesses', async () => {
3030
const inputs = await loader.getAllHarnesses(inputHarness);
31-
expect(inputs.length).toBe(3);
31+
expect(inputs.length).toBe(5);
3232
});
3333

3434
it('should load input with specific id', async () => {
@@ -49,48 +49,62 @@ export function runHarnessTests(
4949

5050
it('should be able to get id of input', async () => {
5151
const inputs = await loader.getAllHarnesses(inputHarness);
52-
expect(inputs.length).toBe(3);
52+
expect(inputs.length).toBe(5);
5353
expect(await inputs[0].getId()).toMatch(/mat-input-\d+/);
5454
expect(await inputs[1].getId()).toMatch(/mat-input-\d+/);
5555
expect(await inputs[2].getId()).toBe('myTextarea');
56+
expect(await inputs[3].getId()).toBe('nativeControl');
57+
expect(await inputs[4].getId()).toMatch(/mat-input-\d+/);
5658
});
5759

5860
it('should be able to get name of input', async () => {
5961
const inputs = await loader.getAllHarnesses(inputHarness);
60-
expect(inputs.length).toBe(3);
62+
expect(inputs.length).toBe(5);
6163
expect(await inputs[0].getName()).toBe('favorite-food');
6264
expect(await inputs[1].getName()).toBe('');
6365
expect(await inputs[2].getName()).toBe('');
66+
expect(await inputs[3].getName()).toBe('');
67+
expect(await inputs[4].getName()).toBe('');
6468
});
6569

6670
it('should be able to get value of input', async () => {
6771
const inputs = await loader.getAllHarnesses(inputHarness);
68-
expect(inputs.length).toBe(3);
72+
expect(inputs.length).toBe(5);
6973
expect(await inputs[0].getValue()).toBe('Sushi');
7074
expect(await inputs[1].getValue()).toBe('');
7175
expect(await inputs[2].getValue()).toBe('');
76+
expect(await inputs[3].getValue()).toBe('');
77+
expect(await inputs[4].getValue()).toBe('');
7278
});
7379

7480
it('should be able to set value of input', async () => {
7581
const inputs = await loader.getAllHarnesses(inputHarness);
76-
expect(inputs.length).toBe(3);
82+
expect(inputs.length).toBe(5);
7783
expect(await inputs[0].getValue()).toBe('Sushi');
7884
expect(await inputs[1].getValue()).toBe('');
85+
expect(await inputs[3].getValue()).toBe('');
86+
expect(await inputs[4].getValue()).toBe('');
7987

8088
await inputs[0].setValue('');
8189
await inputs[2].setValue('new-value');
90+
await inputs[3].setValue('new-value');
91+
await inputs[4].setValue('new-value');
8292

8393
expect(await inputs[0].getValue()).toBe('');
8494
expect(await inputs[2].getValue()).toBe('new-value');
95+
expect(await inputs[3].getValue()).toBe('new-value');
96+
expect(await inputs[4].getValue()).toBe('new-value');
8597
});
8698

8799
it('should be able to get disabled state', async () => {
88100
const inputs = await loader.getAllHarnesses(inputHarness);
89-
expect(inputs.length).toBe(3);
101+
expect(inputs.length).toBe(5);
90102

91103
expect(await inputs[0].isDisabled()).toBe(false);
92104
expect(await inputs[1].isDisabled()).toBe(false);
93105
expect(await inputs[2].isDisabled()).toBe(false);
106+
expect(await inputs[3].isDisabled()).toBe(false);
107+
expect(await inputs[4].isDisabled()).toBe(false);
94108

95109
fixture.componentInstance.disabled = true;
96110

@@ -99,11 +113,13 @@ export function runHarnessTests(
99113

100114
it('should be able to get readonly state', async () => {
101115
const inputs = await loader.getAllHarnesses(inputHarness);
102-
expect(inputs.length).toBe(3);
116+
expect(inputs.length).toBe(5);
103117

104118
expect(await inputs[0].isReadonly()).toBe(false);
105119
expect(await inputs[1].isReadonly()).toBe(false);
106120
expect(await inputs[2].isReadonly()).toBe(false);
121+
expect(await inputs[3].isReadonly()).toBe(false);
122+
expect(await inputs[4].isReadonly()).toBe(false);
107123

108124
fixture.componentInstance.readonly = true;
109125

@@ -112,11 +128,13 @@ export function runHarnessTests(
112128

113129
it('should be able to get required state', async () => {
114130
const inputs = await loader.getAllHarnesses(inputHarness);
115-
expect(inputs.length).toBe(3);
131+
expect(inputs.length).toBe(5);
116132

117133
expect(await inputs[0].isRequired()).toBe(false);
118134
expect(await inputs[1].isRequired()).toBe(false);
119135
expect(await inputs[2].isRequired()).toBe(false);
136+
expect(await inputs[3].isRequired()).toBe(false);
137+
expect(await inputs[4].isRequired()).toBe(false);
120138

121139
fixture.componentInstance.required = true;
122140

@@ -125,18 +143,22 @@ export function runHarnessTests(
125143

126144
it('should be able to get placeholder of input', async () => {
127145
const inputs = await loader.getAllHarnesses(inputHarness);
128-
expect(inputs.length).toBe(3);
146+
expect(inputs.length).toBe(5);
129147
expect(await inputs[0].getPlaceholder()).toBe('Favorite food');
130148
expect(await inputs[1].getPlaceholder()).toBe('');
131149
expect(await inputs[2].getPlaceholder()).toBe('Leave a comment');
150+
expect(await inputs[3].getPlaceholder()).toBe('Native control');
151+
expect(await inputs[4].getPlaceholder()).toBe('');
132152
});
133153

134154
it('should be able to get type of input', async () => {
135155
const inputs = await loader.getAllHarnesses(inputHarness);
136-
expect(inputs.length).toBe(3);
156+
expect(inputs.length).toBe(5);
137157
expect(await inputs[0].getType()).toBe('text');
138158
expect(await inputs[1].getType()).toBe('number');
139159
expect(await inputs[2].getType()).toBe('textarea');
160+
expect(await inputs[3].getType()).toBe('text');
161+
expect(await inputs[4].getType()).toBe('textarea');
140162

141163
fixture.componentInstance.inputType = 'text';
142164

@@ -180,6 +202,24 @@ function getActiveElementTagName() {
180202
<mat-form-field>
181203
<textarea id="myTextarea" matInput placeholder="Leave a comment"></textarea>
182204
</mat-form-field>
205+
206+
<mat-form-field>
207+
<input matNativeControl placeholder="Native control" id="nativeControl">
208+
</mat-form-field>
209+
210+
<mat-form-field>
211+
<textarea matNativeControl></textarea>
212+
</mat-form-field>
213+
214+
<mat-form-field>
215+
<!--
216+
Select native controls should not be handled as part of the input harness. We add this
217+
to assert that the harness does not accidentally match it.
218+
-->
219+
<select matNativeControl>
220+
<option value="first">First</option>
221+
</select>
222+
</mat-form-field>
183223
`
184224
})
185225
class InputHarnessTest {

0 commit comments

Comments
 (0)