@angular/material
Version:
Angular Material
1 lines • 18.8 kB
Source Map (JSON)
{"version":3,"file":"menu-testing.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/material/menu/testing/menu-harness.ts","../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/material/menu/testing/context-menu-harness.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {\n ComponentHarnessConstructor,\n ContentContainerComponentHarness,\n HarnessLoader,\n HarnessPredicate,\n TestElement,\n} from '@angular/cdk/testing';\nimport {coerceBooleanProperty} from '@angular/cdk/coercion';\nimport {MatIconHarness} from '@angular/material/icon/testing';\nimport {MenuHarnessFilters, MenuItemHarnessFilters} from './menu-harness-filters';\n\n/** Harness for interacting with a mat-menu in tests. */\nexport class MatMenuHarness extends ContentContainerComponentHarness<string> {\n private _documentRootLocator = this.documentRootLocatorFactory();\n\n /** The selector for the host element of a `MatMenu` instance. */\n static hostSelector = '.mat-mdc-menu-trigger';\n\n /**\n * Gets a `HarnessPredicate` that can be used to search for a menu with specific attributes.\n * @param options Options for filtering which menu instances are considered a match.\n * @return a `HarnessPredicate` configured with the given options.\n */\n static with<T extends MatMenuHarness>(\n this: ComponentHarnessConstructor<T>,\n options: MenuHarnessFilters = {},\n ): HarnessPredicate<T> {\n return new HarnessPredicate(this, options)\n .addOption('triggerText', options.triggerText, (harness, text) =>\n HarnessPredicate.stringMatches(harness.getTriggerText(), text),\n )\n .addOption('triggerIconName', options.triggerIconName, async (harness, triggerIconName) => {\n const result = await harness.locatorForOptional(\n MatIconHarness.with({name: triggerIconName}),\n )();\n return result !== null;\n });\n }\n\n /** Whether the menu is disabled. */\n async isDisabled(): Promise<boolean> {\n const disabled = (await this.host()).getAttribute('disabled');\n return coerceBooleanProperty(await disabled);\n }\n\n /** Whether the menu is open. */\n async isOpen(): Promise<boolean> {\n return !!(await this._getMenuPanel());\n }\n\n /** Gets the text of the menu's trigger element. */\n async getTriggerText(): Promise<string> {\n return (await this.host()).text();\n }\n\n /** Focuses the menu. */\n async focus(): Promise<void> {\n return (await this.host()).focus();\n }\n\n /** Blurs the menu. */\n async blur(): Promise<void> {\n return (await this.host()).blur();\n }\n\n /** Whether the menu is focused. */\n async isFocused(): Promise<boolean> {\n return (await this.host()).isFocused();\n }\n\n /** Opens the menu. */\n async open(): Promise<void> {\n if (!(await this.isOpen())) {\n return (await this.host()).click();\n }\n }\n\n /** Closes the menu. */\n async close(): Promise<void> {\n const panel = await this._getMenuPanel();\n if (panel) {\n return panel.click();\n }\n }\n\n /**\n * Gets a list of `MatMenuItemHarness` representing the items in the menu.\n * @param filters Optionally filters which menu items are included.\n */\n async getItems(\n filters?: Omit<MenuItemHarnessFilters, 'ancestor'>,\n ): Promise<MatMenuItemHarness[]> {\n const panelId = await this._getPanelId();\n if (panelId) {\n return this._documentRootLocator.locatorForAll(\n MatMenuItemHarness.with({\n ...(filters || {}),\n ancestor: `#${panelId}`,\n } as MenuItemHarnessFilters),\n )();\n }\n return [];\n }\n\n /**\n * Clicks an item in the menu, and optionally continues clicking items in subsequent sub-menus.\n * @param itemFilter A filter used to represent which item in the menu should be clicked. The\n * first matching menu item will be clicked.\n * @param subItemFilters A list of filters representing the items to click in any subsequent\n * sub-menus. The first item in the sub-menu matching the corresponding filter in\n * `subItemFilters` will be clicked.\n */\n async clickItem(\n itemFilter: Omit<MenuItemHarnessFilters, 'ancestor'>,\n ...subItemFilters: Omit<MenuItemHarnessFilters, 'ancestor'>[]\n ): Promise<void> {\n await this.open();\n return clickItemImplementation(await this.getItems(itemFilter), itemFilter, subItemFilters);\n }\n\n protected override async getRootHarnessLoader(): Promise<HarnessLoader> {\n const panelId = await this._getPanelId();\n return this.documentRootLocatorFactory().harnessLoaderFor(`#${panelId}`);\n }\n\n /** Gets the menu panel associated with this menu. */\n private async _getMenuPanel(): Promise<TestElement | null> {\n const panelId = await this._getPanelId();\n return panelId ? this._documentRootLocator.locatorForOptional(`#${panelId}`)() : null;\n }\n\n /** Gets the id of the menu panel associated with this menu. */\n private async _getPanelId(): Promise<string | null> {\n const panelId = await (await this.host()).getAttribute('aria-controls');\n return panelId || null;\n }\n}\n\nexport class MatMenuItemHarness extends ContentContainerComponentHarness<string> {\n /** The selector for the host element of a `MatMenuItem` instance. */\n static hostSelector = '.mat-mdc-menu-item';\n\n /**\n * Gets a `HarnessPredicate` that can be used to search for a menu item with specific attributes.\n * @param options Options for filtering which menu item instances are considered a match.\n * @return a `HarnessPredicate` configured with the given options.\n */\n static with<T extends MatMenuItemHarness>(\n this: ComponentHarnessConstructor<T>,\n options: MenuItemHarnessFilters = {},\n ): HarnessPredicate<T> {\n return new HarnessPredicate(this, options)\n .addOption('text', options.text, (harness, text) =>\n HarnessPredicate.stringMatches(harness.getText(), text),\n )\n .addOption(\n 'hasSubmenu',\n options.hasSubmenu,\n async (harness, hasSubmenu) => (await harness.hasSubmenu()) === hasSubmenu,\n );\n }\n\n /** Whether the menu is disabled. */\n async isDisabled(): Promise<boolean> {\n const disabled = (await this.host()).getAttribute('disabled');\n return coerceBooleanProperty(await disabled);\n }\n\n /** Gets the text of the menu item. */\n async getText(): Promise<string> {\n return (await this.host()).text();\n }\n\n /** Focuses the menu item. */\n async focus(): Promise<void> {\n return (await this.host()).focus();\n }\n\n /** Blurs the menu item. */\n async blur(): Promise<void> {\n return (await this.host()).blur();\n }\n\n /** Whether the menu item is focused. */\n async isFocused(): Promise<boolean> {\n return (await this.host()).isFocused();\n }\n\n /** Clicks the menu item. */\n async click(): Promise<void> {\n return (await this.host()).click();\n }\n\n /** Whether this item has a submenu. */\n async hasSubmenu(): Promise<boolean> {\n return (await this.host()).matchesSelector(MatMenuHarness.hostSelector);\n }\n\n /** Gets the submenu associated with this menu item, or null if none. */\n async getSubmenu(): Promise<MatMenuHarness | null> {\n if (await this.hasSubmenu()) {\n return new MatMenuHarness(this.locatorFactory);\n }\n return null;\n }\n}\n\nexport async function clickItemImplementation(\n items: MatMenuItemHarness[],\n itemFilter: Omit<MenuItemHarnessFilters, 'ancestor'>,\n subItemFilters: Omit<MenuItemHarnessFilters, 'ancestor'>[],\n): Promise<void> {\n if (!items.length) {\n throw Error(`Could not find item matching ${JSON.stringify(itemFilter)}`);\n }\n\n if (!subItemFilters.length) {\n return await items[0].click();\n }\n\n const menu = await items[0].getSubmenu();\n if (!menu) {\n throw Error(`Item matching ${JSON.stringify(itemFilter)} does not have a submenu`);\n }\n return menu.clickItem(...(subItemFilters as [Omit<MenuItemHarnessFilters, 'ancestor'>]));\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {\n ComponentHarnessConstructor,\n ContentContainerComponentHarness,\n HarnessLoader,\n HarnessPredicate,\n TestElement,\n} from '@angular/cdk/testing';\nimport {ContextMenuHarnessFilters, MenuItemHarnessFilters} from './menu-harness-filters';\nimport {clickItemImplementation, MatMenuItemHarness} from './menu-harness';\n\n/** Harness for interacting with context menus in tests. */\nexport class MatContextMenuHarness extends ContentContainerComponentHarness<string> {\n private _documentRootLocator = this.documentRootLocatorFactory();\n\n /** The selector for the host element of a `MatContextMenu` instance. */\n static hostSelector = '.mat-context-menu-trigger';\n\n /**\n * Gets a `HarnessPredicate` that can be used to search for a context menu with specific\n * attributes.\n * @param options Options for filtering which menu instances are considered a match.\n * @return a `HarnessPredicate` configured with the given options.\n */\n static with<T extends MatContextMenuHarness>(\n this: ComponentHarnessConstructor<T>,\n options: ContextMenuHarnessFilters = {},\n ): HarnessPredicate<T> {\n return new HarnessPredicate(this, options);\n }\n\n /** Whether the menu is open. */\n async isOpen(): Promise<boolean> {\n return !!(await this._getMenuPanel());\n }\n\n /**\n * Opens the menu.\n * @param relativeX X coordinate, relative to the element, to dispatch the opening click at.\n * @param relativeY Y coordinate, relative to the element, to dispatch the opening click at.\n */\n async open(relativeX = 0, relativeY = 0): Promise<void> {\n if (!(await this.isOpen())) {\n return (await this.host()).rightClick(relativeX, relativeY);\n }\n }\n\n /** Closes the menu. */\n async close(): Promise<void> {\n const panel = await this._getMenuPanel();\n if (panel) {\n return panel.click();\n }\n }\n\n /** Gets whether the context menu trigger is disabled. */\n async isDisabled(): Promise<boolean> {\n const host = await this.host();\n return host.hasClass('mat-context-menu-trigger-disabled');\n }\n\n /**\n * Gets a list of `MatMenuItemHarness` representing the items in the menu.\n * @param filters Optionally filters which menu items are included.\n */\n async getItems(\n filters?: Omit<MenuItemHarnessFilters, 'ancestor'>,\n ): Promise<MatMenuItemHarness[]> {\n const panelId = await this._getPanelId();\n if (panelId) {\n return this._documentRootLocator.locatorForAll(\n MatMenuItemHarness.with({\n ...(filters || {}),\n ancestor: `#${panelId}`,\n } as MenuItemHarnessFilters),\n )();\n }\n return [];\n }\n\n /**\n * Clicks an item in the menu, and optionally continues clicking items in subsequent sub-menus.\n * @param itemFilter A filter used to represent which item in the menu should be clicked. The\n * first matching menu item will be clicked.\n * @param subItemFilters A list of filters representing the items to click in any subsequent\n * sub-menus. The first item in the sub-menu matching the corresponding filter in\n * `subItemFilters` will be clicked.\n */\n async clickItem(\n itemFilter: Omit<MenuItemHarnessFilters, 'ancestor'>,\n ...subItemFilters: Omit<MenuItemHarnessFilters, 'ancestor'>[]\n ): Promise<void> {\n await this.open();\n return clickItemImplementation(await this.getItems(itemFilter), itemFilter, subItemFilters);\n }\n\n protected override async getRootHarnessLoader(): Promise<HarnessLoader> {\n const panelId = await this._getPanelId();\n return this.documentRootLocatorFactory().harnessLoaderFor(`#${panelId}`);\n }\n\n /** Gets the menu panel associated with this menu. */\n private async _getMenuPanel(): Promise<TestElement | null> {\n const panelId = await this._getPanelId();\n return panelId ? this._documentRootLocator.locatorForOptional(`#${panelId}`)() : null;\n }\n\n /** Gets the id of the menu panel associated with this menu. */\n private async _getPanelId(): Promise<string | null> {\n const panelId = await (await this.host()).getAttribute('aria-controls');\n return panelId || null;\n }\n}\n"],"names":[],"mappings":"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"}