/** * @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 {ComponentHarness, HarnessPredicate} from '@angular/cdk/testing'; import {IconHarnessFilters, IconType} from './icon-harness-filters'; /** Harness for interacting with a standard mat-icon in tests. */ export class MatIconHarness extends ComponentHarness { /** The selector for the host element of a `MatIcon` instance. */ static hostSelector = '.mat-icon'; /** * Gets a `HarnessPredicate` that can be used to search for a `MatIconHarness` that meets * certain criteria. * @param options Options for filtering which icon instances are considered a match. * @return a `HarnessPredicate` configured with the given options. */ static with(options: IconHarnessFilters = {}): HarnessPredicate { return new HarnessPredicate(MatIconHarness, options) .addOption('type', options.type, async (harness, type) => (await harness.getType()) === type) .addOption('name', options.name, (harness, text) => HarnessPredicate.stringMatches(harness.getName(), text), ) .addOption('namespace', options.namespace, (harness, text) => HarnessPredicate.stringMatches(harness.getNamespace(), text), ); } /** Gets the type of the icon. */ async getType(): Promise { const type = await (await this.host()).getAttribute('data-mat-icon-type'); return type === 'svg' ? IconType.SVG : IconType.FONT; } /** Gets the name of the icon. */ async getName(): Promise { const host = await this.host(); const nameFromDom = await host.getAttribute('data-mat-icon-name'); // If we managed to figure out the name from the attribute, use it. if (nameFromDom) { return nameFromDom; } // Some icons support defining the icon as a ligature. // As a fallback, try to extract it from the DOM text. if ((await this.getType()) === IconType.FONT) { // Other directives may add content to the icon (e.g. `MatBadge`), however only the direct // text nodes affect the name of the icon. Exclude all element descendants from the result. const text = await host.text({exclude: '*'}); // There are some internal cases where the icon name is wrapped in another node. // Fall back to extracting the entire text if we ended up excluding everything above. return text.length > 0 ? text : host.text(); } return null; } /** Gets the namespace of the icon. */ async getNamespace(): Promise { return (await this.host()).getAttribute('data-mat-icon-namespace'); } /** Gets whether the icon is inline. */ async isInline(): Promise { return (await this.host()).hasClass('mat-icon-inline'); } }