{"version":3,"file":"testing.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/cdk/testing/change-detection.ts","../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/cdk/testing/component-harness.ts","../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/cdk/testing/harness-environment.ts","../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/cdk/testing/test-element.ts","../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/cdk/testing/test-element-errors.ts","../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/cdk/testing/text-filtering.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 {BehaviorSubject, Subscription} from 'rxjs';\n\n/**\n * The status of the test harness auto change detection. If not diabled test harnesses will\n * automatically trigger change detection after every action (such as a click) and before every read\n * (such as getting the text of an element).\n */\nexport interface AutoChangeDetectionStatus {\n /** Whether auto change detection is disabled. */\n isDisabled: boolean;\n /**\n * An optional callback, if present it indicates that change detection should be run immediately,\n * while handling the status change. The callback should then be called as soon as change\n * detection is done.\n */\n onDetectChangesNow?: () => void;\n}\n\n/** Subject used to dispatch and listen for changes to the auto change detection status . */\nconst autoChangeDetectionSubject = new BehaviorSubject({\n isDisabled: false,\n});\n\n/** The current subscription to `autoChangeDetectionSubject`. */\nlet autoChangeDetectionSubscription: Subscription | null;\n\n/**\n * The default handler for auto change detection status changes. This handler will be used if the\n * specific environment does not install its own.\n * @param status The new auto change detection status.\n */\nfunction defaultAutoChangeDetectionHandler(status: AutoChangeDetectionStatus) {\n status.onDetectChangesNow?.();\n}\n\n/**\n * Allows a test `HarnessEnvironment` to install its own handler for auto change detection status\n * changes.\n * @param handler The handler for the auto change detection status.\n */\nexport function handleAutoChangeDetectionStatus(\n handler: (status: AutoChangeDetectionStatus) => void,\n) {\n stopHandlingAutoChangeDetectionStatus();\n autoChangeDetectionSubscription = autoChangeDetectionSubject.subscribe(handler);\n}\n\n/** Allows a `HarnessEnvironment` to stop handling auto change detection status changes. */\nexport function stopHandlingAutoChangeDetectionStatus() {\n autoChangeDetectionSubscription?.unsubscribe();\n autoChangeDetectionSubscription = null;\n}\n\n/**\n * Batches together triggering of change detection over the duration of the given function.\n * @param fn The function to call with batched change detection.\n * @param triggerBeforeAndAfter Optionally trigger change detection once before and after the batch\n * operation. If false, change detection will not be triggered.\n * @return The result of the given function.\n */\nasync function batchChangeDetection(fn: () => Promise, triggerBeforeAndAfter: boolean) {\n // If change detection batching is already in progress, just run the function.\n if (autoChangeDetectionSubject.getValue().isDisabled) {\n return await fn();\n }\n\n // If nothing is handling change detection batching, install the default handler.\n if (!autoChangeDetectionSubscription) {\n handleAutoChangeDetectionStatus(defaultAutoChangeDetectionHandler);\n }\n\n if (triggerBeforeAndAfter) {\n await new Promise(resolve =>\n autoChangeDetectionSubject.next({\n isDisabled: true,\n onDetectChangesNow: resolve as () => void,\n }),\n );\n // The function passed in may throw (e.g. if the user wants to make an expectation of an error\n // being thrown. If this happens, we need to make sure we still re-enable change detection, so\n // we wrap it in a `finally` block.\n try {\n return await fn();\n } finally {\n await new Promise(resolve =>\n autoChangeDetectionSubject.next({\n isDisabled: false,\n onDetectChangesNow: resolve as () => void,\n }),\n );\n }\n } else {\n autoChangeDetectionSubject.next({isDisabled: true});\n // The function passed in may throw (e.g. if the user wants to make an expectation of an error\n // being thrown. If this happens, we need to make sure we still re-enable change detection, so\n // we wrap it in a `finally` block.\n try {\n return await fn();\n } finally {\n autoChangeDetectionSubject.next({isDisabled: false});\n }\n }\n}\n\n/**\n * Disables the harness system's auto change detection for the duration of the given function.\n * @param fn The function to disable auto change detection for.\n * @return The result of the given function.\n */\nexport async function manualChangeDetection(fn: () => Promise) {\n return batchChangeDetection(fn, false);\n}\n\n/**\n * Resolves the given list of async values in parallel (i.e. via Promise.all) while batching change\n * detection over the entire operation such that change detection occurs exactly once before\n * resolving the values and once after.\n * @param values A getter for the async values to resolve in parallel with batched change detection.\n * @return The resolved values.\n */\nexport function parallel(\n values: () => [\n T1 | PromiseLike,\n T2 | PromiseLike,\n T3 | PromiseLike,\n T4 | PromiseLike,\n T5 | PromiseLike,\n ],\n): Promise<[T1, T2, T3, T4, T5]>;\n\n/**\n * Resolves the given list of async values in parallel (i.e. via Promise.all) while batching change\n * detection over the entire operation such that change detection occurs exactly once before\n * resolving the values and once after.\n * @param values A getter for the async values to resolve in parallel with batched change detection.\n * @return The resolved values.\n */\nexport function parallel(\n values: () => [\n T1 | PromiseLike,\n T2 | PromiseLike,\n T3 | PromiseLike,\n T4 | PromiseLike,\n ],\n): Promise<[T1, T2, T3, T4]>;\n\n/**\n * Resolves the given list of async values in parallel (i.e. via Promise.all) while batching change\n * detection over the entire operation such that change detection occurs exactly once before\n * resolving the values and once after.\n * @param values A getter for the async values to resolve in parallel with batched change detection.\n * @return The resolved values.\n */\nexport function parallel(\n values: () => [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike],\n): Promise<[T1, T2, T3]>;\n\n/**\n * Resolves the given list of async values in parallel (i.e. via Promise.all) while batching change\n * detection over the entire operation such that change detection occurs exactly once before\n * resolving the values and once after.\n * @param values A getter for the async values to resolve in parallel with batched change detection.\n * @return The resolved values.\n */\nexport function parallel(\n values: () => [T1 | PromiseLike, T2 | PromiseLike],\n): Promise<[T1, T2]>;\n\n/**\n * Resolves the given list of async values in parallel (i.e. via Promise.all) while batching change\n * detection over the entire operation such that change detection occurs exactly once before\n * resolving the values and once after.\n * @param values A getter for the async values to resolve in parallel with batched change detection.\n * @return The resolved values.\n */\nexport function parallel(values: () => (T | PromiseLike)[]): Promise;\n\n/**\n * Resolves the given list of async values in parallel (i.e. via Promise.all) while batching change\n * detection over the entire operation such that change detection occurs exactly once before\n * resolving the values and once after.\n * @param values A getter for the async values to resolve in parallel with batched change detection.\n * @return The resolved values.\n */\nexport async function parallel(values: () => Iterable>): Promise {\n return batchChangeDetection(() => Promise.all(values()), true);\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 {parallel} from './change-detection';\nimport {TestElement} from './test-element';\n\n/**\n * An async function that returns a promise when called.\n * @deprecated This was just an alias for `() => Promise`. Use that instead.\n * @breaking-change 21.0.0 Remove this alias.\n * @docs-private\n */\nexport type AsyncFactoryFn = () => Promise;\n\n/** An async function that takes an item and returns a boolean promise */\nexport type AsyncPredicate = (item: T) => Promise;\n\n/** An async function that takes an item and an option value and returns a boolean promise. */\nexport type AsyncOptionPredicate = (item: T, option: O) => Promise;\n\n/**\n * A query for a `ComponentHarness`, which is expressed as either a `ComponentHarnessConstructor` or\n * a `HarnessPredicate`.\n */\nexport type HarnessQuery =\n | ComponentHarnessConstructor\n | HarnessPredicate;\n\n/**\n * The result type obtained when searching using a particular list of queries. This type depends on\n * the particular items being queried.\n * - If one of the queries is for a `ComponentHarnessConstructor`, it means that the result\n * might be a harness of type `C1`\n * - If one of the queries is for a `HarnessPredicate`, it means that the result might be a\n * harness of type `C2`\n * - If one of the queries is for a `string`, it means that the result might be a `TestElement`.\n *\n * Since we don't know for sure which query will match, the result type if the union of the types\n * for all possible results.\n *\n * @usageNotes\n * ### Example\n *\n * The type:\n * ```ts\n * LocatorFnResult<[\n * ComponentHarnessConstructor,\n * HarnessPredicate,\n * string\n * ]>\n * ```\n *\n * is equivalent to:\n *\n * ```ts\n * MyHarness | MyOtherHarness | TestElement\n * ```\n */\nexport type LocatorFnResult | string)[]> = {\n [I in keyof T]: T[I] extends new (...args: any[]) => infer C // Map `ComponentHarnessConstructor` to `C`.\n ? C\n : // Map `HarnessPredicate` to `C`.\n T[I] extends {harnessType: new (...args: any[]) => infer C}\n ? C\n : // Map `string` to `TestElement`.\n T[I] extends string\n ? TestElement\n : // Map everything else to `never` (should not happen due to the type constraint on `T`).\n never;\n}[number];\n\n/**\n * Interface used to load ComponentHarness objects. This interface is used by test authors to\n * instantiate `ComponentHarness`es.\n */\nexport interface HarnessLoader {\n /**\n * Searches for an element with the given selector under the current instances's root element,\n * and returns a `HarnessLoader` rooted at the matching element. If multiple elements match the\n * selector, the first is used. If no elements match, an error is thrown.\n * @param selector The selector for the root element of the new `HarnessLoader`\n * @return A `HarnessLoader` rooted at the element matching the given selector.\n * @throws If a matching element can't be found.\n */\n getChildLoader(selector: string): Promise;\n\n /**\n * Searches for all elements with the given selector under the current instances's root element,\n * and returns an array of `HarnessLoader`s, one for each matching element, rooted at that\n * element.\n * @param selector The selector for the root element of the new `HarnessLoader`\n * @return A list of `HarnessLoader`s, one for each matching element, rooted at that element.\n */\n getAllChildLoaders(selector: string): Promise;\n\n /**\n * Searches for an instance of the component corresponding to the given harness type under the\n * `HarnessLoader`'s root element, and returns a `ComponentHarness` for that instance. If multiple\n * matching components are found, a harness for the first one is returned. If no matching\n * component is found, an error is thrown.\n * @param query A query for a harness to create\n * @return An instance of the given harness type\n * @throws If a matching component instance can't be found.\n */\n getHarness(query: HarnessQuery): Promise;\n\n /**\n * Searches for an instance of the component corresponding to the given harness type under the\n * `HarnessLoader`'s root element, and returns a `ComponentHarness` for that instance. If multiple\n * matching components are found, a harness for the first one is returned. If no matching\n * component is found, null is returned.\n * @param query A query for a harness to create\n * @return An instance of the given harness type (or null if not found).\n */\n getHarnessOrNull(query: HarnessQuery): Promise;\n\n /**\n * Searches for an instance of the component corresponding to the given harness type under the\n * `HarnessLoader`'s root element, and returns a `ComponentHarness` for the instance on the page\n * at the given index. If no matching component exists at that index, an error is thrown.\n * @param query A query for a harness to create\n * @param index The zero-indexed offset of the matching component instance to return\n * @return An instance of the given harness type.\n * @throws If a matching component instance can't be found at the given index.\n */\n getHarnessAtIndex(query: HarnessQuery, index: number): Promise;\n\n /**\n * Searches for all instances of the component corresponding to the given harness type under the\n * `HarnessLoader`'s root element, and returns a list `ComponentHarness` for each instance.\n * @param query A query for a harness to create\n * @return A list instances of the given harness type.\n */\n getAllHarnesses(query: HarnessQuery): Promise;\n\n /**\n * Searches for all instances of the component corresponding to the given harness type under the\n * `HarnessLoader`'s root element, and returns the total count of all matching components.\n * @param query A query for a harness to create\n * @return An integer indicating the number of instances that were found.\n */\n countHarnesses(query: HarnessQuery): Promise;\n\n /**\n * Searches for an instance of the component corresponding to the given harness type under the\n * `HarnessLoader`'s root element, and returns a boolean indicating if any were found.\n * @param query A query for a harness to create\n * @return A boolean indicating if an instance was found.\n */\n hasHarness(query: HarnessQuery): Promise;\n}\n\n/**\n * Interface used to create asynchronous locator functions used find elements and component\n * harnesses. This interface is used by `ComponentHarness` authors to create locator functions for\n * their `ComponentHarness` subclass.\n */\nexport interface LocatorFactory {\n /** Gets a locator factory rooted at the document root. */\n documentRootLocatorFactory(): LocatorFactory;\n\n /** The root element of this `LocatorFactory` as a `TestElement`. */\n rootElement: TestElement;\n\n /**\n * Creates an asynchronous locator function that can be used to find a `ComponentHarness` instance\n * or element under the root element of this `LocatorFactory`.\n *\n * For example, given the following DOM and assuming `DivHarness.hostSelector` is `'div'`\n *\n * ```html\n *
\n * ```\n *\n * then we expect:\n *\n * ```ts\n * await lf.locatorFor(DivHarness, 'div')() // Gets a `DivHarness` instance for #d1\n * await lf.locatorFor('div', DivHarness)() // Gets a `TestElement` instance for #d1\n * await lf.locatorFor('span')() // Throws because the `Promise` rejects\n * ```\n *\n * @param queries A list of queries specifying which harnesses and elements to search for:\n * - A `string` searches for elements matching the CSS selector specified by the string.\n * - A `ComponentHarness` constructor searches for `ComponentHarness` instances matching the\n * given class.\n * - A `HarnessPredicate` searches for `ComponentHarness` instances matching the given\n * predicate.\n * @return An asynchronous locator function that searches for and returns a `Promise` for the\n * first element or harness matching the given search criteria. Matches are ordered first by\n * order in the DOM, and second by order in the queries list. If no matches are found, the\n * `Promise` rejects. The type that the `Promise` resolves to is a union of all result types for\n * each query.\n */\n locatorFor | string)[]>(\n ...queries: T\n ): () => Promise>;\n\n /**\n * Creates an asynchronous locator function that can be used to find a `ComponentHarness` instance\n * or element under the root element of this `LocatorFactory`.\n *\n * For example, given the following DOM and assuming `DivHarness.hostSelector` is `'div'`\n *\n * ```html\n *
\n * ```\n *\n * then we expect:\n *\n * ```ts\n * await lf.locatorForOptional(DivHarness, 'div')() // Gets a `DivHarness` instance for #d1\n * await lf.locatorForOptional('div', DivHarness)() // Gets a `TestElement` instance for #d1\n * await lf.locatorForOptional('span')() // Gets `null`\n * ```\n *\n * @param queries A list of queries specifying which harnesses and elements to search for:\n * - A `string` searches for elements matching the CSS selector specified by the string.\n * - A `ComponentHarness` constructor searches for `ComponentHarness` instances matching the\n * given class.\n * - A `HarnessPredicate` searches for `ComponentHarness` instances matching the given\n * predicate.\n * @return An asynchronous locator function that searches for and returns a `Promise` for the\n * first element or harness matching the given search criteria. Matches are ordered first by\n * order in the DOM, and second by order in the queries list. If no matches are found, the\n * `Promise` is resolved with `null`. The type that the `Promise` resolves to is a union of all\n * result types for each query or null.\n */\n locatorForOptional | string)[]>(\n ...queries: T\n ): () => Promise | null>;\n\n /**\n * Creates an asynchronous locator function that can be used to find `ComponentHarness` instances\n * or elements under the root element of this `LocatorFactory`.\n *\n * For example, given the following DOM and assuming `DivHarness.hostSelector` is `'div'` and\n * `IdIsD1Harness.hostSelector` is `'#d1'`\n *\n * ```html\n *
\n * ```\n *\n * then we expect:\n *\n * ```ts\n * // Gets [DivHarness for #d1, TestElement for #d1, DivHarness for #d2, TestElement for #d2]\n * await lf.locatorForAll(DivHarness, 'div')()\n * // Gets [TestElement for #d1, TestElement for #d2]\n * await lf.locatorForAll('div', '#d1')()\n * // Gets [DivHarness for #d1, IdIsD1Harness for #d1, DivHarness for #d2]\n * await lf.locatorForAll(DivHarness, IdIsD1Harness)()\n * // Gets []\n * await lf.locatorForAll('span')()\n * ```\n *\n * @param queries A list of queries specifying which harnesses and elements to search for:\n * - A `string` searches for elements matching the CSS selector specified by the string.\n * - A `ComponentHarness` constructor searches for `ComponentHarness` instances matching the\n * given class.\n * - A `HarnessPredicate` searches for `ComponentHarness` instances matching the given\n * predicate.\n * @return An asynchronous locator function that searches for and returns a `Promise` for all\n * elements and harnesses matching the given search criteria. Matches are ordered first by\n * order in the DOM, and second by order in the queries list. If an element matches more than\n * one `ComponentHarness` class, the locator gets an instance of each for the same element. If\n * an element matches multiple `string` selectors, only one `TestElement` instance is returned\n * for that element. The type that the `Promise` resolves to is an array where each element is\n * the union of all result types for each query.\n */\n locatorForAll | string)[]>(\n ...queries: T\n ): () => Promise[]>;\n\n /** @return A `HarnessLoader` rooted at the root element of this `LocatorFactory`. */\n rootHarnessLoader(): Promise;\n\n /**\n * Gets a `HarnessLoader` instance for an element under the root of this `LocatorFactory`.\n * @param selector The selector for the root element.\n * @return A `HarnessLoader` rooted at the first element matching the given selector.\n * @throws If no matching element is found for the given selector.\n */\n harnessLoaderFor(selector: string): Promise;\n\n /**\n * Gets a `HarnessLoader` instance for an element under the root of this `LocatorFactory`\n * @param selector The selector for the root element.\n * @return A `HarnessLoader` rooted at the first element matching the given selector, or null if\n * no matching element is found.\n */\n harnessLoaderForOptional(selector: string): Promise;\n\n /**\n * Gets a list of `HarnessLoader` instances, one for each matching element.\n * @param selector The selector for the root element.\n * @return A list of `HarnessLoader`, one rooted at each element matching the given selector.\n */\n harnessLoaderForAll(selector: string): Promise;\n\n /**\n * Flushes change detection and async tasks captured in the Angular zone.\n * In most cases it should not be necessary to call this manually. However, there may be some edge\n * cases where it is needed to fully flush animation events.\n */\n forceStabilize(): Promise;\n\n /**\n * Waits for all scheduled or running async tasks to complete. This allows harness\n * authors to wait for async tasks outside of the Angular zone.\n */\n waitForTasksOutsideAngular(): Promise;\n}\n\n/**\n * Base class for component test harnesses that all component harness authors should extend. This\n * base component harness provides the basic ability to locate element and sub-component harnesses.\n */\nexport abstract class ComponentHarness {\n constructor(protected readonly locatorFactory: LocatorFactory) {}\n\n /** Gets a `Promise` for the `TestElement` representing the host element of the component. */\n async host(): Promise {\n return this.locatorFactory.rootElement;\n }\n\n /**\n * Gets a `LocatorFactory` for the document root element. This factory can be used to create\n * locators for elements that a component creates outside of its own root element. (e.g. by\n * appending to document.body).\n */\n protected documentRootLocatorFactory(): LocatorFactory {\n return this.locatorFactory.documentRootLocatorFactory();\n }\n\n /**\n * Creates an asynchronous locator function that can be used to find a `ComponentHarness` instance\n * or element under the host element of this `ComponentHarness`.\n *\n * For example, given the following DOM and assuming `DivHarness.hostSelector` is `'div'`\n *\n * ```html\n *
\n * ```\n *\n * then we expect:\n *\n * ```ts\n * await ch.locatorFor(DivHarness, 'div')() // Gets a `DivHarness` instance for #d1\n * await ch.locatorFor('div', DivHarness)() // Gets a `TestElement` instance for #d1\n * await ch.locatorFor('span')() // Throws because the `Promise` rejects\n * ```\n *\n * @param queries A list of queries specifying which harnesses and elements to search for:\n * - A `string` searches for elements matching the CSS selector specified by the string.\n * - A `ComponentHarness` constructor searches for `ComponentHarness` instances matching the\n * given class.\n * - A `HarnessPredicate` searches for `ComponentHarness` instances matching the given\n * predicate.\n * @return An asynchronous locator function that searches for and returns a `Promise` for the\n * first element or harness matching the given search criteria. Matches are ordered first by\n * order in the DOM, and second by order in the queries list. If no matches are found, the\n * `Promise` rejects. The type that the `Promise` resolves to is a union of all result types for\n * each query.\n */\n protected locatorFor | string)[]>(\n ...queries: T\n ): () => Promise> {\n return this.locatorFactory.locatorFor(...queries);\n }\n\n /**\n * Creates an asynchronous locator function that can be used to find a `ComponentHarness` instance\n * or element under the host element of this `ComponentHarness`.\n *\n * For example, given the following DOM and assuming `DivHarness.hostSelector` is `'div'`\n *\n * ```html\n *
\n * ```\n *\n * then we expect:\n *\n * ```ts\n * await ch.locatorForOptional(DivHarness, 'div')() // Gets a `DivHarness` instance for #d1\n * await ch.locatorForOptional('div', DivHarness)() // Gets a `TestElement` instance for #d1\n * await ch.locatorForOptional('span')() // Gets `null`\n * ```\n *\n * @param queries A list of queries specifying which harnesses and elements to search for:\n * - A `string` searches for elements matching the CSS selector specified by the string.\n * - A `ComponentHarness` constructor searches for `ComponentHarness` instances matching the\n * given class.\n * - A `HarnessPredicate` searches for `ComponentHarness` instances matching the given\n * predicate.\n * @return An asynchronous locator function that searches for and returns a `Promise` for the\n * first element or harness matching the given search criteria. Matches are ordered first by\n * order in the DOM, and second by order in the queries list. If no matches are found, the\n * `Promise` is resolved with `null`. The type that the `Promise` resolves to is a union of all\n * result types for each query or null.\n */\n protected locatorForOptional | string)[]>(\n ...queries: T\n ): () => Promise | null> {\n return this.locatorFactory.locatorForOptional(...queries);\n }\n\n /**\n * Creates an asynchronous locator function that can be used to find `ComponentHarness` instances\n * or elements under the host element of this `ComponentHarness`.\n *\n * For example, given the following DOM and assuming `DivHarness.hostSelector` is `'div'` and\n * `IdIsD1Harness.hostSelector` is `'#d1'`\n *\n * ```html\n *
\n * ```\n *\n * then we expect:\n *\n * ```ts\n * // Gets [DivHarness for #d1, TestElement for #d1, DivHarness for #d2, TestElement for #d2]\n * await ch.locatorForAll(DivHarness, 'div')()\n * // Gets [TestElement for #d1, TestElement for #d2]\n * await ch.locatorForAll('div', '#d1')()\n * // Gets [DivHarness for #d1, IdIsD1Harness for #d1, DivHarness for #d2]\n * await ch.locatorForAll(DivHarness, IdIsD1Harness)()\n * // Gets []\n * await ch.locatorForAll('span')()\n * ```\n *\n * @param queries A list of queries specifying which harnesses and elements to search for:\n * - A `string` searches for elements matching the CSS selector specified by the string.\n * - A `ComponentHarness` constructor searches for `ComponentHarness` instances matching the\n * given class.\n * - A `HarnessPredicate` searches for `ComponentHarness` instances matching the given\n * predicate.\n * @return An asynchronous locator function that searches for and returns a `Promise` for all\n * elements and harnesses matching the given search criteria. Matches are ordered first by\n * order in the DOM, and second by order in the queries list. If an element matches more than\n * one `ComponentHarness` class, the locator gets an instance of each for the same element. If\n * an element matches multiple `string` selectors, only one `TestElement` instance is returned\n * for that element. The type that the `Promise` resolves to is an array where each element is\n * the union of all result types for each query.\n */\n protected locatorForAll | string)[]>(\n ...queries: T\n ): () => Promise[]> {\n return this.locatorFactory.locatorForAll(...queries);\n }\n\n /**\n * Flushes change detection and async tasks in the Angular zone.\n * In most cases it should not be necessary to call this manually. However, there may be some edge\n * cases where it is needed to fully flush animation events.\n */\n protected async forceStabilize() {\n return this.locatorFactory.forceStabilize();\n }\n\n /**\n * Waits for all scheduled or running async tasks to complete. This allows harness\n * authors to wait for async tasks outside of the Angular zone.\n */\n protected async waitForTasksOutsideAngular() {\n return this.locatorFactory.waitForTasksOutsideAngular();\n }\n}\n\n/**\n * Base class for component harnesses that authors should extend if they anticipate that consumers\n * of the harness may want to access other harnesses within the `` of the component.\n */\nexport abstract class ContentContainerComponentHarness\n extends ComponentHarness\n implements HarnessLoader\n{\n /**\n * Gets a `HarnessLoader` that searches for harnesses under the first element matching the given\n * selector within the current harness's content.\n * @param selector The selector for an element in the component's content.\n * @returns A `HarnessLoader` that searches for harnesses under the given selector.\n */\n async getChildLoader(selector: S): Promise {\n return (await this.getRootHarnessLoader()).getChildLoader(selector);\n }\n\n /**\n * Gets a list of `HarnessLoader` for each element matching the given selector under the current\n * harness's cotnent that searches for harnesses under that element.\n * @param selector The selector for elements in the component's content.\n * @returns A list of `HarnessLoader` for each element matching the given selector.\n */\n async getAllChildLoaders(selector: S): Promise {\n return (await this.getRootHarnessLoader()).getAllChildLoaders(selector);\n }\n\n /**\n * Gets the first matching harness for the given query within the current harness's content.\n * @param query The harness query to search for.\n * @returns The first harness matching the given query.\n * @throws If no matching harness is found.\n */\n async getHarness(query: HarnessQuery): Promise {\n return (await this.getRootHarnessLoader()).getHarness(query);\n }\n\n /**\n * Gets the first matching harness for the given query within the current harness's content.\n * @param query The harness query to search for.\n * @returns The first harness matching the given query, or null if none is found.\n */\n async getHarnessOrNull(query: HarnessQuery): Promise {\n return (await this.getRootHarnessLoader()).getHarnessOrNull(query);\n }\n\n /**\n * Gets a matching harness for the given query and index within the current harness's content.\n * @param query The harness query to search for.\n * @param index The zero-indexed offset of the component to find.\n * @returns The first harness matching the given query.\n * @throws If no matching harness is found.\n */\n async getHarnessAtIndex(\n query: HarnessQuery,\n index: number,\n ): Promise {\n return (await this.getRootHarnessLoader()).getHarnessAtIndex(query, index);\n }\n\n /**\n * Gets all matching harnesses for the given query within the current harness's content.\n * @param query The harness query to search for.\n * @returns The list of harness matching the given query.\n */\n async getAllHarnesses(query: HarnessQuery): Promise {\n return (await this.getRootHarnessLoader()).getAllHarnesses(query);\n }\n\n /**\n * Returns the number of matching harnesses for the given query within the current harness's\n * content.\n *\n * @param query The harness query to search for.\n * @returns The number of matching harnesses for the given query.\n */\n async countHarnesses(query: HarnessQuery): Promise {\n return (await this.getRootHarnessLoader()).countHarnesses(query);\n }\n\n /**\n * Checks whether there is a matching harnesses for the given query within the current harness's\n * content.\n *\n * @param query The harness query to search for.\n * @returns Whether there is matching harnesses for the given query.\n */\n async hasHarness(query: HarnessQuery): Promise {\n return (await this.getRootHarnessLoader()).hasHarness(query);\n }\n\n /**\n * Gets the root harness loader from which to start\n * searching for content contained by this harness.\n */\n protected async getRootHarnessLoader(): Promise {\n return this.locatorFactory.rootHarnessLoader();\n }\n}\n\n/**\n * Constructor for a ComponentHarness subclass. To be a valid ComponentHarnessConstructor, the\n * class must also have a static `hostSelector` property.\n */\nexport interface ComponentHarnessConstructor {\n new (locatorFactory: LocatorFactory): T;\n\n /**\n * `ComponentHarness` subclasses must specify a static `hostSelector` property that is used to\n * find the host element for the corresponding component. This property should match the selector\n * for the Angular component.\n */\n hostSelector: string;\n}\n\n/** A set of criteria that can be used to filter a list of `ComponentHarness` instances. */\nexport interface BaseHarnessFilters {\n /** Only find instances whose host element matches the given selector. */\n selector?: string;\n /** Only find instances that are nested under an element with the given selector. */\n ancestor?: string;\n}\n\n/**\n * A class used to associate a ComponentHarness class with predicate functions that can be used to\n * filter instances of the class to be matched.\n */\nexport class HarnessPredicate {\n private _predicates: AsyncPredicate[] = [];\n private _descriptions: string[] = [];\n private _ancestor: string;\n\n constructor(\n public harnessType: ComponentHarnessConstructor,\n options: BaseHarnessFilters,\n ) {\n this._ancestor = options.ancestor || '';\n if (this._ancestor) {\n this._descriptions.push(`has ancestor matching selector \"${this._ancestor}\"`);\n }\n const selector = options.selector;\n if (selector !== undefined) {\n this.add(`host matches selector \"${selector}\"`, async item => {\n return (await item.host()).matchesSelector(selector);\n });\n }\n }\n\n /**\n * Checks if the specified nullable string value matches the given pattern.\n * @param value The nullable string value to check, or a Promise resolving to the\n * nullable string value.\n * @param pattern The pattern the value is expected to match. If `pattern` is a string,\n * `value` is expected to match exactly. If `pattern` is a regex, a partial match is\n * allowed. If `pattern` is `null`, the value is expected to be `null`.\n * @return Whether the value matches the pattern.\n */\n static async stringMatches(\n value: string | null | Promise,\n pattern: string | RegExp | null,\n ): Promise {\n value = await value;\n if (pattern === null) {\n return value === null;\n } else if (value === null) {\n return false;\n }\n return typeof pattern === 'string' ? value === pattern : pattern.test(value);\n }\n\n /**\n * Adds a predicate function to be run against candidate harnesses.\n * @param description A description of this predicate that may be used in error messages.\n * @param predicate An async predicate function.\n * @return this (for method chaining).\n */\n add(description: string, predicate: AsyncPredicate) {\n this._descriptions.push(description);\n this._predicates.push(predicate);\n return this;\n }\n\n /**\n * Adds a predicate function that depends on an option value to be run against candidate\n * harnesses. If the option value is undefined, the predicate will be ignored.\n * @param name The name of the option (may be used in error messages).\n * @param option The option value.\n * @param predicate The predicate function to run if the option value is not undefined.\n * @return this (for method chaining).\n */\n addOption(name: string, option: O | undefined, predicate: AsyncOptionPredicate) {\n if (option !== undefined) {\n this.add(`${name} = ${_valueAsString(option)}`, item => predicate(item, option));\n }\n return this;\n }\n\n /**\n * Filters a list of harnesses on this predicate.\n * @param harnesses The list of harnesses to filter.\n * @return A list of harnesses that satisfy this predicate.\n */\n async filter(harnesses: T[]): Promise {\n if (harnesses.length === 0) {\n return [];\n }\n const results = await parallel(() => harnesses.map(h => this.evaluate(h)));\n return harnesses.filter((_, i) => results[i]);\n }\n\n /**\n * Evaluates whether the given harness satisfies this predicate.\n * @param harness The harness to check\n * @return A promise that resolves to true if the harness satisfies this predicate,\n * and resolves to false otherwise.\n */\n async evaluate(harness: T): Promise {\n const results = await parallel(() => this._predicates.map(p => p(harness)));\n return results.reduce((combined, current) => combined && current, true);\n }\n\n /** Gets a description of this predicate for use in error messages. */\n getDescription() {\n return this._descriptions.join(', ');\n }\n\n /** Gets the selector used to find candidate elements. */\n getSelector() {\n // We don't have to go through the extra trouble if there are no ancestors.\n if (!this._ancestor) {\n return (this.harnessType.hostSelector || '').trim();\n }\n\n const [ancestors, ancestorPlaceholders] = _splitAndEscapeSelector(this._ancestor);\n const [selectors, selectorPlaceholders] = _splitAndEscapeSelector(\n this.harnessType.hostSelector || '',\n );\n const result: string[] = [];\n\n // We have to add the ancestor to each part of the host compound selector, otherwise we can get\n // incorrect results. E.g. `.ancestor .a, .ancestor .b` vs `.ancestor .a, .b`.\n ancestors.forEach(escapedAncestor => {\n const ancestor = _restoreSelector(escapedAncestor, ancestorPlaceholders);\n return selectors.forEach(escapedSelector =>\n result.push(`${ancestor} ${_restoreSelector(escapedSelector, selectorPlaceholders)}`),\n );\n });\n\n return result.join(', ');\n }\n}\n\n/** Represent a value as a string for the purpose of logging. */\nfunction _valueAsString(value: unknown) {\n if (value === undefined) {\n return 'undefined';\n }\n try {\n // `JSON.stringify` doesn't handle RegExp properly, so we need a custom replacer.\n // Use a character that is unlikely to appear in real strings to denote the start and end of\n // the regex. This allows us to strip out the extra quotes around the value added by\n // `JSON.stringify`. Also do custom escaping on `\"` characters to prevent `JSON.stringify`\n // from escaping them as if they were part of a string.\n const stringifiedValue = JSON.stringify(value, (_, v) =>\n v instanceof RegExp\n ? `◬MAT_RE_ESCAPE◬${v.toString().replace(/\"/g, '◬MAT_RE_ESCAPE◬')}◬MAT_RE_ESCAPE◬`\n : v,\n );\n // Strip out the extra quotes around regexes and put back the manually escaped `\"` characters.\n return stringifiedValue\n .replace(/\"◬MAT_RE_ESCAPE◬|◬MAT_RE_ESCAPE◬\"/g, '')\n .replace(/◬MAT_RE_ESCAPE◬/g, '\"');\n } catch {\n // `JSON.stringify` will throw if the object is cyclical,\n // in this case the best we can do is report the value as `{...}`.\n return '{...}';\n }\n}\n\n/**\n * Splits up a compound selector into its parts and escapes any quoted content. The quoted content\n * has to be escaped, because it can contain commas which will throw throw us off when trying to\n * split it.\n * @param selector Selector to be split.\n * @returns The escaped string where any quoted content is replaced with a placeholder. E.g.\n * `[foo=\"bar\"]` turns into `[foo=__cdkPlaceholder-0__]`. Use `_restoreSelector` to restore\n * the placeholders.\n */\nfunction _splitAndEscapeSelector(selector: string): [parts: string[], placeholders: string[]] {\n const placeholders: string[] = [];\n\n // Note that the regex doesn't account for nested quotes so something like `\"ab'cd'e\"` will be\n // considered as two blocks. It's a bit of an edge case, but if we find that it's a problem,\n // we can make it a bit smarter using a loop. Use this for now since it's more readable and\n // compact. More complete implementation:\n // https://github.com/angular/angular/blob/bd34bc9e89f18a/packages/compiler/src/shadow_css.ts#L655\n const result = selector.replace(/([\"'][^[\"']*[\"'])/g, (_, keep) => {\n const replaceBy = `__cdkPlaceholder-${placeholders.length}__`;\n placeholders.push(keep);\n return replaceBy;\n });\n\n return [result.split(',').map(part => part.trim()), placeholders];\n}\n\n/** Restores a selector whose content was escaped in `_splitAndEscapeSelector`. */\nfunction _restoreSelector(selector: string, placeholders: string[]): string {\n return selector.replace(/__cdkPlaceholder-(\\d+)__/g, (_, index) => placeholders[+index]);\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 {parallel} from './change-detection';\nimport {\n ComponentHarness,\n ComponentHarnessConstructor,\n HarnessLoader,\n HarnessPredicate,\n HarnessQuery,\n LocatorFactory,\n LocatorFnResult,\n} from './component-harness';\nimport {TestElement} from './test-element';\n\n/** Parsed form of the queries passed to the `locatorFor*` methods. */\ntype ParsedQueries = {\n /** The full list of queries, in their original order. */\n allQueries: (string | HarnessPredicate)[];\n /**\n * A filtered view of `allQueries` containing only the queries that are looking for a\n * `ComponentHarness`\n */\n harnessQueries: HarnessPredicate[];\n /**\n * A filtered view of `allQueries` containing only the queries that are looking for a\n * `TestElement`\n */\n elementQueries: string[];\n /** The set of all `ComponentHarness` subclasses represented in the original query list. */\n harnessTypes: Set>;\n};\n\n/**\n * Base harness environment class that can be extended to allow `ComponentHarness`es to be used in\n * different test environments (e.g. testbed, protractor, etc.). This class implements the\n * functionality of both a `HarnessLoader` and `LocatorFactory`. This class is generic on the raw\n * element type, `E`, used by the particular test environment.\n */\nexport abstract class HarnessEnvironment implements HarnessLoader, LocatorFactory {\n /** The root element of this `HarnessEnvironment` as a `TestElement`. */\n get rootElement(): TestElement {\n this._rootElement = this._rootElement || this.createTestElement(this.rawRootElement);\n return this._rootElement;\n }\n set rootElement(element: TestElement) {\n this._rootElement = element;\n }\n private _rootElement: TestElement | undefined;\n\n protected constructor(\n /** The native root element of this `HarnessEnvironment`. */\n protected rawRootElement: E,\n ) {}\n\n /** Gets a locator factory rooted at the document root. */\n documentRootLocatorFactory(): LocatorFactory {\n return this.createEnvironment(this.getDocumentRoot());\n }\n\n /**\n * Creates an asynchronous locator function that can be used to find a `ComponentHarness` instance\n * or element under the root element of this `HarnessEnvironment`.\n *\n * For example, given the following DOM and assuming `DivHarness.hostSelector` is `'div'`\n *\n * ```html\n *
\n * ```\n *\n * then we expect:\n *\n * ```ts\n * await lf.locatorFor(DivHarness, 'div')() // Gets a `DivHarness` instance for #d1\n * await lf.locatorFor('div', DivHarness)() // Gets a `TestElement` instance for #d1\n * await lf.locatorFor('span')() // Throws because the `Promise` rejects\n * ```\n *\n * @param queries A list of queries specifying which harnesses and elements to search for:\n * - A `string` searches for elements matching the CSS selector specified by the string.\n * - A `ComponentHarness` constructor searches for `ComponentHarness` instances matching the\n * given class.\n * - A `HarnessPredicate` searches for `ComponentHarness` instances matching the given\n * predicate.\n * @return An asynchronous locator function that searches for and returns a `Promise` for the\n * first element or harness matching the given search criteria. Matches are ordered first by\n * order in the DOM, and second by order in the queries list. If no matches are found, the\n * `Promise` rejects. The type that the `Promise` resolves to is a union of all result types for\n * each query.\n */\n locatorFor | string)[]>(\n ...queries: T\n ): () => Promise> {\n return () =>\n _assertResultFound(\n this._getAllHarnessesAndTestElements(queries),\n _getDescriptionForLocatorForQueries(queries),\n );\n }\n\n /**\n * Creates an asynchronous locator function that can be used to find a `ComponentHarness` instance\n * or element under the root element of this `HarnessEnvironmnet`.\n *\n * For example, given the following DOM and assuming `DivHarness.hostSelector` is `'div'`\n *\n * ```html\n *
\n * ```\n *\n * then we expect:\n *\n * ```ts\n * await lf.locatorForOptional(DivHarness, 'div')() // Gets a `DivHarness` instance for #d1\n * await lf.locatorForOptional('div', DivHarness)() // Gets a `TestElement` instance for #d1\n * await lf.locatorForOptional('span')() // Gets `null`\n * ```\n *\n * @param queries A list of queries specifying which harnesses and elements to search for:\n * - A `string` searches for elements matching the CSS selector specified by the string.\n * - A `ComponentHarness` constructor searches for `ComponentHarness` instances matching the\n * given class.\n * - A `HarnessPredicate` searches for `ComponentHarness` instances matching the given\n * predicate.\n * @return An asynchronous locator function that searches for and returns a `Promise` for the\n * first element or harness matching the given search criteria. Matches are ordered first by\n * order in the DOM, and second by order in the queries list. If no matches are found, the\n * `Promise` is resolved with `null`. The type that the `Promise` resolves to is a union of all\n * result types for each query or null.\n */\n locatorForOptional | string)[]>(\n ...queries: T\n ): () => Promise | null> {\n return async () => (await this._getAllHarnessesAndTestElements(queries))[0] || null;\n }\n\n /**\n * Creates an asynchronous locator function that can be used to find `ComponentHarness` instances\n * or elements under the root element of this `HarnessEnvironment`.\n *\n * For example, given the following DOM and assuming `DivHarness.hostSelector` is `'div'` and\n * `IdIsD1Harness.hostSelector` is `'#d1'`\n *\n * ```html\n *
\n * ```\n *\n * then we expect:\n *\n * ```ts\n * // Gets [DivHarness for #d1, TestElement for #d1, DivHarness for #d2, TestElement for #d2]\n * await lf.locatorForAll(DivHarness, 'div')()\n * // Gets [TestElement for #d1, TestElement for #d2]\n * await lf.locatorForAll('div', '#d1')()\n * // Gets [DivHarness for #d1, IdIsD1Harness for #d1, DivHarness for #d2]\n * await lf.locatorForAll(DivHarness, IdIsD1Harness)()\n * // Gets []\n * await lf.locatorForAll('span')()\n * ```\n *\n * @param queries A list of queries specifying which harnesses and elements to search for:\n * - A `string` searches for elements matching the CSS selector specified by the string.\n * - A `ComponentHarness` constructor searches for `ComponentHarness` instances matching the\n * given class.\n * - A `HarnessPredicate` searches for `ComponentHarness` instances matching the given\n * predicate.\n * @return An asynchronous locator function that searches for and returns a `Promise` for all\n * elements and harnesses matching the given search criteria. Matches are ordered first by\n * order in the DOM, and second by order in the queries list. If an element matches more than\n * one `ComponentHarness` class, the locator gets an instance of each for the same element. If\n * an element matches multiple `string` selectors, only one `TestElement` instance is returned\n * for that element. The type that the `Promise` resolves to is an array where each element is\n * the union of all result types for each query.\n */\n locatorForAll | string)[]>(\n ...queries: T\n ): () => Promise[]> {\n return () => this._getAllHarnessesAndTestElements(queries);\n }\n\n /** @return A `HarnessLoader` rooted at the root element of this `HarnessEnvironment`. */\n async rootHarnessLoader(): Promise {\n return this;\n }\n\n /**\n * Gets a `HarnessLoader` instance for an element under the root of this `HarnessEnvironment`.\n * @param selector The selector for the root element.\n * @return A `HarnessLoader` rooted at the first element matching the given selector.\n * @throws If no matching element is found for the given selector.\n */\n async harnessLoaderFor(selector: string): Promise {\n return this.createEnvironment(\n await _assertResultFound(this.getAllRawElements(selector), [\n _getDescriptionForHarnessLoaderQuery(selector),\n ]),\n );\n }\n\n /**\n * Gets a `HarnessLoader` instance for an element under the root of this `HarnessEnvironment`.\n * @param selector The selector for the root element.\n * @return A `HarnessLoader` rooted at the first element matching the given selector, or null if\n * no matching element is found.\n */\n async harnessLoaderForOptional(selector: string): Promise {\n const elements = await this.getAllRawElements(selector);\n return elements[0] ? this.createEnvironment(elements[0]) : null;\n }\n\n /**\n * Gets a list of `HarnessLoader` instances, one for each matching element.\n * @param selector The selector for the root element.\n * @return A list of `HarnessLoader`, one rooted at each element matching the given selector.\n */\n async harnessLoaderForAll(selector: string): Promise {\n const elements = await this.getAllRawElements(selector);\n return elements.map(element => this.createEnvironment(element));\n }\n\n /**\n * Searches for an instance of the component corresponding to the given harness type under the\n * `HarnessEnvironment`'s root element, and returns a `ComponentHarness` for that instance. If\n * multiple matching components are found, a harness for the first one is returned. If no matching\n * component is found, an error is thrown.\n * @param query A query for a harness to create\n * @return An instance of the given harness type\n * @throws If a matching component instance can't be found.\n */\n getHarness(query: HarnessQuery): Promise {\n return this.locatorFor(query)();\n }\n\n /**\n * Searches for an instance of the component corresponding to the given harness type under the\n * `HarnessEnvironment`'s root element, and returns a `ComponentHarness` for that instance. If\n * multiple matching components are found, a harness for the first one is returned. If no matching\n * component is found, null is returned.\n * @param query A query for a harness to create\n * @return An instance of the given harness type (or null if not found).\n */\n getHarnessOrNull(query: HarnessQuery): Promise {\n return this.locatorForOptional(query)();\n }\n\n /**\n * Searches for an instance of the component corresponding to the given harness type and index\n * under the `HarnessEnvironment`'s root element, and returns a `ComponentHarness` for that\n * instance. The index specifies the offset of the component to find. If no matching\n * component is found at that index, an error is thrown.\n * @param query A query for a harness to create\n * @param index The zero-indexed offset of the component to find\n * @return An instance of the given harness type\n * @throws If a matching component instance can't be found.\n */\n async getHarnessAtIndex(\n query: HarnessQuery,\n offset: number,\n ): Promise {\n if (offset < 0) {\n throw Error('Index must not be negative');\n }\n const harnesses = await this.locatorForAll(query)();\n if (offset >= harnesses.length) {\n throw Error(`No harness was located at index ${offset}`);\n }\n return harnesses[offset];\n }\n\n /**\n * Searches for all instances of the component corresponding to the given harness type under the\n * `HarnessEnvironment`'s root element, and returns a list `ComponentHarness` for each instance.\n * @param query A query for a harness to create\n * @return A list instances of the given harness type.\n */\n getAllHarnesses(query: HarnessQuery): Promise {\n return this.locatorForAll(query)();\n }\n\n /**\n * Searches for all instance of the component corresponding to the given harness type under the\n * `HarnessEnvironment`'s root element, and returns the number that were found.\n * @param query A query for a harness to create\n * @return The number of instances that were found.\n */\n async countHarnesses(query: HarnessQuery): Promise {\n return (await this.locatorForAll(query)()).length;\n }\n\n /**\n * Searches for an instance of the component corresponding to the given harness type under the\n * `HarnessEnvironment`'s root element, and returns a boolean indicating if any were found.\n * @param query A query for a harness to create\n * @return A boolean indicating if an instance was found.\n */\n async hasHarness(query: HarnessQuery): Promise {\n return (await this.locatorForOptional(query)()) !== null;\n }\n\n /**\n * Searches for an element with the given selector under the evironment's root element,\n * and returns a `HarnessLoader` rooted at the matching element. If multiple elements match the\n * selector, the first is used. If no elements match, an error is thrown.\n * @param selector The selector for the root element of the new `HarnessLoader`\n * @return A `HarnessLoader` rooted at the element matching the given selector.\n * @throws If a matching element can't be found.\n */\n async getChildLoader(selector: string): Promise {\n return this.createEnvironment(\n await _assertResultFound(this.getAllRawElements(selector), [\n _getDescriptionForHarnessLoaderQuery(selector),\n ]),\n );\n }\n\n /**\n * Searches for all elements with the given selector under the environment's root element,\n * and returns an array of `HarnessLoader`s, one for each matching element, rooted at that\n * element.\n * @param selector The selector for the root element of the new `HarnessLoader`\n * @return A list of `HarnessLoader`s, one for each matching element, rooted at that element.\n */\n async getAllChildLoaders(selector: string): Promise {\n return (await this.getAllRawElements(selector)).map(e => this.createEnvironment(e));\n }\n\n /** Creates a `ComponentHarness` for the given harness type with the given raw host element. */\n protected createComponentHarness(\n harnessType: ComponentHarnessConstructor,\n element: E,\n ): T {\n return new harnessType(this.createEnvironment(element));\n }\n\n /**\n * Flushes change detection and async tasks captured in the Angular zone.\n * In most cases it should not be necessary to call this manually. However, there may be some edge\n * cases where it is needed to fully flush animation events.\n * This is an abstrct method that must be implemented by subclasses.\n */\n abstract forceStabilize(): Promise;\n\n /**\n * Waits for all scheduled or running async tasks to complete. This allows harness\n * authors to wait for async tasks outside of the Angular zone.\n * This is an abstrct method that must be implemented by subclasses.\n */\n abstract waitForTasksOutsideAngular(): Promise;\n\n /** Gets the root element for the document. */\n protected abstract getDocumentRoot(): E;\n\n /** Creates a `TestElement` from a raw element. */\n protected abstract createTestElement(element: E): TestElement;\n\n /** Creates a `HarnessEnvironment` rooted at the given raw element. */\n protected abstract createEnvironment(element: E): HarnessEnvironment;\n\n /**\n * Gets a list of all elements matching the given selector under this environment's root element.\n */\n protected abstract getAllRawElements(selector: string): Promise;\n\n /**\n * Matches the given raw elements with the given list of element and harness queries to produce a\n * list of matched harnesses and test elements.\n */\n private async _getAllHarnessesAndTestElements | string)[]>(\n queries: T,\n ): Promise[]> {\n if (!queries.length) {\n throw Error('CDK Component harness query must contain at least one element.');\n }\n\n const {allQueries, harnessQueries, elementQueries, harnessTypes} = _parseQueries(queries);\n\n // Combine all of the queries into one large comma-delimited selector and use it to get all raw\n // elements matching any of the individual queries.\n const rawElements = await this.getAllRawElements(\n [...elementQueries, ...harnessQueries.map(predicate => predicate.getSelector())].join(','),\n );\n\n // If every query is searching for the same harness subclass, we know every result corresponds\n // to an instance of that subclass. Likewise, if every query is for a `TestElement`, we know\n // every result corresponds to a `TestElement`. Otherwise we need to verify which result was\n // found by which selector so it can be matched to the appropriate instance.\n const skipSelectorCheck =\n (elementQueries.length === 0 && harnessTypes.size === 1) || harnessQueries.length === 0;\n\n const perElementMatches = await parallel(() =>\n rawElements.map(async rawElement => {\n const testElement = this.createTestElement(rawElement);\n const allResultsForElement = await parallel(\n // For each query, get `null` if it doesn't match, or a `TestElement` or\n // `ComponentHarness` as appropriate if it does match. This gives us everything that\n // matches the current raw element, but it may contain duplicate entries (e.g.\n // multiple `TestElement` or multiple `ComponentHarness` of the same type).\n () =>\n allQueries.map(query =>\n this._getQueryResultForElement(query, rawElement, testElement, skipSelectorCheck),\n ),\n );\n return _removeDuplicateQueryResults(allResultsForElement);\n }),\n );\n return ([] as any).concat(...perElementMatches);\n }\n\n /**\n * Check whether the given query matches the given element, if it does return the matched\n * `TestElement` or `ComponentHarness`, if it does not, return null. In cases where the caller\n * knows for sure that the query matches the element's selector, `skipSelectorCheck` can be used\n * to skip verification and optimize performance.\n */\n private async _getQueryResultForElement(\n query: string | HarnessPredicate,\n rawElement: E,\n testElement: TestElement,\n skipSelectorCheck: boolean = false,\n ): Promise {\n if (typeof query === 'string') {\n return skipSelectorCheck || (await testElement.matchesSelector(query)) ? testElement : null;\n }\n if (skipSelectorCheck || (await testElement.matchesSelector(query.getSelector()))) {\n const harness = this.createComponentHarness(query.harnessType, rawElement);\n return (await query.evaluate(harness)) ? harness : null;\n }\n return null;\n }\n}\n\n/**\n * Parses a list of queries in the format accepted by the `locatorFor*` methods into an easier to\n * work with format.\n */\nfunction _parseQueries | string)[]>(\n queries: T,\n): ParsedQueries & ComponentHarness> {\n const allQueries = [];\n const harnessQueries = [];\n const elementQueries = [];\n const harnessTypes = new Set<\n ComponentHarnessConstructor & ComponentHarness>\n >();\n\n for (const query of queries) {\n if (typeof query === 'string') {\n allQueries.push(query);\n elementQueries.push(query);\n } else {\n const predicate = query instanceof HarnessPredicate ? query : new HarnessPredicate(query, {});\n allQueries.push(predicate);\n harnessQueries.push(predicate);\n harnessTypes.add(predicate.harnessType);\n }\n }\n\n return {allQueries, harnessQueries, elementQueries, harnessTypes};\n}\n\n/**\n * Removes duplicate query results for a particular element. (e.g. multiple `TestElement`\n * instances or multiple instances of the same `ComponentHarness` class.\n */\nasync function _removeDuplicateQueryResults(\n results: T,\n): Promise {\n let testElementMatched = false;\n let matchedHarnessTypes = new Set();\n const dedupedMatches = [];\n for (const result of results) {\n if (!result) {\n continue;\n }\n if (result instanceof ComponentHarness) {\n if (!matchedHarnessTypes.has(result.constructor)) {\n matchedHarnessTypes.add(result.constructor);\n dedupedMatches.push(result);\n }\n } else if (!testElementMatched) {\n testElementMatched = true;\n dedupedMatches.push(result);\n }\n }\n return dedupedMatches as T;\n}\n\n/** Verifies that there is at least one result in an array. */\nasync function _assertResultFound(\n results: Promise,\n queryDescriptions: string[],\n): Promise {\n const result = (await results)[0];\n if (result == undefined) {\n throw Error(\n `Failed to find element matching one of the following queries:\\n` +\n queryDescriptions.map(desc => `(${desc})`).join(',\\n'),\n );\n }\n return result;\n}\n\n/** Gets a list of description strings from a list of queries. */\nfunction _getDescriptionForLocatorForQueries(queries: (string | HarnessQuery)[]) {\n return queries.map(query =>\n typeof query === 'string'\n ? _getDescriptionForTestElementQuery(query)\n : _getDescriptionForComponentHarnessQuery(query),\n );\n}\n\n/** Gets a description string for a `ComponentHarness` query. */\nfunction _getDescriptionForComponentHarnessQuery(query: HarnessQuery) {\n const harnessPredicate =\n query instanceof HarnessPredicate ? query : new HarnessPredicate(query, {});\n const {name, hostSelector} = harnessPredicate.harnessType;\n const description = `${name} with host element matching selector: \"${hostSelector}\"`;\n const constraints = harnessPredicate.getDescription();\n return (\n description +\n (constraints ? ` satisfying the constraints: ${harnessPredicate.getDescription()}` : '')\n );\n}\n\n/** Gets a description string for a `TestElement` query. */\nfunction _getDescriptionForTestElementQuery(selector: string) {\n return `TestElement for element matching selector: \"${selector}\"`;\n}\n\n/** Gets a description string for a `HarnessLoader` query. */\nfunction _getDescriptionForHarnessLoaderQuery(selector: string) {\n return `HarnessLoader for element matching selector: \"${selector}\"`;\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 {ElementDimensions} from './element-dimensions';\n\n/** Modifier keys that may be held while typing. */\nexport interface ModifierKeys {\n control?: boolean;\n alt?: boolean;\n shift?: boolean;\n meta?: boolean;\n}\n\n/** Data that can be attached to a custom event dispatched from a `TestElement`. */\nexport type EventData =\n | string\n | number\n | boolean\n | Function\n | undefined\n | null\n | EventData[]\n | {[key: string]: EventData};\n\n/** An enum of non-text keys that can be used with the `sendKeys` method. */\n// NOTE: This is a separate enum from `@angular/cdk/keycodes` because we don't necessarily want to\n// support every possible keyCode. We also can't rely on Protractor's `Key` because we don't want a\n// dependency on any particular testing framework here. Instead we'll just maintain this supported\n// list of keys and let individual concrete `HarnessEnvironment` classes map them to whatever key\n// representation is used in its respective testing framework.\n// tslint:disable-next-line:prefer-const-enum Seems like this causes some issues with System.js\nexport enum TestKey {\n BACKSPACE,\n TAB,\n ENTER,\n SHIFT,\n CONTROL,\n ALT,\n ESCAPE,\n PAGE_UP,\n PAGE_DOWN,\n END,\n HOME,\n LEFT_ARROW,\n UP_ARROW,\n RIGHT_ARROW,\n DOWN_ARROW,\n INSERT,\n DELETE,\n F1,\n F2,\n F3,\n F4,\n F5,\n F6,\n F7,\n F8,\n F9,\n F10,\n F11,\n F12,\n META,\n COMMA, // Commas are a common separator key.\n}\n\n/**\n * This acts as a common interface for DOM elements across both unit and e2e tests. It is the\n * interface through which the ComponentHarness interacts with the component's DOM.\n */\nexport interface TestElement {\n /** Blur the element. */\n blur(): Promise;\n\n /** Clear the element's input (for input and textarea elements only). */\n clear(): Promise;\n\n /**\n * Click the element at the default location for the current environment. If you need to guarantee\n * the element is clicked at a specific location, consider using `click('center')` or\n * `click(x, y)` instead.\n */\n click(modifiers?: ModifierKeys): Promise;\n\n /** Click the element at the element's center. */\n click(location: 'center', modifiers?: ModifierKeys): Promise;\n\n /**\n * Click the element at the specified coordinates relative to the top-left of the element.\n * @param relativeX Coordinate within the element, along the X-axis at which to click.\n * @param relativeY Coordinate within the element, along the Y-axis at which to click.\n * @param modifiers Modifier keys held while clicking\n */\n click(relativeX: number, relativeY: number, modifiers?: ModifierKeys): Promise;\n\n /**\n * Right clicks on the element at the specified coordinates relative to the top-left of it.\n * @param relativeX Coordinate within the element, along the X-axis at which to click.\n * @param relativeY Coordinate within the element, along the Y-axis at which to click.\n * @param modifiers Modifier keys held while clicking\n */\n rightClick(relativeX: number, relativeY: number, modifiers?: ModifierKeys): Promise;\n\n /** Focus the element. */\n focus(): Promise;\n\n /** Get the computed value of the given CSS property for the element. */\n getCssValue(property: string): Promise;\n\n /** Hovers the mouse over the element. */\n hover(): Promise;\n\n /** Moves the mouse away from the element. */\n mouseAway(): Promise;\n\n /**\n * Sends the given string to the input as a series of key presses. Also fires input events\n * and attempts to add the string to the Element's value. Note that some environments cannot\n * reproduce native browser behavior for keyboard shortcuts such as Tab, Ctrl + A, etc.\n * @throws An error if no keys have been specified.\n */\n sendKeys(...keys: (string | TestKey)[]): Promise;\n\n /**\n * Sends the given string to the input as a series of key presses. Also fires input\n * events and attempts to add the string to the Element's value.\n * @throws An error if no keys have been specified.\n */\n sendKeys(modifiers: ModifierKeys, ...keys: (string | TestKey)[]): Promise;\n\n /**\n * Gets the text from the element.\n * @param options Options that affect what text is included.\n */\n text(options?: TextOptions): Promise;\n\n /**\n * Sets the value of a `contenteditable` element.\n * @param value Value to be set on the element.\n */\n setContenteditableValue(value: string): Promise;\n\n /** Gets the value for the given attribute from the element. */\n getAttribute(name: string): Promise;\n\n /** Checks whether the element has the given class. */\n hasClass(name: string): Promise;\n\n /** Gets the dimensions of the element. */\n getDimensions(): Promise;\n\n /** Gets the value of a property of an element. */\n getProperty(name: string): Promise;\n\n /** Checks whether this element matches the given selector. */\n matchesSelector(selector: string): Promise;\n\n /** Checks whether the element is focused. */\n isFocused(): Promise;\n\n /** Sets the value of a property of an input. */\n setInputValue(value: string): Promise;\n\n // Note that ideally here we'd be selecting options based on their value, rather than their\n // index, but we're limited by `@angular/forms` which will modify the option value in some cases.\n // Since the value will be truncated, we can't rely on it to do the lookup in the DOM. See:\n // https://github.com/angular/angular/blob/main/packages/forms/src/directives/select_control_value_accessor.ts#L19\n /** Selects the options at the specified indexes inside of a native `select` element. */\n selectOptions(...optionIndexes: number[]): Promise;\n\n /**\n * Dispatches an event with a particular name.\n * @param name Name of the event to be dispatched.\n */\n dispatchEvent(name: string, data?: Record): Promise;\n}\n\n/**\n * Options that affect the text returned by `TestElement.text`.\n */\nexport interface TextOptions {\n /** Optional selector for elements whose content should be excluded from the text string. */\n exclude?: string;\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\n/**\n * Returns an error which reports that no keys have been specified.\n * @docs-private\n */\nexport function getNoKeysSpecifiedError() {\n return Error('No keys have been specified.');\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\n/**\n * Gets text of element excluding certain selectors within the element.\n * @param element Element to get text from,\n * @param excludeSelector Selector identifying which elements to exclude,\n */\nexport function _getTextWithExcludedElements(element: Element, excludeSelector: string) {\n const clone = element.cloneNode(true) as Element;\n const exclusions = clone.querySelectorAll(excludeSelector);\n for (let i = 0; i < exclusions.length; i++) {\n exclusions[i].remove();\n }\n return (clone.textContent || '').trim();\n}\n"],"names":["autoChangeDetectionSubject","BehaviorSubject","isDisabled","autoChangeDetectionSubscription","defaultAutoChangeDetectionHandler","status","onDetectChangesNow","handleAutoChangeDetectionStatus","handler","stopHandlingAutoChangeDetectionStatus","subscribe","unsubscribe","batchChangeDetection","fn","triggerBeforeAndAfter","getValue","Promise","resolve","next","manualChangeDetection","parallel","values","all","ComponentHarness","locatorFactory","constructor","host","rootElement","documentRootLocatorFactory","locatorFor","queries","locatorForOptional","locatorForAll","forceStabilize","waitForTasksOutsideAngular","ContentContainerComponentHarness","getChildLoader","selector","getRootHarnessLoader","getAllChildLoaders","getHarness","query","getHarnessOrNull","getHarnessAtIndex","index","getAllHarnesses","countHarnesses","hasHarness","rootHarnessLoader","HarnessPredicate","harnessType","_predicates","_descriptions","_ancestor","options","ancestor","push","undefined","add","item","matchesSelector","stringMatches","value","pattern","test","description","predicate","addOption","name","option","_valueAsString","filter","harnesses","length","results","map","h","evaluate","_","i","harness","p","reduce","combined","current","getDescription","join","getSelector","hostSelector","trim","ancestors","ancestorPlaceholders","_splitAndEscapeSelector","selectors","selectorPlaceholders","result","forEach","escapedAncestor","_restoreSelector","escapedSelector","stringifiedValue","JSON","stringify","v","RegExp","toString","replace","placeholders","keep","replaceBy","split","part","HarnessEnvironment","rawRootElement","_rootElement","createTestElement","element","createEnvironment","getDocumentRoot","_assertResultFound","_getAllHarnessesAndTestElements","_getDescriptionForLocatorForQueries","harnessLoaderFor","getAllRawElements","_getDescriptionForHarnessLoaderQuery","harnessLoaderForOptional","elements","harnessLoaderForAll","offset","Error","e","createComponentHarness","allQueries","harnessQueries","elementQueries","harnessTypes","_parseQueries","rawElements","skipSelectorCheck","size","perElementMatches","rawElement","testElement","allResultsForElement","_getQueryResultForElement","_removeDuplicateQueryResults","concat","Set","testElementMatched","matchedHarnessTypes","dedupedMatches","has","queryDescriptions","desc","_getDescriptionForTestElementQuery","_getDescriptionForComponentHarnessQuery","harnessPredicate","constraints","TestKey","getNoKeysSpecifiedError","_getTextWithExcludedElements","excludeSelector","clone","cloneNode","exclusions","querySelectorAll","remove","textContent"],"mappings":"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"}