Skip to content

fix(material/input): input harness not matching matNativeControl #18221

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/material/input/testing/input-harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import {InputHarnessFilters} from './input-harness-filters';

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

/**
* Gets a `HarnessPredicate` that can be used to search for a `MatInputHarness` that meets
Expand Down
60 changes: 50 additions & 10 deletions src/material/input/testing/shared.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function runHarnessTests(

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

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

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

it('should be able to get name of input', async () => {
const inputs = await loader.getAllHarnesses(inputHarness);
expect(inputs.length).toBe(3);
expect(inputs.length).toBe(5);
expect(await inputs[0].getName()).toBe('favorite-food');
expect(await inputs[1].getName()).toBe('');
expect(await inputs[2].getName()).toBe('');
expect(await inputs[3].getName()).toBe('');
expect(await inputs[4].getName()).toBe('');
});

it('should be able to get value of input', async () => {
const inputs = await loader.getAllHarnesses(inputHarness);
expect(inputs.length).toBe(3);
expect(inputs.length).toBe(5);
expect(await inputs[0].getValue()).toBe('Sushi');
expect(await inputs[1].getValue()).toBe('');
expect(await inputs[2].getValue()).toBe('');
expect(await inputs[3].getValue()).toBe('');
expect(await inputs[4].getValue()).toBe('');
});

it('should be able to set value of input', async () => {
const inputs = await loader.getAllHarnesses(inputHarness);
expect(inputs.length).toBe(3);
expect(inputs.length).toBe(5);
expect(await inputs[0].getValue()).toBe('Sushi');
expect(await inputs[1].getValue()).toBe('');
expect(await inputs[3].getValue()).toBe('');
expect(await inputs[4].getValue()).toBe('');

await inputs[0].setValue('');
await inputs[2].setValue('new-value');
await inputs[3].setValue('new-value');
await inputs[4].setValue('new-value');

expect(await inputs[0].getValue()).toBe('');
expect(await inputs[2].getValue()).toBe('new-value');
expect(await inputs[3].getValue()).toBe('new-value');
expect(await inputs[4].getValue()).toBe('new-value');
});

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

expect(await inputs[0].isDisabled()).toBe(false);
expect(await inputs[1].isDisabled()).toBe(false);
expect(await inputs[2].isDisabled()).toBe(false);
expect(await inputs[3].isDisabled()).toBe(false);
expect(await inputs[4].isDisabled()).toBe(false);

fixture.componentInstance.disabled = true;

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

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

expect(await inputs[0].isReadonly()).toBe(false);
expect(await inputs[1].isReadonly()).toBe(false);
expect(await inputs[2].isReadonly()).toBe(false);
expect(await inputs[3].isReadonly()).toBe(false);
expect(await inputs[4].isReadonly()).toBe(false);

fixture.componentInstance.readonly = true;

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

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

expect(await inputs[0].isRequired()).toBe(false);
expect(await inputs[1].isRequired()).toBe(false);
expect(await inputs[2].isRequired()).toBe(false);
expect(await inputs[3].isRequired()).toBe(false);
expect(await inputs[4].isRequired()).toBe(false);

fixture.componentInstance.required = true;

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

it('should be able to get placeholder of input', async () => {
const inputs = await loader.getAllHarnesses(inputHarness);
expect(inputs.length).toBe(3);
expect(inputs.length).toBe(5);
expect(await inputs[0].getPlaceholder()).toBe('Favorite food');
expect(await inputs[1].getPlaceholder()).toBe('');
expect(await inputs[2].getPlaceholder()).toBe('Leave a comment');
expect(await inputs[3].getPlaceholder()).toBe('Native control');
expect(await inputs[4].getPlaceholder()).toBe('');
});

it('should be able to get type of input', async () => {
const inputs = await loader.getAllHarnesses(inputHarness);
expect(inputs.length).toBe(3);
expect(inputs.length).toBe(5);
expect(await inputs[0].getType()).toBe('text');
expect(await inputs[1].getType()).toBe('number');
expect(await inputs[2].getType()).toBe('textarea');
expect(await inputs[3].getType()).toBe('text');
expect(await inputs[4].getType()).toBe('textarea');

fixture.componentInstance.inputType = 'text';

Expand Down Expand Up @@ -180,6 +202,24 @@ function getActiveElementTagName() {
<mat-form-field>
<textarea id="myTextarea" matInput placeholder="Leave a comment"></textarea>
</mat-form-field>

<mat-form-field>
<input matNativeControl placeholder="Native control" id="nativeControl">
</mat-form-field>

<mat-form-field>
<textarea matNativeControl></textarea>
</mat-form-field>

<mat-form-field>
<!--
Select native controls should not be handled as part of the input harness. We add this
to assert that the harness does not accidentally match it.
-->
<select matNativeControl>
<option value="first">First</option>
</select>
</mat-form-field>
`
})
class InputHarnessTest {
Expand Down