{"version":3,"file":"testing.mjs","sources":["../../../../../../../src/material/menu/testing/menu-harness.ts","../../../../../../../src/material/menu/testing/menu-harness-filters.ts","../../../../../../../src/material/menu/testing/public-api.ts","../../../../../../../src/material/menu/testing/index.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.io/license\n */\n\nimport {\n  BaseHarnessFilters,\n  ComponentHarness,\n  ComponentHarnessConstructor,\n  ContentContainerComponentHarness,\n  HarnessLoader,\n  HarnessPredicate,\n  TestElement,\n  TestKey,\n} from '@angular/cdk/testing';\nimport {coerceBooleanProperty} from '@angular/cdk/coercion';\nimport {MenuHarnessFilters, MenuItemHarnessFilters} from './menu-harness-filters';\n\nexport abstract class _MatMenuHarnessBase<\n  ItemType extends (ComponentHarnessConstructor<Item> & {\n    with: (options?: ItemFilters) => HarnessPredicate<Item>}),\n  Item extends ComponentHarness & {\n    click(): Promise<void>,\n    getSubmenu(): Promise<_MatMenuHarnessBase<ItemType, Item, ItemFilters> | null>},\n  ItemFilters extends BaseHarnessFilters\n> extends ContentContainerComponentHarness<string> {\n  private _documentRootLocator = this.documentRootLocatorFactory();\n  protected abstract _itemClass: ItemType;\n\n  // TODO: potentially extend MatButtonHarness\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.sendKeys(TestKey.ESCAPE);\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(filters?: Omit<ItemFilters, 'ancestor'>): Promise<Item[]> {\n    const panelId = await this._getPanelId();\n    if (panelId) {\n      return this._documentRootLocator.locatorForAll(this._itemClass.with({\n        ...(filters || {}),\n        ancestor: `#${panelId}`\n      } as ItemFilters))();\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<ItemFilters, 'ancestor'>,\n      ...subItemFilters: Omit<ItemFilters, 'ancestor'>[]): Promise<void> {\n    await this.open();\n    const items = await this.getItems(itemFilter);\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<ItemFilters, 'ancestor'>]);\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 abstract class _MatMenuItemHarnessBase<\n  MenuType extends ComponentHarnessConstructor<Menu>,\n  Menu extends ComponentHarness,\n> extends ContentContainerComponentHarness<string> {\n  protected abstract _menuClass: MenuType;\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(this._menuClass.hostSelector);\n  }\n\n  /** Gets the submenu associated with this menu item, or null if none. */\n  async getSubmenu(): Promise<Menu | null> {\n    if (await this.hasSubmenu()) {\n      return new this._menuClass(this.locatorFactory);\n    }\n    return null;\n  }\n}\n\n\n/** Harness for interacting with a standard mat-menu in tests. */\nexport class MatMenuHarness extends _MatMenuHarnessBase<\n  typeof MatMenuItemHarness, MatMenuItemHarness, MenuItemHarnessFilters> {\n  /** The selector for the host element of a `MatMenu` instance. */\n  static hostSelector = '.mat-menu-trigger';\n  protected _itemClass = MatMenuItemHarness;\n\n  /**\n   * Gets a `HarnessPredicate` that can be used to search for a `MatMenuHarness` that meets certain\n   * criteria.\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(options: MenuHarnessFilters = {}): HarnessPredicate<MatMenuHarness> {\n    return new HarnessPredicate(MatMenuHarness, options)\n        .addOption('triggerText', options.triggerText,\n            (harness, text) => HarnessPredicate.stringMatches(harness.getTriggerText(), text));\n  }\n}\n\n/** Harness for interacting with a standard mat-menu-item in tests. */\nexport class MatMenuItemHarness extends\n  _MatMenuItemHarnessBase<typeof MatMenuHarness, MatMenuHarness> {\n  /** The selector for the host element of a `MatMenuItem` instance. */\n  static hostSelector = '.mat-menu-item';\n  protected _menuClass = MatMenuHarness;\n\n  /**\n   * Gets a `HarnessPredicate` that can be used to search for a `MatMenuItemHarness` that meets\n   * certain criteria.\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(options: MenuItemHarnessFilters = {}): HarnessPredicate<MatMenuItemHarness> {\n    return new HarnessPredicate(MatMenuItemHarness, options)\n        .addOption('text', options.text,\n            (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))\n        .addOption('hasSubmenu', options.hasSubmenu,\n            async (harness, hasSubmenu) => (await harness.hasSubmenu()) === hasSubmenu);\n  }\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.io/license\n */\n\nimport {BaseHarnessFilters} from '@angular/cdk/testing';\n\n/** A set of criteria that can be used to filter a list of `MatMenuHarness` instances. */\nexport interface MenuHarnessFilters extends BaseHarnessFilters {\n  /** Only find instances whose trigger text matches the given value. */\n  triggerText?: string | RegExp;\n}\n\n/** A set of criteria that can be used to filter a list of `MatMenuItemHarness` instances. */\nexport interface MenuItemHarnessFilters extends BaseHarnessFilters {\n  /** Only find instances whose text matches the given value. */\n  text?: string | RegExp;\n  /** Only find instances that have a sub-menu. */\n  hasSubmenu?: boolean;\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.io/license\n */\n\nexport * from './menu-harness';\nexport * from './menu-harness-filters';\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.io/license\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;AAAA;;;;;;;MAqBsB,mBAOpB,SAAQ,gCAAwC;IAPlD;;QAQU,yBAAoB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;KA8GlE;;;IAxGC,MAAM,UAAU;QACd,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;QAC9D,OAAO,qBAAqB,CAAC,MAAM,QAAQ,CAAC,CAAC;KAC9C;;IAGD,MAAM,MAAM;QACV,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;KACvC;;IAGD,MAAM,cAAc;QAClB,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC;KACnC;;IAGD,MAAM,KAAK;QACT,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC;KACpC;;IAGD,MAAM,IAAI;QACR,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC;KACnC;;IAGD,MAAM,SAAS;QACb,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC;KACxC;;IAGD,MAAM,IAAI;QACR,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE;YACxB,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC;SACpC;KACF;;IAGD,MAAM,KAAK;QACT,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QACzC,IAAI,KAAK,EAAE;YACT,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SACvC;KACF;;;;;IAMD,MAAM,QAAQ,CAAC,OAAuC;QACpD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QACzC,IAAI,OAAO,EAAE;YACX,OAAO,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBAClE,IAAI,OAAO,IAAI,EAAE,CAAC;gBAClB,QAAQ,EAAE,IAAI,OAAO,EAAE;aACT,CAAC,CAAC,EAAE,CAAC;SACtB;QACD,OAAO,EAAE,CAAC;KACX;;;;;;;;;IAUD,MAAM,SAAS,CACX,UAAyC,EACzC,GAAG,cAA+C;QACpD,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YACjB,MAAM,KAAK,CAAC,gCAAgC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;SAC3E;QAED,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;YAC1B,OAAO,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;SAC/B;QAED,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,EAAE;YACT,MAAM,KAAK,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,0BAA0B,CAAC,CAAC;SACpF;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,cAAiD,CAAC,CAAC;KAC7E;IAEkB,MAAM,oBAAoB;QAC3C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC,0BAA0B,EAAE,CAAC,gBAAgB,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC;KAC1E;;IAGO,MAAM,aAAa;QACzB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QACzC,OAAO,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;KACvF;;IAGO,MAAM,WAAW;QACvB,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,eAAe,CAAC,CAAC;QACxE,OAAO,OAAO,IAAI,IAAI,CAAC;KACxB;CACF;MAEqB,uBAGpB,SAAQ,gCAAwC;;IAIhD,MAAM,UAAU;QACd,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;QAC9D,OAAO,qBAAqB,CAAC,MAAM,QAAQ,CAAC,CAAC;KAC9C;;IAGD,MAAM,OAAO;QACX,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC;KACnC;;IAGD,MAAM,KAAK;QACT,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC;KACpC;;IAGD,MAAM,IAAI;QACR,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC;KACnC;;IAGD,MAAM,SAAS;QACb,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC;KACxC;;IAGD,MAAM,KAAK;QACT,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC;KACpC;;IAGD,MAAM,UAAU;QACd,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;KAC1E;;IAGD,MAAM,UAAU;QACd,IAAI,MAAM,IAAI,CAAC,UAAU,EAAE,EAAE;YAC3B,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;SACjD;QACD,OAAO,IAAI,CAAC;KACb;CACF;AAGD;MACa,cAAe,SAAQ,mBACoC;IADxE;;QAIY,eAAU,GAAG,kBAAkB,CAAC;KAa3C;;;;;;;IALC,OAAO,IAAI,CAAC,UAA8B,EAAE;QAC1C,OAAO,IAAI,gBAAgB,CAAC,cAAc,EAAE,OAAO,CAAC;aAC/C,SAAS,CAAC,aAAa,EAAE,OAAO,CAAC,WAAW,EACzC,CAAC,OAAO,EAAE,IAAI,KAAK,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;KAC5F;;AAdD;AACO,2BAAY,GAAG,mBAAmB,CAAC;AAgB5C;MACa,kBAAmB,SAC9B,uBAA8D;IADhE;;QAIY,eAAU,GAAG,cAAc,CAAC;KAevC;;;;;;;IAPC,OAAO,IAAI,CAAC,UAAkC,EAAE;QAC9C,OAAO,IAAI,gBAAgB,CAAC,kBAAkB,EAAE,OAAO,CAAC;aACnD,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAC3B,CAAC,OAAO,EAAE,IAAI,KAAK,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;aAC9E,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,UAAU,EACvC,OAAO,OAAO,EAAE,UAAU,KAAK,CAAC,MAAM,OAAO,CAAC,UAAU,EAAE,MAAM,UAAU,CAAC,CAAC;KACrF;;AAhBD;AACO,+BAAY,GAAG,gBAAgB;;ACzNxC;;;;;;;;ACAA;;;;;;;;ACAA;;;;;;;;;;"}