Skip to content

feat(button-toggle): add test harness #17996

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 19, 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
57 changes: 57 additions & 0 deletions src/material/button-toggle/testing/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
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/button-toggle/testing",
deps = [
"//src/cdk/coercion",
"//src/cdk/testing",
"//src/material/button-toggle",
],
)

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

ng_test_library(
name = "harness_tests_lib",
srcs = [
"button-toggle-group-shared.spec.ts",
"button-toggle-shared.spec.ts",
],
deps = [
":testing",
"//src/cdk/testing",
"//src/cdk/testing/testbed",
"//src/material/button-toggle",
],
)

ng_test_library(
name = "unit_tests_lib",
srcs = glob(
["**/*.spec.ts"],
exclude = [
"button-toggle-shared.spec.ts",
"button-toggle-group-shared.spec.ts",
],
),
deps = [
":harness_tests_lib",
":testing",
"//src/material/button-toggle",
],
)

ng_web_test_suite(
name = "unit_tests",
deps = [":unit_tests_lib"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* @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 {BaseHarnessFilters} from '@angular/cdk/testing';

/** Criteria that can be used to filter a list of `MatButtonToggleGroupHarness` instances. */
export interface ButtonToggleGroupHarnessFilters extends BaseHarnessFilters {
}
56 changes: 56 additions & 0 deletions src/material/button-toggle/testing/button-toggle-group-harness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* @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, HarnessPredicate} from '@angular/cdk/testing';
import {MatButtonToggleAppearance} from '@angular/material/button-toggle';
import {ButtonToggleGroupHarnessFilters} from './button-toggle-group-harness-filters';
import {ButtonToggleHarnessFilters} from './button-toggle-harness-filters';
import {MatButtonToggleHarness} from './button-toggle-harness';


/** Harness for interacting with a standard mat-button-toggle in tests. */
export class MatButtonToggleGroupHarness extends ComponentHarness {
/** The selector for the host element of a `MatButton` instance. */
static hostSelector = 'mat-button-toggle-group';

/**
* Gets a `HarnessPredicate` that can be used to search for a `MatButtonToggleGroupHarness`
* that meets certain criteria.
* @param options Options for filtering which button toggle instances are considered a match.
* @return a `HarnessPredicate` configured with the given options.
*/
static with(options: ButtonToggleGroupHarnessFilters = {}):
HarnessPredicate<MatButtonToggleGroupHarness> {
return new HarnessPredicate(MatButtonToggleGroupHarness, options);
}

/**
* Gets the button toggles that are inside the group.
* @param filter Optionally filters which toggles are included.
*/
async getToggles(filter: ButtonToggleHarnessFilters = {}): Promise<MatButtonToggleHarness[]> {
return this.locatorForAll(MatButtonToggleHarness.with(filter))();
}

/** Gets whether the button toggle group is disabled. */
async isDisabled(): Promise<boolean> {
return await (await this.host()).getAttribute('aria-disabled') === 'true';
}

/** Gets whether the button toggle group is laid out vertically. */
async isVertical(): Promise<boolean> {
return (await this.host()).hasClass('mat-button-toggle-vertical');
}

/** Gets the appearance that the group is using. */
async getAppearance(): Promise<MatButtonToggleAppearance> {
const host = await this.host();
const className = 'mat-button-toggle-group-appearance-standard';
return await host.hasClass(className) ? 'standard' : 'legacy';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import {HarnessLoader} from '@angular/cdk/testing';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
import {Component} from '@angular/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {MatButtonToggleModule, MatButtonToggleAppearance} from '@angular/material/button-toggle';
import {MatButtonToggleGroupHarness} from './button-toggle-group-harness';

/** Shared tests to run on both the original and MDC-based button toggle group. */
export function runHarnessTests(
buttonToggleModule: typeof MatButtonToggleModule,
buttonToggleGroupHarness: typeof MatButtonToggleGroupHarness) {
let fixture: ComponentFixture<ButtonToggleGroupHarnessTest>;
let loader: HarnessLoader;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [buttonToggleModule],
declarations: [ButtonToggleGroupHarnessTest],
}).compileComponents();

fixture = TestBed.createComponent(ButtonToggleGroupHarnessTest);
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});

it('should load all button toggle group harnesses', async () => {
const groups = await loader.getAllHarnesses(buttonToggleGroupHarness);
expect(groups.length).toBe(1);
});

it('should load the the toggles inside the group', async () => {
const group = await loader.getHarness(buttonToggleGroupHarness);
const toggles = await group.getToggles();
expect(toggles.length).toBe(2);
});

it('should get whether the group is disabled', async () => {
const group = await loader.getHarness(buttonToggleGroupHarness);
expect(await group.isDisabled()).toBe(false);
fixture.componentInstance.disabled = true;
expect(await group.isDisabled()).toBe(true);
});

it('should get whether the group is vertical', async () => {
const group = await loader.getHarness(buttonToggleGroupHarness);
expect(await group.isVertical()).toBe(false);
fixture.componentInstance.vertical = true;
expect(await group.isVertical()).toBe(true);
});

