diff --git a/src/material-experimental/config.bzl b/src/material-experimental/config.bzl index eeae879e9d2f..498a95582e28 100644 --- a/src/material-experimental/config.bzl +++ b/src/material-experimental/config.bzl @@ -8,6 +8,7 @@ entryPoints = [ "mdc-chips", "mdc-chips/testing", "mdc-form-field", + "mdc-form-field/testing", "mdc-input", "mdc-list", "mdc-menu", diff --git a/src/material-experimental/mdc-form-field/testing/BUILD.bazel b/src/material-experimental/mdc-form-field/testing/BUILD.bazel new file mode 100644 index 000000000000..83718c20e105 --- /dev/null +++ b/src/material-experimental/mdc-form-field/testing/BUILD.bazel @@ -0,0 +1,59 @@ +package(default_visibility = ["//visibility:public"]) + +load("//tools:defaults.bzl", "ng_test_library", "ng_web_test_suite", "ts_library") + +ts_library( + name = "testing", + srcs = glob( + ["**/*.ts"], + exclude = ["**/*.spec.ts"], + ), + module_name = "@angular/material-experimental/mdc-form-field/testing", + deps = [ + "//src/cdk/testing", + "//src/material/form-field/testing", + "//src/material/form-field/testing/control", + "//src/material/input/testing", + "//src/material/select/testing", + ], +) + +filegroup( + name = "source-files", + srcs = glob(["**/*.ts"]), +) + +ng_test_library( + name = "unit_tests_lib", + srcs = glob( + ["**/*.spec.ts"], + exclude = ["shared.spec.ts"], + ), + deps = [ + ":testing", + "//src/cdk/overlay", + "//src/material-experimental/mdc-form-field", + "//src/material-experimental/mdc-input", + "//src/material/autocomplete", + "//src/material/core", + "//src/material/form-field/testing:harness_tests_lib", + "//src/material/input/testing", + "//src/material/select", + "//src/material/select/testing", + "@npm//@angular/common", + ], +) + +ng_web_test_suite( + name = "unit_tests", + static_files = [ + "@npm//:node_modules/@material/textfield/dist/mdc.textfield.js", + "@npm//:node_modules/@material/line-ripple/dist/mdc.lineRipple.js", + "@npm//:node_modules/@material/notched-outline/dist/mdc.notchedOutline.js", + "@npm//:node_modules/@material/floating-label/dist/mdc.floatingLabel.js", + ], + deps = [ + ":unit_tests_lib", + "//src/material-experimental:mdc_require_config.js", + ], +) diff --git a/src/material-experimental/mdc-form-field/testing/form-field-harness.spec.ts b/src/material-experimental/mdc-form-field/testing/form-field-harness.spec.ts new file mode 100644 index 000000000000..d03a84797556 --- /dev/null +++ b/src/material-experimental/mdc-form-field/testing/form-field-harness.spec.ts @@ -0,0 +1,38 @@ +import {OverlayModule} from '@angular/cdk/overlay'; +import {CommonModule} from '@angular/common'; +import {NgModule} from '@angular/core'; +import {MatFormFieldModule} from '@angular/material-experimental/mdc-form-field'; +import {MatInputModule} from '@angular/material-experimental/mdc-input'; +import {MatAutocompleteModule} from '@angular/material/autocomplete'; +import {MatCommonModule, MatOptionModule} from '@angular/material/core'; +import {MatInputHarness} from '@angular/material/input/testing'; +import { + MAT_SELECT_SCROLL_STRATEGY_PROVIDER, + MatSelect, + MatSelectTrigger +} from '@angular/material/select'; +import {MatSelectHarness} from '@angular/material/select/testing'; +import {runHarnessTests} from '@angular/material/form-field/testing/shared.spec'; +import {MatFormFieldHarness} from './form-field-harness'; + +// TODO: remove this once there is a `MatSelect` module which does not come +// with the form-field module provided. This is a copy of the `MatSelect` module +// that does not provide any form-field module. +@NgModule({ + imports: [CommonModule, OverlayModule, MatOptionModule, MatCommonModule], + exports: [MatSelect, MatSelectTrigger, MatOptionModule, MatCommonModule], + declarations: [MatSelect, MatSelectTrigger], + providers: [MAT_SELECT_SCROLL_STRATEGY_PROVIDER] +}) +export class SelectWithoutFormFieldModule { +} + +describe('MDC-based MatFormFieldHarness', () => { + runHarnessTests( + [MatFormFieldModule, MatAutocompleteModule, MatInputModule, SelectWithoutFormFieldModule], { + formFieldHarness: MatFormFieldHarness as any, + inputHarness: MatInputHarness, + selectHarness: MatSelectHarness, + isMdcImplementation: true, + }); +}); diff --git a/src/material-experimental/mdc-form-field/testing/form-field-harness.ts b/src/material-experimental/mdc-form-field/testing/form-field-harness.ts new file mode 100644 index 000000000000..d20ceaed7c56 --- /dev/null +++ b/src/material-experimental/mdc-form-field/testing/form-field-harness.ts @@ -0,0 +1,230 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import { + ComponentHarness, + ComponentHarnessConstructor, + HarnessPredicate, + HarnessQuery, + TestElement +} from '@angular/cdk/testing'; +import {FormFieldHarnessFilters} from '@angular/material/form-field/testing'; +import {MatFormFieldControlHarness} from '@angular/material/form-field/testing/control'; +import {MatInputHarness} from '@angular/material/input/testing'; +import {MatSelectHarness} from '@angular/material/select/testing'; + +// TODO(devversion): support datepicker harness once developed (COMP-203). +// Also support chip list harness. +/** Possible harnesses of controls which can be bound to a form-field. */ +export type FormFieldControlHarness = MatInputHarness|MatSelectHarness; + +/** Harness for interacting with a MDC-based form-field's in tests. */ +export class MatFormFieldHarness extends ComponentHarness { + static hostSelector = '.mat-mdc-form-field'; + + /** + * Gets a `HarnessPredicate` that can be used to search for a `MatFormFieldHarness` that meets + * certain criteria. + * @param options Options for filtering which form field instances are considered a match. + * @return a `HarnessPredicate` configured with the given options. + */ + static with(options: FormFieldHarnessFilters = {}): HarnessPredicate { + return new HarnessPredicate(MatFormFieldHarness, options) + .addOption( + 'floatingLabelText', options.floatingLabelText, + async (harness, text) => HarnessPredicate.stringMatches(await harness.getLabel(), text)) + .addOption( + 'hasErrors', options.hasErrors, + async (harness, hasErrors) => await harness.hasErrors() === hasErrors); + } + + private _mdcTextField = this.locatorFor('.mat-mdc-text-field-wrapper'); + + private _prefixContainer = this.locatorForOptional('.mat-mdc-form-field-prefix'); + private _suffixContainer = this.locatorForOptional('.mat-mdc-form-field-suffix'); + private _label = this.locatorForOptional('.mdc-floating-label'); + private _errors = this.locatorForAll('.mat-mdc-form-field-error'); + private _hints = this.locatorForAll('.mat-mdc-form-field-hint'); + + private _inputControl = this.locatorForOptional(MatInputHarness); + private _selectControl = this.locatorForOptional(MatSelectHarness); + + /** Gets the appearance of the form-field. */ + async getAppearance(): Promise<'fill'|'outline'> { + const textFieldEl = await this._mdcTextField(); + if (await textFieldEl.hasClass('mdc-text-field--outlined')) { + return 'outline'; + } + return 'fill'; + } + + /** + * Gets the harness of the control that is bound to the form-field. Only + * default controls such as "MatInputHarness" and "MatSelectHarness" are + * supported. + */ + async getControl(): Promise; + + /** + * Gets the harness of the control that is bound to the form-field. Searches + * for a control that matches the specified harness type. + */ + async getControl(type: ComponentHarnessConstructor): + Promise; + + /** + * Gets the harness of the control that is bound to the form-field. Searches + * for a control that matches the specified harness predicate. + */ + async getControl(type: HarnessPredicate): + Promise; + + // Implementation of the "getControl" method overload signatures. + async getControl(type?: HarnessQuery) { + if (type) { + return this.locatorForOptional(type)(); + } + const hostEl = await this.host(); + const [isInput, isSelect] = await Promise.all([ + hostEl.hasClass('mat-mdc-form-field-type-mat-input'), + hostEl.hasClass('mat-mdc-form-field-type-mat-select'), + ]); + if (isInput) { + return this._inputControl(); + } else if (isSelect) { + return this._selectControl(); + } + return null; + } + + /** Whether the form-field has a label. */ + async hasLabel(): Promise { + return (await this._label()) !== null; + } + + /** Gets the label of the form-field. */ + async getLabel(): Promise { + const labelEl = await this._label(); + return labelEl ? labelEl.text() : null; + } + + /** Whether the form-field has errors. */ + async hasErrors(): Promise { + return (await this.getTextErrors()).length > 0; + } + + /** Whether the label is currently floating. */ + async isLabelFloating(): Promise { + const labelEl = await this._label(); + return labelEl !== null ? await labelEl.hasClass('mdc-floating-label--float-above') : false; + } + + /** Whether the form-field is disabled. */ + async isDisabled(): Promise { + return (await this.host()).hasClass('mat-form-field-disabled'); + } + + /** Whether the form-field is currently autofilled. */ + async isAutofilled(): Promise { + return (await this.host()).hasClass('mat-form-field-autofilled'); + } + + /** Gets the theme color of the form-field. */ + async getThemeColor(): Promise<'primary'|'accent'|'warn'> { + const hostEl = await this.host(); + const [isAccent, isWarn] = + await Promise.all([hostEl.hasClass('mat-accent'), hostEl.hasClass('mat-warn')]); + if (isAccent) { + return 'accent'; + } else if (isWarn) { + return 'warn'; + } + return 'primary'; + } + + /** Gets error messages which are currently displayed in the form-field. */ + async getTextErrors(): Promise { + return Promise.all((await this._errors()).map(e => e.text())); + } + + /** Gets hint messages which are currently displayed in the form-field. */ + async getTextHints(): Promise { + return Promise.all((await this._hints()).map(e => e.text())); + } + + /** + * Gets a reference to the container element which contains all projected + * prefixes of the form-field. + */ + async getHarnessLoaderForPrefix(): Promise { + return this._prefixContainer(); + } + + /** + * Gets a reference to the container element which contains all projected + * suffixes of the form-field. + */ + async getHarnessLoaderForSuffix(): Promise { + return this._suffixContainer(); + } + + /** + * Whether the form control has been touched. Returns "null" + * if no form control is set up. + */ + async isControlTouched(): Promise { + if (!await this._hasFormControl()) { + return null; + } + return (await this.host()).hasClass('ng-touched'); + } + + /** + * Whether the form control is dirty. Returns "null" + * if no form control is set up. + */ + async isControlDirty(): Promise { + if (!await this._hasFormControl()) { + return null; + } + return (await this.host()).hasClass('ng-dirty'); + } + + /** + * Whether the form control is valid. Returns "null" + * if no form control is set up. + */ + async isControlValid(): Promise { + if (!await this._hasFormControl()) { + return null; + } + return (await this.host()).hasClass('ng-valid'); + } + + /** + * Whether the form control is pending validation. Returns "null" + * if no form control is set up. + */ + async isControlPending(): Promise { + if (!await this._hasFormControl()) { + return null; + } + return (await this.host()).hasClass('ng-pending'); + } + + /** Checks whether the form-field control has set up a form control. */ + private async _hasFormControl(): Promise { + const hostEl = await this.host(); + // If no form "NgControl" is bound to the form-field control, the form-field + // is not able to forward any control status classes. Therefore if either the + // "ng-touched" or "ng-untouched" class is set, we know that it has a form control + const [isTouched, isUntouched] = + await Promise.all([hostEl.hasClass('ng-touched'), hostEl.hasClass('ng-untouched')]); + return isTouched || isUntouched; + } +} diff --git a/src/material-experimental/mdc-form-field/testing/index.ts b/src/material-experimental/mdc-form-field/testing/index.ts new file mode 100644 index 000000000000..676ca90f1ffa --- /dev/null +++ b/src/material-experimental/mdc-form-field/testing/index.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +export * from './public-api'; diff --git a/src/material-experimental/mdc-form-field/testing/public-api.ts b/src/material-experimental/mdc-form-field/testing/public-api.ts new file mode 100644 index 000000000000..3c64d4b8540c --- /dev/null +++ b/src/material-experimental/mdc-form-field/testing/public-api.ts @@ -0,0 +1,15 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +// Re-export everything from the "form-field/testing/control" entry-point. To avoid +// circular dependencies, harnesses for default form-field controls (i.e. input, select) +// need to import the base form-field control harness through a separate entry-point. +export * from '@angular/material/form-field/testing/control'; + +export {FormFieldHarnessFilters} from '@angular/material/form-field/testing'; +export * from './form-field-harness'; diff --git a/src/material/form-field/testing/form-field-harness.spec.ts b/src/material/form-field/testing/form-field-harness.spec.ts index 327102532604..7ce1d0d18068 100644 --- a/src/material/form-field/testing/form-field-harness.spec.ts +++ b/src/material/form-field/testing/form-field-harness.spec.ts @@ -1,15 +1,18 @@ -import {MatInputHarness} from '@angular/material/input/testing'; -import {MatSelectHarness} from '@angular/material/select/testing'; import {MatAutocompleteModule} from '@angular/material/autocomplete'; import {MatFormFieldModule} from '@angular/material/form-field'; import {MatInputModule} from '@angular/material/input'; +import {MatInputHarness} from '@angular/material/input/testing'; import {MatSelectModule} from '@angular/material/select'; +import {MatSelectHarness} from '@angular/material/select/testing'; import {MatFormFieldHarness} from './form-field-harness'; import {runHarnessTests} from './shared.spec'; describe('Non-MDC-based MatFormFieldHarness', () => { - runHarnessTests( - [MatFormFieldModule, MatAutocompleteModule, MatInputModule, MatSelectModule], - MatFormFieldHarness, MatInputHarness, MatSelectHarness); + runHarnessTests([MatFormFieldModule, MatAutocompleteModule, MatInputModule, MatSelectModule], { + formFieldHarness: MatFormFieldHarness, + inputHarness: MatInputHarness, + selectHarness: MatSelectHarness, + isMdcImplementation: false, + }); }); diff --git a/src/material/form-field/testing/form-field-harness.ts b/src/material/form-field/testing/form-field-harness.ts index 93162b46025f..3fba566c2ef1 100644 --- a/src/material/form-field/testing/form-field-harness.ts +++ b/src/material/form-field/testing/form-field-harness.ts @@ -113,11 +113,6 @@ export class MatFormFieldHarness extends ComponentHarness { return labelEl ? labelEl.text() : null; } - /** Whether the form-field has a floating label. */ - async hasFloatingLabel(): Promise { - return (await this.host()).hasClass('mat-form-field-can-float'); - } - /** Whether the form-field has errors. */ async hasErrors(): Promise { return (await this.getTextErrors()).length > 0; @@ -125,7 +120,13 @@ export class MatFormFieldHarness extends ComponentHarness { /** Whether the label is currently floating. */ async isLabelFloating(): Promise { - return (await this.host()).hasClass('mat-form-field-should-float'); + const [hasLabel, shouldFloat] = await Promise.all([ + this.hasLabel(), + (await this.host()).hasClass('mat-form-field-should-float'), + ]); + // If there is no label, the label conceptually can never float. The `should-float` class + // is just always set regardless of whether the label is displayed or not. + return hasLabel && shouldFloat; } /** Whether the form-field is disabled. */ diff --git a/src/material/form-field/testing/shared.spec.ts b/src/material/form-field/testing/shared.spec.ts index f43881800720..249d331ca34b 100644 --- a/src/material/form-field/testing/shared.spec.ts +++ b/src/material/form-field/testing/shared.spec.ts @@ -1,8 +1,4 @@ -import { - ComponentHarness, - HarnessLoader, - HarnessPredicate -} from '@angular/cdk/testing'; +import {ComponentHarness, HarnessLoader, HarnessPredicate} from '@angular/cdk/testing'; import { createFakeEvent, dispatchFakeEvent, @@ -16,8 +12,12 @@ import {MatFormFieldHarness} from './form-field-harness'; /** Shared tests to run on both the original and MDC-based form-field's. */ export function runHarnessTests( - modules: Type[], formFieldHarness: typeof MatFormFieldHarness, inputHarness: Type, - selectHarness: Type) { + modules: Type[], {formFieldHarness, inputHarness, selectHarness, isMdcImplementation}: { + formFieldHarness: typeof MatFormFieldHarness, + inputHarness: Type, + selectHarness: Type, + isMdcImplementation: boolean + }) { let fixture: ComponentFixture; let loader: HarnessLoader; @@ -36,7 +36,7 @@ export function runHarnessTests( it('should be able to load harnesses', async () => { const formFields = await loader.getAllHarnesses(formFieldHarness); - expect(formFields.length).toBe(4); + expect(formFields.length).toBe(5); }); it('should be able to load form-field that matches specific selector', async () => { @@ -48,10 +48,11 @@ export function runHarnessTests( it('should be able to get appearance of form-field', async () => { const formFields = await loader.getAllHarnesses(formFieldHarness); - expect(await formFields[0].getAppearance()).toBe('legacy'); - expect(await formFields[1].getAppearance()).toBe('standard'); + expect(await formFields[0].getAppearance()).toBe(isMdcImplementation ? 'fill' : 'legacy'); + expect(await formFields[1].getAppearance()).toBe(isMdcImplementation ? 'fill' : 'standard'); expect(await formFields[2].getAppearance()).toBe('fill'); expect(await formFields[3].getAppearance()).toBe('outline'); + expect(await formFields[4].getAppearance()).toBe(isMdcImplementation ? 'fill' : 'legacy'); }); it('should be able to get control of form-field', async () => { @@ -60,6 +61,7 @@ export function runHarnessTests( expect(await formFields[1].getControl() instanceof inputHarness).toBe(true); expect(await formFields[2].getControl() instanceof selectHarness).toBe(true); expect(await formFields[3].getControl() instanceof inputHarness).toBe(true); + expect(await formFields[4].getControl() instanceof inputHarness).toBe(true); }); it('should be able to get custom control of form-field', async () => { @@ -69,6 +71,7 @@ export function runHarnessTests( .toBe(true); expect(await formFields[2].getControl(CustomControlHarness)).toBe(null); expect(await formFields[3].getControl(CustomControlHarness)).toBe(null); + expect(await formFields[4].getControl(CustomControlHarness)).toBe(null); }); it('should be able to get custom control of form-field using a predicate', async () => { @@ -78,39 +81,34 @@ export function runHarnessTests( expect(await formFields[1].getControl(predicate) instanceof CustomControlHarness).toBe(true); expect(await formFields[2].getControl(predicate)).toBe(null); expect(await formFields[3].getControl(predicate)).toBe(null); + expect(await formFields[4].getControl(predicate)).toBe(null); }); it('should be able to check whether form-field has label', async () => { const formFields = await loader.getAllHarnesses(formFieldHarness); - expect(await formFields[0].hasLabel()).toBe(true); + // The non MDC-based form-field elevates the placeholder to a floating + // label. This is not the case in the MDC-based implementation. + expect(await formFields[0].hasLabel()).toBe(!isMdcImplementation); expect(await formFields[1].hasLabel()).toBe(false); expect(await formFields[2].hasLabel()).toBe(true); expect(await formFields[3].hasLabel()).toBe(true); - - fixture.componentInstance.hasLabel = true; - expect(await formFields[1].hasLabel()).toBe(true); - }); - - it('should be able to check whether form-field has floating label', async () => { - const formFields = await loader.getAllHarnesses(formFieldHarness); - expect(await formFields[0].hasFloatingLabel()).toBe(false); - expect(await formFields[1].hasFloatingLabel()).toBe(true); - expect(await formFields[2].hasFloatingLabel()).toBe(true); - expect(await formFields[3].hasFloatingLabel()).toBe(true); - - fixture.componentInstance.shouldLabelFloat = 'auto'; - expect(await formFields[0].hasFloatingLabel()).toBe(true); + expect(await formFields[4].hasLabel()).toBe(true); }); it('should be able to check whether label is floating', async () => { const formFields = await loader.getAllHarnesses(formFieldHarness); - expect(await formFields[0].isLabelFloating()).toBe(false); - expect(await formFields[1].isLabelFloating()).toBe(true); + // The first form-field uses the legacy appearance. This means that the + // placeholder will be elevated to a label. Also since there is a static + // value, the label will float initially. The MDC implementation does not + // elevate placeholders to floating labels. + expect(await formFields[0].isLabelFloating()).toBe(!isMdcImplementation); + expect(await formFields[1].isLabelFloating()).toBe(false); expect(await formFields[2].isLabelFloating()).toBe(false); expect(await formFields[3].isLabelFloating()).toBe(true); + expect(await formFields[4].isLabelFloating()).toBe(false); fixture.componentInstance.shouldLabelFloat = 'always'; - expect(await formFields[0].hasFloatingLabel()).toBe(true); + expect(await formFields[4].isLabelFloating()).toBe(true); }); it('should be able to check whether form-field is disabled', async () => { @@ -119,12 +117,14 @@ export function runHarnessTests( expect(await formFields[1].isDisabled()).toBe(false); expect(await formFields[2].isDisabled()).toBe(false); expect(await formFields[3].isDisabled()).toBe(false); + expect(await formFields[4].isDisabled()).toBe(false); fixture.componentInstance.isDisabled = true; expect(await formFields[0].isDisabled()).toBe(true); expect(await formFields[1].isDisabled()).toBe(false); expect(await formFields[2].isDisabled()).toBe(true); expect(await formFields[3].isDisabled()).toBe(false); + expect(await formFields[4].isDisabled()).toBe(false); }); it('should be able to check whether form-field is auto-filled', async () => { @@ -133,6 +133,7 @@ export function runHarnessTests( expect(await formFields[1].isAutofilled()).toBe(false); expect(await formFields[2].isAutofilled()).toBe(false); expect(await formFields[3].isAutofilled()).toBe(false); + expect(await formFields[4].isAutofilled()).toBe(false); const autofillTriggerEvent: any = createFakeEvent('animationstart'); autofillTriggerEvent.animationName = 'cdk-text-field-autofill-start'; @@ -146,6 +147,7 @@ export function runHarnessTests( expect(await formFields[1].isAutofilled()).toBe(false); expect(await formFields[2].isAutofilled()).toBe(false); expect(await formFields[3].isAutofilled()).toBe(false); + expect(await formFields[4].isAutofilled()).toBe(false); }); it('should be able to get theme color of form-field', async () => { @@ -154,14 +156,18 @@ export function runHarnessTests( expect(await formFields[1].getThemeColor()).toBe('warn'); expect(await formFields[2].getThemeColor()).toBe('accent'); expect(await formFields[3].getThemeColor()).toBe('primary'); + expect(await formFields[4].getThemeColor()).toBe('primary'); }); it('should be able to get label of form-field', async () => { const formFields = await loader.getAllHarnesses(formFieldHarness); - expect(await formFields[0].getLabel()).toBe('With placeholder'); + // In the MDC based implementation, the placeholder will not be elevated + // to a label, and the harness will return `null`. + expect(await formFields[0].getLabel()).toBe(isMdcImplementation ? null : 'With placeholder'); expect(await formFields[1].getLabel()).toBe(null); expect(await formFields[2].getLabel()).toBe('Label'); expect(await formFields[3].getLabel()).toBe('autocomplete_label'); + expect(await formFields[4].getLabel()).toBe('Label'); }); it('should be able to get error messages of form-field', async () => { @@ -250,7 +256,6 @@ export function runHarnessTests( Custom control harness - Second input label Error 1 @@ -274,11 +279,16 @@ export function runHarnessTests( autocomplete_option + + + Label + + ` }) class FormFieldHarnessTest { requiredControl = new FormControl('Initial value', [Validators.required]); - shouldLabelFloat: 'never'|'auto'|'always' = 'never'; + shouldLabelFloat: 'always'|'auto' = 'auto'; hasLabel = false; isDisabled = false; diff --git a/tools/public_api_guard/material/form-field/testing.d.ts b/tools/public_api_guard/material/form-field/testing.d.ts index 3378166e4e59..959952cf82f8 100644 --- a/tools/public_api_guard/material/form-field/testing.d.ts +++ b/tools/public_api_guard/material/form-field/testing.d.ts @@ -17,7 +17,6 @@ export declare class MatFormFieldHarness extends ComponentHarness { getTextHints(): Promise; getThemeColor(): Promise<'primary' | 'accent' | 'warn'>; hasErrors(): Promise; - hasFloatingLabel(): Promise; hasLabel(): Promise; isAutofilled(): Promise; isControlDirty(): Promise;