Skip to content

feat(select,input,form-field): move test harnesses out of experimental #17874

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 1 commit into from
Dec 10, 2019
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
3 changes: 0 additions & 3 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@

# Material experimental package
/src/material-experimental/* @jelbourn
/src/material-experimental/input/** @devversion
/src/material-experimental/form-field/** @devversion
/src/material-experimental/mdc-autocomplete/** @crisbeto
/src/material-experimental/mdc-button/** @andrewseguin
/src/material-experimental/mdc-card/** @mmalerba
Expand All @@ -112,7 +110,6 @@
/src/material-experimental/mdc-theming/** @mmalerba
/src/material-experimental/mdc-typography/** @mmalerba
/src/material-experimental/popover-edit/** @kseamon @andrewseguin
/src/material-experimental/select/** @crisbeto

# CDK experimental package
/src/cdk-experimental/* @jelbourn
Expand Down
6 changes: 1 addition & 5 deletions src/material-experimental/config.bzl
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
entryPoints = [
"form-field/testing",
"form-field/testing/control",
"input/testing",
"mdc-autocomplete",
"mdc-button",
"mdc-button/testing",
Expand All @@ -22,14 +19,13 @@ entryPoints = [
"mdc-slider",
"mdc-tabs",
"popover-edit",
"select/testing",
]

# List of all non-testing entry-points of the Angular material-experimental package.
MATERIAL_EXPERIMENTAL_ENTRYPOINTS = [
ep
for ep in entryPoints
if not ep.endswith("/testing")
if not "/testing" in ep
]

# List of all testing entry-points of the Angular material-experimental package.
Expand Down
6 changes: 5 additions & 1 deletion src/material/config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,17 @@ entryPoints = [
"toolbar",
"tooltip",
"tree",
"form-field/testing",
"form-field/testing/control",
"input/testing",
"select/testing",
]

# List of all non-testing entry-points of the Angular Material package.
MATERIAL_ENTRYPOINTS = [
ep
for ep in entryPoints
if not ep.endswith("/testing")
if not "/testing" in ep
]

# List of all testing entry-points of the Angular Material package.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,20 @@ ts_library(
["**/*.ts"],
exclude = ["**/*.spec.ts"],
),
module_name = "@angular/material-experimental/form-field/testing",
module_name = "@angular/material/form-field/testing",
deps = [
"//src/cdk/testing",
"//src/material-experimental/form-field/testing/control",
"//src/material-experimental/input/testing",
"//src/material-experimental/select/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 = "harness_tests_lib",
srcs = ["shared.spec.ts"],
Expand All @@ -39,12 +44,12 @@ ng_test_library(
deps = [
":harness_tests_lib",
":testing",
"//src/material-experimental/input/testing",
"//src/material-experimental/select/testing",
"//src/material/autocomplete",
"//src/material/form-field",
"//src/material/input",
"//src/material/input/testing",
"//src/material/select",
"//src/material/select/testing",
],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ load("//tools:defaults.bzl", "ts_library")
ts_library(
name = "control",
srcs = glob(["**/*.ts"]),
module_name = "@angular/material-experimental/form-field/testing/control",
module_name = "@angular/material/form-field/testing/control",
deps = ["//src/cdk/testing"],
)

filegroup(
name = "source-files",
srcs = glob(["**/*.ts"]),
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,10 @@

import {BaseHarnessFilters} from '@angular/cdk/testing';

export interface FormFieldHarnessFilters extends BaseHarnessFilters {}
/** A set of criteria that can be used to filter a list of `MatFormFieldHarness` instances. */
export interface FormFieldHarnessFilters extends BaseHarnessFilters {
/** Filters based on the text of the form field's floating label. */
floatingLabelText?: string | RegExp;
/** Filters based on whether the form field has error messages. */
hasErrors?: boolean;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {MatInputHarness} from '@angular/material-experimental/input/testing';
import {MatSelectHarness} from '@angular/material-experimental/select/testing';
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';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ import {
HarnessQuery,
TestElement
} from '@angular/cdk/testing';
import {
MatFormFieldControlHarness
} from '@angular/material-experimental/form-field/testing/control';
import {MatInputHarness} from '@angular/material-experimental/input/testing';
import {MatSelectHarness} from '@angular/material-experimental/select/testing';
import {MatFormFieldControlHarness} from '@angular/material/form-field/testing/control';
import {MatInputHarness} from '@angular/material/input/testing';
import {MatSelectHarness} from '@angular/material/select/testing';
import {FormFieldHarnessFilters} from './form-field-harness-filters';

// TODO(devversion): support datepicker harness once developed (COMP-203).
Expand All @@ -30,21 +28,24 @@ export class MatFormFieldHarness extends ComponentHarness {
static hostSelector = '.mat-form-field';

/**
* Gets a `HarnessPredicate` that can be used to search for an form-field with
* specific attributes.
* @param options Options for narrowing the search:
* - `selector` finds a form-field that matches the given selector.
* 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<MatFormFieldHarness> {
return new HarnessPredicate(MatFormFieldHarness, options);
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 _prefixContainer = this.locatorForOptional('.mat-form-field-prefix');
private _suffixContainer = this.locatorForOptional('.mat-form-field-suffix');
private _label = this.locatorForOptional('.mat-form-field-label');
private _errors = this.locatorForAll('.mat-error');
private _hints = this.locatorForAll('mat-hint,.mat-hint');
private _hints = this.locatorForAll('mat-hint, .mat-hint');

private _inputControl = this.locatorForOptional(MatInputHarness);
private _selectControl = this.locatorForOptional(MatSelectHarness);
Expand Down Expand Up @@ -117,6 +118,11 @@ export class MatFormFieldHarness extends ComponentHarness {
return (await this.host()).hasClass('mat-form-field-can-float');
}

/** Whether the form-field has errors. */
async hasErrors(): Promise<boolean> {
return (await this.getTextErrors()).length > 0;
}

/** Whether the label is currently floating. */
async isLabelFloating(): Promise<boolean> {
return (await this.host()).hasClass('mat-form-field-should-float');
Expand Down Expand Up @@ -146,28 +152,28 @@ export class MatFormFieldHarness extends ComponentHarness {
}

/** Gets error messages which are currently displayed in the form-field. */
async getErrorMessages(): Promise<string[]> {
async getTextErrors(): Promise<string[]> {
return Promise.all((await this._errors()).map(e => e.text()));
}

/** Gets hint messages which are currently displayed in the form-field. */
async getHintMessages(): Promise<string[]> {
async getTextHints(): Promise<string[]> {
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 getPrefixContainer(): Promise<TestElement|null> {
async getHarnessLoaderForPrefix(): Promise<TestElement|null> {
return this._prefixContainer();
}

/**
* Gets a reference to the container element which contains all projected
* suffixes of the form-field.
*/
async getSuffixContainer(): Promise<TestElement|null> {
async getHarnessLoaderForSuffix(): Promise<TestElement|null> {
return this._suffixContainer();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// 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-experimental/form-field/testing/control';
export * from '@angular/material/form-field/testing/control';

export * from './form-field-harness';
export * from './form-field-harness-filters';
Original file line number Diff line number Diff line change
Expand Up @@ -166,33 +166,33 @@ export function runHarnessTests(

it('should be able to get error messages of form-field', async () => {
const formFields = await loader.getAllHarnesses(formFieldHarness);
expect(await formFields[1].getErrorMessages()).toEqual([]);
expect(await formFields[1].getTextErrors()).toEqual([]);

fixture.componentInstance.requiredControl.setValue('');
dispatchFakeEvent(fixture.nativeElement.querySelector('#with-errors input'), 'blur');
expect(await formFields[1].getErrorMessages()).toEqual(['Error 1', 'Error 2']);
expect(await formFields[1].getTextErrors()).toEqual(['Error 1', 'Error 2']);
});

it('should be able to get hint messages of form-field', async () => {
const formFields = await loader.getAllHarnesses(formFieldHarness);
expect(await formFields[1].getHintMessages()).toEqual(['Hint 1', 'Hint 2']);
expect(await formFields[1].getTextHints()).toEqual(['Hint 1', 'Hint 2']);

fixture.componentInstance.requiredControl.setValue('');
dispatchFakeEvent(fixture.nativeElement.querySelector('#with-errors input'), 'blur');
expect(await formFields[1].getHintMessages()).toEqual([]);
expect(await formFields[1].getTextHints()).toEqual([]);
});

it('should be able to get prefix container of form-field', async () => {
const formFields = await loader.getAllHarnesses(formFieldHarness);
const prefixContainers = await Promise.all(formFields.map(f => f.getPrefixContainer()));
const prefixContainers = await Promise.all(formFields.map(f => f.getHarnessLoaderForPrefix()));
expect(prefixContainers[0]).not.toBe(null);
expect(await prefixContainers[0]!.text()).toBe('prefix_textprefix_text_2');
expect(prefixContainers[1]).toBe(null);
});

it('should be able to get suffix container of form-field', async () => {
const formFields = await loader.getAllHarnesses(formFieldHarness);
const suffixContainer = await Promise.all(formFields.map(f => f.getSuffixContainer()));
const suffixContainer = await Promise.all(formFields.map(f => f.getHarnessLoaderForSuffix()));
expect(suffixContainer[0]).not.toBe(null);
expect(await suffixContainer[0]!.text()).toBe('suffix_text');
expect(suffixContainer[1]).toBe(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ ts_library(
["**/*.ts"],
exclude = ["**/*.spec.ts"],
),
module_name = "@angular/material-experimental/input/testing",
module_name = "@angular/material/input/testing",
deps = [
"//src/cdk/coercion",
"//src/cdk/testing",
"//src/material-experimental/form-field/testing/control",
"//src/material/form-field/testing/control",
],
)

filegroup(
name = "source-files",
srcs = glob(["**/*.ts"]),
)

ng_test_library(
name = "harness_tests_lib",
srcs = ["shared.spec.ts"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

import {BaseHarnessFilters} from '@angular/cdk/testing';

/** A set of criteria that can be used to filter a list of `MatInputHarness` instances. */
export interface InputHarnessFilters extends BaseHarnessFilters {
value?: string;
/** Filters based on the value of the input. */
value?: string | RegExp;
/** Filters based on the placeholder text of the input. */
placeholder?: string | RegExp;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,27 @@
*/

import {HarnessPredicate} from '@angular/cdk/testing';
import {
MatFormFieldControlHarness
} from '@angular/material-experimental/form-field/testing/control';
import {MatFormFieldControlHarness} from '@angular/material/form-field/testing/control';
import {InputHarnessFilters} from './input-harness-filters';

/** Harness for interacting with a standard Material inputs in tests. */
export class MatInputHarness extends MatFormFieldControlHarness {
static hostSelector = '[matInput]';

/**
* Gets a `HarnessPredicate` that can be used to search for an input with
* specific attributes.
* @param options Options for narrowing the search:
* - `name` finds an input with specific name.
* - `id` finds an input with specific id.
* - `value` finds an input with specific value.
* Gets a `HarnessPredicate` that can be used to search for a `MatInputHarness` that meets
* certain criteria.
* @param options Options for filtering which input instances are considered a match.
* @return a `HarnessPredicate` configured with the given options.
*/
static with(options: InputHarnessFilters = {}): HarnessPredicate<MatInputHarness> {
return new HarnessPredicate(MatInputHarness, options)
.addOption(
'value', options.value, async (harness, value) => (await harness.getValue()) === value);
.addOption('value', options.value, async (harness, value) => {
return (await harness.getValue()) === value;
})
.addOption('placeholder', options.placeholder, async (harness, placeholder) => {
return (await harness.getPlaceholder()) === placeholder;
});
}

/** Whether the input is disabled. */
Expand Down Expand Up @@ -67,7 +66,7 @@ export class MatInputHarness extends MatFormFieldControlHarness {
return (await (await this.host()).getProperty('type'))!;
}

/** Gets the placeholder of the input. / */
/** Gets the placeholder of the input. */
async getPlaceholder(): Promise<string> {
// The "placeholder" property of the native input is never undefined.
return (await (await this.host()).getProperty('placeholder'))!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ ts_library(
["**/*.ts"],
exclude = ["**/*.spec.ts"],
),
module_name = "@angular/material-experimental/select/testing",
module_name = "@angular/material/select/testing",
deps = [
"//src/cdk/coercion",
"//src/cdk/testing",
"//src/material-experimental/form-field/testing/control",
"//src/material/form-field/testing/control",
],
)

filegroup(
name = "source-files",
srcs = glob(["**/*.ts"]),
)

ng_test_library(
name = "harness_tests_lib",
srcs = ["shared.spec.ts"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@

import {BaseHarnessFilters} from '@angular/cdk/testing';

/** A set of criteria that can be used to filter a list of `MatSelectHarness` instances. */
export interface SelectHarnessFilters extends BaseHarnessFilters {}
Loading