From 4abc82fa5ec86d4f0cb184f65019963c83a5e8ce Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Mon, 20 Jan 2020 10:42:09 +0100 Subject: [PATCH 1/3] 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. --- src/material/input/testing/input-harness.ts | 2 +- src/material/input/testing/shared.spec.ts | 35 +++++++++++++++------ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/material/input/testing/input-harness.ts b/src/material/input/testing/input-harness.ts index ce982f6119e0..257d78b98b17 100644 --- a/src/material/input/testing/input-harness.ts +++ b/src/material/input/testing/input-harness.ts @@ -12,7 +12,7 @@ import {InputHarnessFilters} from './input-harness-filters'; /** Harness for interacting with a standard Material inputs in tests. */ export class MatInputHarness extends MatFormFieldControlHarness { - static hostSelector = '[matInput]'; + static hostSelector = '.mat-input-element'; /** * Gets a `HarnessPredicate` that can be used to search for a `MatInputHarness` that meets diff --git a/src/material/input/testing/shared.spec.ts b/src/material/input/testing/shared.spec.ts index 058720daf0a7..e52bb2ff84db 100644 --- a/src/material/input/testing/shared.spec.ts +++ b/src/material/input/testing/shared.spec.ts @@ -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(4); }); it('should load input with specific id', async () => { @@ -49,48 +49,55 @@ 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(4); 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'); }); 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(4); 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(''); }); 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(4); 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(''); }); 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(4); expect(await inputs[0].getValue()).toBe('Sushi'); expect(await inputs[1].getValue()).toBe(''); + expect(await inputs[3].getValue()).toBe(''); await inputs[0].setValue(''); await inputs[2].setValue('new-value'); + await inputs[3].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'); }); it('should be able to get disabled state', async () => { const inputs = await loader.getAllHarnesses(inputHarness); - expect(inputs.length).toBe(3); + expect(inputs.length).toBe(4); 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); fixture.componentInstance.disabled = true; @@ -99,11 +106,12 @@ 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(4); 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); fixture.componentInstance.readonly = true; @@ -112,11 +120,12 @@ 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(4); 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); fixture.componentInstance.required = true; @@ -125,18 +134,20 @@ 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(4); 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'); }); 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(4); 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'); fixture.componentInstance.inputType = 'text'; @@ -180,6 +191,10 @@ function getActiveElementTagName() { + + + + ` }) class InputHarnessTest { From 5c3296fe55a46e3daaa2e5e46147a942a72516c5 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Thu, 23 Jan 2020 10:04:09 +0100 Subject: [PATCH 2/3] fixup! fix(material/input): input harness selector not matching `matNativeControl` Address feedback --- src/material/input/testing/input-harness.ts | 5 ++++- src/material/input/testing/shared.spec.ts | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/material/input/testing/input-harness.ts b/src/material/input/testing/input-harness.ts index 257d78b98b17..578e18cf9da5 100644 --- a/src/material/input/testing/input-harness.ts +++ b/src/material/input/testing/input-harness.ts @@ -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 = '.mat-input-element'; + // 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]'; /** * Gets a `HarnessPredicate` that can be used to search for a `MatInputHarness` that meets diff --git a/src/material/input/testing/shared.spec.ts b/src/material/input/testing/shared.spec.ts index e52bb2ff84db..ef05c9bdc61e 100644 --- a/src/material/input/testing/shared.spec.ts +++ b/src/material/input/testing/shared.spec.ts @@ -195,6 +195,16 @@ function getActiveElementTagName() { + + + + + ` }) class InputHarnessTest { From 1885af5008f94cd62aadd5b974c93036ca803b4a Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Thu, 23 Jan 2020 21:18:11 +0100 Subject: [PATCH 3/3] fixup! fixup! fix(material/input): input harness selector not matching `matNativeControl` Address feedback --- src/material/input/testing/input-harness.ts | 2 +- src/material/input/testing/shared.spec.ts | 35 +++++++++++++++------ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/material/input/testing/input-harness.ts b/src/material/input/testing/input-harness.ts index 578e18cf9da5..c74ea2476bae 100644 --- a/src/material/input/testing/input-harness.ts +++ b/src/material/input/testing/input-harness.ts @@ -15,7 +15,7 @@ export class MatInputHarness extends MatFormFieldControlHarness { // 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]'; + static hostSelector = '[matInput], input[matNativeControl], textarea[matNativeControl]'; /** * Gets a `HarnessPredicate` that can be used to search for a `MatInputHarness` that meets diff --git a/src/material/input/testing/shared.spec.ts b/src/material/input/testing/shared.spec.ts index ef05c9bdc61e..0a405f88520d 100644 --- a/src/material/input/testing/shared.spec.ts +++ b/src/material/input/testing/shared.spec.ts @@ -28,7 +28,7 @@ export function runHarnessTests( it('should load all input harnesses', async () => { const inputs = await loader.getAllHarnesses(inputHarness); - expect(inputs.length).toBe(4); + expect(inputs.length).toBe(5); }); it('should load input with specific id', async () => { @@ -49,55 +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(4); + 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(4); + 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(4); + 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(4); + 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(4); + 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; @@ -106,12 +113,13 @@ export function runHarnessTests( it('should be able to get readonly state', async () => { const inputs = await loader.getAllHarnesses(inputHarness); - expect(inputs.length).toBe(4); + 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; @@ -120,12 +128,13 @@ export function runHarnessTests( it('should be able to get required state', async () => { const inputs = await loader.getAllHarnesses(inputHarness); - expect(inputs.length).toBe(4); + 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; @@ -134,20 +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(4); + 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(4); + 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'; @@ -196,6 +207,10 @@ function getActiveElementTagName() { + + + +