{"version":3,"file":"select-testing.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/material/select/testing/select-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 {ComponentHarnessConstructor, HarnessPredicate, parallel} from '@angular/cdk/testing';\nimport {\n  MatOptionHarness,\n  MatOptgroupHarness,\n  OptionHarnessFilters,\n  OptgroupHarnessFilters,\n} from '@angular/material/core/testing';\nimport {MatFormFieldControlHarnessBase} from '@angular/material/form-field/testing/control';\nimport {SelectHarnessFilters} from './select-harness-filters';\n\n/** Harness for interacting with a mat-select in tests. */\nexport class MatSelectHarness extends MatFormFieldControlHarnessBase {\n  static hostSelector = '.mat-mdc-select';\n  private _prefix = 'mat-mdc';\n  private _optionClass = MatOptionHarness;\n  private _optionGroupClass = MatOptgroupHarness;\n  private _documentRootLocator = this.documentRootLocatorFactory();\n  private _backdrop = this._documentRootLocator.locatorFor('.cdk-overlay-backdrop');\n\n  /**\n   * Gets a `HarnessPredicate` that can be used to search for a select with specific attributes.\n   * @param options Options for filtering which select instances are considered a match.\n   * @return a `HarnessPredicate` configured with the given options.\n   */\n  static with<T extends MatSelectHarness>(\n    this: ComponentHarnessConstructor<T>,\n    options: SelectHarnessFilters = {},\n  ): HarnessPredicate<T> {\n    return new HarnessPredicate(this, options)\n      .addOption('disabled', options.disabled, async (harness, disabled) => {\n        return (await harness.isDisabled()) === disabled;\n      })\n      .addOption('label', options.label, (harness, label) => {\n        return HarnessPredicate.stringMatches(harness.getLabel(), label);\n      });\n  }\n\n  /** Gets a boolean promise indicating if the select is disabled. */\n  async isDisabled(): Promise<boolean> {\n    return (await this.host()).hasClass(`${this._prefix}-select-disabled`);\n  }\n\n  /** Gets a boolean promise indicating if the select is valid. */\n  async isValid(): Promise<boolean> {\n    return !(await (await this.host()).hasClass('ng-invalid'));\n  }\n\n  /** Gets a boolean promise indicating if the select is required. */\n  async isRequired(): Promise<boolean> {\n    return (await this.host()).hasClass(`${this._prefix}-select-required`);\n  }\n\n  /** Gets a boolean promise indicating if the select is empty (no value is selected). */\n  async isEmpty(): Promise<boolean> {\n    return (await this.host()).hasClass(`${this._prefix}-select-empty`);\n  }\n\n  /** Gets a boolean promise indicating if the select is in multi-selection mode. */\n  async isMultiple(): Promise<boolean> {\n    return (await this.host()).hasClass(`${this._prefix}-select-multiple`);\n  }\n\n  /** Gets a promise for the select's value text. */\n  async getValueText(): Promise<string> {\n    const value = await this.locatorFor(`.${this._prefix}-select-value`)();\n    return value.text();\n  }\n\n  /** Focuses the select and returns a void promise that indicates when the action is complete. */\n  async focus(): Promise<void> {\n    return (await this.host()).focus();\n  }\n\n  /** Blurs the select and returns a void promise that indicates when the action is complete. */\n  async blur(): Promise<void> {\n    return (await this.host()).blur();\n  }\n\n  /** Whether the select is focused. */\n  async isFocused(): Promise<boolean> {\n    return (await this.host()).isFocused();\n  }\n\n  /** Gets the options inside the select panel. */\n  async getOptions(filter?: Omit<OptionHarnessFilters, 'ancestor'>): Promise<MatOptionHarness[]> {\n    return this._documentRootLocator.locatorForAll(\n      this._optionClass.with({\n        ...(filter || {}),\n        ancestor: await this._getPanelSelector(),\n      } as OptionHarnessFilters),\n    )();\n  }\n\n  /** Gets the groups of options inside the panel. */\n  async getOptionGroups(\n    filter?: Omit<OptgroupHarnessFilters, 'ancestor'>,\n  ): Promise<MatOptgroupHarness[]> {\n    return this._documentRootLocator.locatorForAll(\n      this._optionGroupClass.with({\n        ...(filter || {}),\n        ancestor: await this._getPanelSelector(),\n      } as OptgroupHarnessFilters),\n    )() as Promise<MatOptgroupHarness[]>;\n  }\n\n  /** Gets whether the select is open. */\n  async isOpen(): Promise<boolean> {\n    return !!(await this._documentRootLocator.locatorForOptional(await this._getPanelSelector())());\n  }\n\n  /** Opens the select's panel. */\n  async open(): Promise<void> {\n    if (!(await this.isOpen())) {\n      const trigger = await this.locatorFor(`.${this._prefix}-select-trigger`)();\n      return trigger.click();\n    }\n  }\n\n  /**\n   * Clicks the options that match the passed-in filter. If the select is in multi-selection\n   * mode all options will be clicked, otherwise the harness will pick the first matching option.\n   */\n  async clickOptions(filter?: OptionHarnessFilters): Promise<void> {\n    await this.open();\n\n    const [isMultiple, options] = await parallel(() => [\n      this.isMultiple(),\n      this.getOptions(filter),\n    ]);\n\n    if (options.length === 0) {\n      throw Error('Select does not have options matching the specified filter');\n    }\n\n    if (isMultiple) {\n      await parallel(() => options.map(option => option.click()));\n    } else {\n      await options[0].click();\n    }\n  }\n\n  /** Closes the select's panel. */\n  async close(): Promise<void> {\n    if (await this.isOpen()) {\n      // This is the most consistent way that works both in both single and multi-select modes,\n      // but it assumes that only one overlay is open at a time. We should be able to make it\n      // a bit more precise after #16645 where we can dispatch an ESCAPE press to the host instead.\n      return (await this._backdrop()).click();\n    }\n  }\n\n  /** Gets the selector that should be used to find this select's panel. */\n  private async _getPanelSelector(): Promise<string> {\n    const id = await (await this.host()).getAttribute('id');\n    return `#${id}-panel`;\n  }\n}\n"],"names":[],"mappings":";;;;AAmBM,MAAO,gBAAiB,SAAQ,8BAA8B,CAAA;EAClE,OAAO,YAAY,GAAG,iBAAiB;AAC/B,EAAA,OAAO,GAAG,SAAS;AACnB,EAAA,YAAY,GAAG,gBAAgB;AAC/B,EAAA,iBAAiB,GAAG,kBAAkB;AACtC,EAAA,oBAAoB,GAAG,IAAI,CAAC,0BAA0B,EAAE;EACxD,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,uBAAuB,CAAC;AAOjF,EAAA,OAAO,IAAI,CAET,OAAA,GAAgC,EAAE,EAAA;IAElC,OAAO,IAAI,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAA,CACtC,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,OAAO,EAAE,QAAQ,KAAI;MACnE,OAAO,CAAC,MAAM,OAAO,CAAC,UAAU,EAAE,MAAM,QAAQ;AAClD,IAAA,CAAC,CAAA,CACA,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,KAAI;MACpD,OAAO,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC;AAClE,IAAA,CAAC,CAAC;AACN,EAAA;AAGA,EAAA,MAAM,UAAU,GAAA;AACd,IAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAA,EAAG,IAAI,CAAC,OAAO,kBAAkB,CAAC;AACxE,EAAA;AAGA,EAAA,MAAM,OAAO,GAAA;AACX,IAAA,OAAO,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;AAC5D,EAAA;AAGA,EAAA,MAAM,UAAU,GAAA;AACd,IAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAA,EAAG,IAAI,CAAC,OAAO,kBAAkB,CAAC;AACxE,EAAA;AAGA,EAAA,MAAM,OAAO,GAAA;AACX,IAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAA,EAAG,IAAI,CAAC,OAAO,eAAe,CAAC;AACrE,EAAA;AAGA,EAAA,MAAM,UAAU,GAAA;AACd,IAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAA,EAAG,IAAI,CAAC,OAAO,kBAAkB,CAAC;AACxE,EAAA;AAGA,EAAA,MAAM,YAAY,GAAA;AAChB,IAAA,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,CAAA,CAAA,EAAI,IAAI,CAAC,OAAO,CAAA,aAAA,CAAe,CAAC,EAAE;AACtE,IAAA,OAAO,KAAK,CAAC,IAAI,EAAE;AACrB,EAAA;AAGA,EAAA,MAAM,KAAK,GAAA;IACT,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE;AACpC,EAAA;AAGA,EAAA,MAAM,IAAI,GAAA;IACR,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE;AACnC,EAAA;AAGA,EAAA,MAAM,SAAS,GAAA;IACb,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE;AACxC,EAAA;EAGA,MAAM,UAAU,CAAC,MAA+C,EAAA;IAC9D,OAAO,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAC5C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;AACrB,MAAA,IAAI,MAAM,IAAI,EAAE,CAAC;AACjB,MAAA,QAAQ,EAAE,MAAM,IAAI,CAAC,iBAAiB;KACf,CAAC,CAC3B,EAAE;AACL,EAAA;EAGA,MAAM,eAAe,CACnB,MAAiD,EAAA;IAEjD,OAAO,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAC5C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;AAC1B,MAAA,IAAI,MAAM,IAAI,EAAE,CAAC;AACjB,MAAA,QAAQ,EAAE,MAAM,IAAI,CAAC,iBAAiB;KACb,CAAC,CAC7B,EAAmC;AACtC,EAAA;AAGA,EAAA,MAAM,MAAM,GAAA;AACV,IAAA,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC,EAAE,CAAC;AACjG,EAAA;AAGA,EAAA,MAAM,IAAI,GAAA;IACR,IAAI,EAAE,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;AAC1B,MAAA,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,CAAA,CAAA,EAAI,IAAI,CAAC,OAAO,CAAA,eAAA,CAAiB,CAAC,EAAE;AAC1E,MAAA,OAAO,OAAO,CAAC,KAAK,EAAE;AACxB,IAAA;AACF,EAAA;EAMA,MAAM,YAAY,CAAC,MAA6B,EAAA;AAC9C,IAAA,MAAM,IAAI,CAAC,IAAI,EAAE;IAEjB,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,MAAM,QAAQ,CAAC,MAAM,CACjD,IAAI,CAAC,UAAU,EAAE,EACjB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CACxB,CAAC;AAEF,IAAA,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;MACxB,MAAM,KAAK,CAAC,4DAA4D,CAAC;AAC3E,IAAA;AAEA,IAAA,IAAI,UAAU,EAAE;AACd,MAAA,MAAM,QAAQ,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;AAC7D,IAAA,CAAA,MAAO;AACL,MAAA,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;AAC1B,IAAA;AACF,EAAA;AAGA,EAAA,MAAM,KAAK,GAAA;AACT,IAAA,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE;MAIvB,OAAO,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE;AACzC,IAAA;AACF,EAAA;AAGQ,EAAA,MAAM,iBAAiB,GAAA;AAC7B,IAAA,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC;IACvD,OAAO,CAAA,CAAA,EAAI,EAAE,CAAA,MAAA,CAAQ;AACvB,EAAA;;;;;"}