it('should get whether the group appearance', async () => {
const group = await loader.getHarness(buttonToggleGroupHarness);
expect(await group.getAppearance()).toBe('standard');
fixture.componentInstance.appearance = 'legacy';
expect(await group.getAppearance()).toBe('legacy');
});
}

@Component({
template: `
<mat-button-toggle-group [disabled]="disabled" [vertical]="vertical" [appearance]="appearance">
<mat-button-toggle value="1">One</mat-button-toggle>
<mat-button-toggle value="2">Two</mat-button-toggle>
</mat-button-toggle-group>
`
})
class ButtonToggleGroupHarnessTest {
disabled = false;
vertical = false;
appearance: MatButtonToggleAppearance = 'standard';
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {MatButtonToggleModule} from '@angular/material/button-toggle';
import {runHarnessTests} from './button-toggle-group-shared.spec';
import {MatButtonToggleGroupHarness} from './button-toggle-group-harness';

describe('Non-MDC-based MatButtonToggleGroupHarness', () => {
runHarnessTests(MatButtonToggleModule, MatButtonToggleGroupHarness);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @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 {BaseHarnessFilters} from '@angular/cdk/testing';

/** Criteria that can be used to filter a list of `MatButtonToggleHarness` instances. */
export interface ButtonToggleHarnessFilters extends BaseHarnessFilters {
/** Only find instances whose text matches the given value. */
text?: string | RegExp;
/** Only find instances whose name matches the given value. */
name?: string | RegExp;
/** Only find instances that are checked. */
checked?: boolean;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {MatButtonToggleModule} from '@angular/material/button-toggle';
import {runHarnessTests} from './button-toggle-shared.spec';
import {MatButtonToggleHarness} from './button-toggle-harness';

describe('Non-MDC-based MatButtonToggleHarness', () => {
runHarnessTests(MatButtonToggleModule, MatButtonToggleHarness);
});
112 changes: 112 additions & 0 deletions src/material/button-toggle/testing/button-toggle-harness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**
* @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, HarnessPredicate} from '@angular/cdk/testing';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {MatButtonToggleAppearance} from '@angular/material/button-toggle';
import {ButtonToggleHarnessFilters} from './button-toggle-harness-filters';


/** Harness for interacting with a standard mat-button-toggle in tests. */
export class MatButtonToggleHarness extends ComponentHarness {
/** The selector for the host element of a `MatButton` instance. */
static hostSelector = 'mat-button-toggle';

private _label = this.locatorFor('.mat-button-toggle-label-content');
private _button = this.locatorFor('.mat-button-toggle-button');

/**
* Gets a `HarnessPredicate` that can be used to search for a `MatButtonToggleHarness` that meets
* certain criteria.
* @param options Options for filtering which button toggle instances are considered a match.
* @return a `HarnessPredicate` configured with the given options.
*/
static with(options: ButtonToggleHarnessFilters = {}): HarnessPredicate<MatButtonToggleHarness> {
return new HarnessPredicate(MatButtonToggleHarness, options)
.addOption('text', options.text,
(harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))
.addOption('name', options.name,
(harness, name) => HarnessPredicate.stringMatches(harness.getName(), name))
.addOption('checked', options.checked,
async (harness, checked) => (await harness.isChecked()) === checked);
}

/** Gets a boolean promise indicating if the button toggle is checked. */
async isChecked(): Promise<boolean> {
const checked = (await this._button()).getAttribute('aria-pressed');
return coerceBooleanProperty(await checked);
}

/** Gets a boolean promise indicating if the button toggle is disabled. */
async isDisabled(): Promise<boolean> {
const disabled = (await this._button()).getAttribute('disabled');
return coerceBooleanProperty(await disabled);
}

/** Gets a promise for the button toggle's name. */
async getName(): Promise<string | null> {
return (await this._button()).getAttribute('name');
}

/** Gets a promise for the button toggle's aria-label. */
async getAriaLabel(): Promise<string | null> {
return (await this._button()).getAttribute('aria-label');
}

/** Gets a promise for the button toggles's aria-labelledby. */
async getAriaLabelledby(): Promise<string | null> {
return (await this._button()).getAttribute('aria-labelledby');
}

/** Gets a promise for the button toggle's text. */
async getText(): Promise<string> {
return (await this._label()).text();
}

/** Gets the appearance that the button toggle is using. */
async getAppearance(): Promise<MatButtonToggleAppearance> {
const host = await this.host();
const className = 'mat-button-toggle-appearance-standard';
return await host.hasClass(className) ? 'standard' : 'legacy';
}

/** Focuses the toggle. */
async focus(): Promise<void> {
return (await this._button()).focus();
}

/** Blurs the toggle. */
async blur(): Promise<void> {
return (await this._button()).blur();
}

/** Toggle the checked state of the buttons toggle. */
async toggle(): Promise<void> {
return (await this._button()).click();
}

/**
* Puts the button toggle in a checked state by toggling it if it's
* currently unchecked, or doing nothing if it is already checked.
*/
async check(): Promise<void> {
if (!(await this.isChecked())) {
await this.toggle();
}
}

/**
* Puts the button toggle in an unchecked state by toggling it if it's
* currently checked, or doing nothing if it's already unchecked.
*/
async uncheck(): Promise<void> {
if (await this.isChecked()) {
await this.toggle();
}
}
}
Loading