sass-references/angular-material/material/list/testing/selection-list-harness.ts

158 lines
5.3 KiB
TypeScript

/**
* @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.dev/license
*/
import {ComponentHarnessConstructor, HarnessPredicate, parallel} from '@angular/cdk/testing';
import {MatListOptionTogglePosition} from '@angular/material/list';
import {MatListHarnessBase} from './list-harness-base';
import {
ListItemHarnessFilters,
ListOptionHarnessFilters,
SelectionListHarnessFilters,
} from './list-harness-filters';
import {getListItemPredicate, MatListItemHarnessBase} from './list-item-harness-base';
/** Harness for interacting with a selection-list in tests. */
export class MatSelectionListHarness extends MatListHarnessBase<
typeof MatListOptionHarness,
MatListOptionHarness,
ListOptionHarnessFilters
> {
/** The selector for the host element of a `MatSelectionList` instance. */
static hostSelector = '.mat-mdc-selection-list';
/**
* Gets a `HarnessPredicate` that can be used to search for a selection list with specific
* attributes.
* @param options Options for filtering which selection list instances are considered a match.
* @return a `HarnessPredicate` configured with the given options.
*/
static with<T extends MatSelectionListHarness>(
this: ComponentHarnessConstructor<T>,
options: SelectionListHarnessFilters = {},
): HarnessPredicate<T> {
return new HarnessPredicate(this, options);
}
override _itemHarness = MatListOptionHarness;
/** Whether the selection list is disabled. */
async isDisabled(): Promise<boolean> {
return (await (await this.host()).getAttribute('aria-disabled')) === 'true';
}
/**
* Selects all items matching any of the given filters.
* @param filters Filters that specify which items should be selected.
*/
async selectItems(...filters: ListOptionHarnessFilters[]): Promise<void> {
const items = await this._getItems(filters);
await parallel(() => items.map(item => item.select()));
}
/**
* Deselects all items matching any of the given filters.
* @param filters Filters that specify which items should be deselected.
*/
async deselectItems(...filters: ListItemHarnessFilters[]): Promise<void> {
const items = await this._getItems(filters);
await parallel(() => items.map(item => item.deselect()));
}
/** Gets all items matching the given list of filters. */
private async _getItems(filters: ListOptionHarnessFilters[]): Promise<MatListOptionHarness[]> {
if (!filters.length) {
return this.getItems();
}
const matches = await parallel(() =>
filters.map(filter => this.locatorForAll(MatListOptionHarness.with(filter))()),
);
return matches.reduce((result, current) => [...result, ...current], []);
}
}
/** Harness for interacting with a list option. */
export class MatListOptionHarness extends MatListItemHarnessBase {
/** The selector for the host element of a `MatListOption` instance. */
static hostSelector = '.mat-mdc-list-option';
/**
* Gets a `HarnessPredicate` that can be used to search for a list option with specific
* attributes.
* @param options Options for filtering which list option instances are considered a match.
* @return a `HarnessPredicate` configured with the given options.
*/
static with<T extends MatListOptionHarness>(
this: ComponentHarnessConstructor<T>,
options: ListOptionHarnessFilters = {},
): HarnessPredicate<T> {
return getListItemPredicate(this, options).addOption(
'is selected',
options.selected,
async (harness, selected) => (await harness.isSelected()) === selected,
);
}
private _beforeCheckbox = this.locatorForOptional('.mdc-list-item__start .mdc-checkbox');
private _beforeRadio = this.locatorForOptional('.mdc-list-item__start .mdc-radio');
/** Gets the position of the checkbox relative to the list option content. */
async getCheckboxPosition(): Promise<MatListOptionTogglePosition> {
return (await this._beforeCheckbox()) !== null ? 'before' : 'after';
}
/** Gets the position of the radio relative to the list option content. */
async getRadioPosition(): Promise<MatListOptionTogglePosition> {
return (await this._beforeRadio()) !== null ? 'before' : 'after';
}
/** Whether the list option is selected. */
async isSelected(): Promise<boolean> {
return (await (await this.host()).getAttribute('aria-selected')) === 'true';
}
/** Focuses the list option. */
async focus(): Promise<void> {
return (await this.host()).focus();
}
/** Blurs the list option. */
async blur(): Promise<void> {
return (await this.host()).blur();
}
/** Whether the list option is focused. */
async isFocused(): Promise<boolean> {
return (await this.host()).isFocused();
}
/** Toggles the checked state of the checkbox. */
async toggle() {
return (await this.host()).click();
}
/**
* Puts the list option in a checked state by toggling it if it is currently
* unchecked, or doing nothing if it is already checked.
*/
async select() {
if (!(await this.isSelected())) {
return this.toggle();
}
}
/**
* Puts the list option in an unchecked state by toggling it if it is currently
* checked, or doing nothing if it is already unchecked.
*/
async deselect() {
if (await this.isSelected()) {
return this.toggle();
}
}
}