/** * @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, ContentContainerComponentHarness, HarnessPredicate, } from '@angular/cdk/testing'; import {TreeNodeHarnessFilters} from './tree-harness-filters'; import {coerceBooleanProperty, coerceNumberProperty} from '@angular/cdk/coercion'; /** Harness for interacting with a standard Angular Material tree node. */ export class MatTreeNodeHarness extends ContentContainerComponentHarness { /** The selector of the host element of a `MatTreeNode` instance. */ static hostSelector = '.mat-tree-node, .mat-nested-tree-node'; _toggle = this.locatorForOptional('[matTreeNodeToggle]'); /** * Gets a `HarnessPredicate` that can be used to search for a tree node with specific attributes. * @param options Options for narrowing the search * @return a `HarnessPredicate` configured with the given options. */ static with(options: TreeNodeHarnessFilters = {}): HarnessPredicate { return getNodePredicate(MatTreeNodeHarness, options); } /** Whether the tree node is expanded. */ async isExpanded(): Promise { return coerceBooleanProperty(await (await this.host()).getAttribute('aria-expanded')); } /** Whether the tree node is expandable. */ async isExpandable(): Promise { return (await (await this.host()).getAttribute('aria-expanded')) !== null; } /** Whether the tree node is disabled. */ async isDisabled(): Promise { return coerceBooleanProperty(await (await this.host()).getProperty('aria-disabled')); } /** Gets the level of the tree node. Note that this gets the aria-level and is 1 indexed. */ async getLevel(): Promise { return coerceNumberProperty(await (await this.host()).getAttribute('aria-level')); } /** Gets the tree node's text. */ async getText(): Promise { return (await this.host()).text({exclude: '.mat-tree-node, .mat-nested-tree-node, button'}); } /** Toggles node between expanded/collapsed. Only works when node is not disabled. */ async toggle(): Promise { const toggle = await this._toggle(); if (toggle) { return toggle.click(); } } /** Expands the node if it is collapsed. Only works when node is not disabled. */ async expand(): Promise { if (!(await this.isExpanded())) { await this.toggle(); } } /** Collapses the node if it is expanded. Only works when node is not disabled. */ async collapse(): Promise { if (await this.isExpanded()) { await this.toggle(); } } } function getNodePredicate( type: ComponentHarnessConstructor, options: TreeNodeHarnessFilters, ): HarnessPredicate { return new HarnessPredicate(type, options) .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text), ) .addOption( 'disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled, ) .addOption( 'expanded', options.expanded, async (harness, expanded) => (await harness.isExpanded()) === expanded, ) .addOption( 'level', options.level, async (harness, level) => (await harness.getLevel()) === level, ); }