blob: a132d691be55b614fab7a6f57bf56bf102cf3f7f [file] [log] [blame]
{"version":3,"file":"testing.js","sources":["../../../../../../src/cdk/testing/change-detection.ts","../../../../../../src/cdk/testing/component-harness.ts","../../../../../../src/cdk/testing/harness-environment.ts","../../../../../../src/cdk/testing/test-element.ts","../../../../../../src/cdk/testing/element-dimensions.ts","../../../../../../src/cdk/testing/text-filtering.ts","../../../../../../src/cdk/testing/public-api.ts","../../../../../../src/cdk/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 {BehaviorSubject, Subscription} from 'rxjs';\n\n/** Represents the status of auto change detection. */\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<AutoChangeDetectionStatus>({\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 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<T>(fn: () => Promise<T>, 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 => autoChangeDetectionSubject.next({\n isDisabled: true,\n onDetectChangesNow: resolve as () => void,\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 => autoChangeDetectionSubject.next({\n isDisabled: false,\n onDetectChangesNow: resolve as () => void,\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<T>(fn: () => Promise<T>) {\n return batchChangeDetection(fn, false);\n}\n\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<T1, T2, T3, T4, T5>(\n values: () =>\n [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>,\n T5 | PromiseLike<T5>\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<T1, T2, T3, T4>(\n values: () =>\n [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>]):\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<T1, T2, T3>(\n values: () => [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>]):\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<T1, T2>(values: () => [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]):\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<T>(values: () => (T | PromiseLike<T>)[]): Promise<T[]>;\n\nexport async function parallel<T>(values: () => Iterable<T | PromiseLike<T>>): Promise<T[]> {\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.io/license\n */\n\nimport {parallel} from './change-detection';\nimport {TestElement} from './test-element';\n\n/** An async function that returns a promise when called. */\nexport type AsyncFactoryFn<T> = () => Promise<T>;\n\n/** An async function that takes an item and returns a boolean promise */\nexport type AsyncPredicate<T> = (item: T) => Promise<boolean>;\n\n/** An async function that takes an item and an option value and returns a boolean promise. */\nexport type AsyncOptionPredicate<T, O> = (item: T, option: O) => Promise<boolean>;\n\n/**\n * A query for a `ComponentHarness`, which is expressed as either a `ComponentHarnessConstructor` or\n * a `HarnessPredicate`.\n */\nexport type HarnessQuery<T extends ComponentHarness> =\n ComponentHarnessConstructor<T> | HarnessPredicate<T>;\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<C1>`, it means that the result\n * might be a harness of type `C1`\n * - If one of the queries is for a `HarnessPredicate<C2>`, 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 * e.g.\n * The type:\n * `LocatorFnResult&lt;[\n * ComponentHarnessConstructor&lt;MyHarness&gt;,\n * HarnessPredicate&lt;MyOtherHarness&gt;,\n * string\n * ]&gt;`\n * is equivalent to:\n * `MyHarness | MyOtherHarness | TestElement`.\n */\nexport type LocatorFnResult<T extends (HarnessQuery<any> | string)[]> = {\n [I in keyof T]:\n // Map `ComponentHarnessConstructor<C>` to `C`.\n T[I] extends new (...args: any[]) => infer C ? C :\n // Map `HarnessPredicate<C>` to `C`.\n T[I] extends { harnessType: new (...args: any[]) => infer C } ? C :\n // Map `string` to `TestElement`.\n T[I] extends string ? TestElement :\n // Map everything else to `never` (should not happen due to the type constraint on `T`).\n never;\n}[number];\n\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<HarnessLoader>;\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<HarnessLoader[]>;\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<T extends ComponentHarness>(query: HarnessQuery<T>): Promise<T>;\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<T extends ComponentHarness>(query: HarnessQuery<T>): Promise<T[]>;\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 * @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 * e.g. Given the following DOM: `<div id=\"d1\" /><div id=\"d2\" />`, and assuming\n * `DivHarness.hostSelector === 'div'`:\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 locatorFor<T extends (HarnessQuery<any> | string)[]>(...queries: T):\n AsyncFactoryFn<LocatorFnResult<T>>;\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 * @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 * e.g. Given the following DOM: `<div id=\"d1\" /><div id=\"d2\" />`, and assuming\n * `DivHarness.hostSelector === 'div'`:\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 locatorForOptional<T extends (HarnessQuery<any> | string)[]>(...queries: T):\n AsyncFactoryFn<LocatorFnResult<T> | 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 * @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 * e.g. Given the following DOM: `<div id=\"d1\" /><div id=\"d2\" />`, and assuming\n * `DivHarness.hostSelector === 'div'` and `IdIsD1Harness.hostSelector === '#d1'`:\n * - `await lf.locatorForAll(DivHarness, 'div')()` gets `[\n * DivHarness, // for #d1\n * TestElement, // for #d1\n * DivHarness, // for #d2\n * TestElement // for #d2\n * ]`\n * - `await lf.locatorForAll('div', '#d1')()` gets `[\n * TestElement, // for #d1\n * TestElement // for #d2\n * ]`\n * - `await lf.locatorForAll(DivHarness, IdIsD1Harness)()` gets `[\n * DivHarness, // for #d1\n * IdIsD1Harness, // for #d1\n * DivHarness // for #d2\n * ]`\n * - `await lf.locatorForAll('span')()` gets `[]`.\n */\n locatorForAll<T extends (HarnessQuery<any> | string)[]>(...queries: T):\n AsyncFactoryFn<LocatorFnResult<T>[]>;\n\n /** @return A `HarnessLoader` rooted at the root element of this `LocatorFactory`. */\n rootHarnessLoader(): Promise<HarnessLoader>;\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<HarnessLoader>;\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<HarnessLoader | null>;\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<HarnessLoader[]>;\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<void>;\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<void>;\n}\n\n/**\n * Base class for component harnesses that all component harness authors should extend. This base\n * component harness provides the basic ability to locate element and sub-component harness. It\n * should be inherited when defining user's own harness.\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<TestElement> {\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 * @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 * e.g. Given the following DOM: `<div id=\"d1\" /><div id=\"d2\" />`, and assuming\n * `DivHarness.hostSelector === 'div'`:\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 protected locatorFor<T extends (HarnessQuery<any> | string)[]>(...queries: T):\n AsyncFactoryFn<LocatorFnResult<T>> {\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 * @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 * e.g. Given the following DOM: `<div id=\"d1\" /><div id=\"d2\" />`, and assuming\n * `DivHarness.hostSelector === 'div'`:\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 protected locatorForOptional<T extends (HarnessQuery<any> | string)[]>(...queries: T):\n AsyncFactoryFn<LocatorFnResult<T> | 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 * @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 * e.g. Given the following DOM: `<div id=\"d1\" /><div id=\"d2\" />`, and assuming\n * `DivHarness.hostSelector === 'div'` and `IdIsD1Harness.hostSelector === '#d1'`:\n * - `await ch.locatorForAll(DivHarness, 'div')()` gets `[\n * DivHarness, // for #d1\n * TestElement, // for #d1\n * DivHarness, // for #d2\n * TestElement // for #d2\n * ]`\n * - `await ch.locatorForAll('div', '#d1')()` gets `[\n * TestElement, // for #d1\n * TestElement // for #d2\n * ]`\n * - `await ch.locatorForAll(DivHarness, IdIsD1Harness)()` gets `[\n * DivHarness, // for #d1\n * IdIsD1Harness, // for #d1\n * DivHarness // for #d2\n * ]`\n * - `await ch.locatorForAll('span')()` gets `[]`.\n */\n protected locatorForAll<T extends (HarnessQuery<any> | string)[]>(...queries: T):\n AsyncFactoryFn<LocatorFnResult<T>[]> {\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/**\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 `<ng-content>` of the component.\n */\nexport abstract class ContentContainerComponentHarness<S extends string = string>\n extends ComponentHarness implements HarnessLoader {\n\n async getChildLoader(selector: S): Promise<HarnessLoader> {\n return (await this.getRootHarnessLoader()).getChildLoader(selector);\n }\n\n async getAllChildLoaders(selector: S): Promise<HarnessLoader[]> {\n return (await this.getRootHarnessLoader()).getAllChildLoaders(selector);\n }\n\n async getHarness<T extends ComponentHarness>(query: HarnessQuery<T>): Promise<T> {\n return (await this.getRootHarnessLoader()).getHarness(query);\n }\n\n async getAllHarnesses<T extends ComponentHarness>(query: HarnessQuery<T>): Promise<T[]> {\n return (await this.getRootHarnessLoader()).getAllHarnesses(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<HarnessLoader> {\n return this.locatorFactory.rootHarnessLoader();\n }\n}\n\n/** Constructor for a ComponentHarness subclass. */\nexport interface ComponentHarnessConstructor<T extends ComponentHarness> {\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 predicates functions that can be used to\n * filter instances of the class.\n */\nexport class HarnessPredicate<T extends ComponentHarness> {\n private _predicates: AsyncPredicate<T>[] = [];\n private _descriptions: string[] = [];\n private _ancestor: string;\n\n constructor(public harnessType: ComponentHarnessConstructor<T>, options: BaseHarnessFilters) {\n this._addBaseOptions(options);\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(value: string | null | Promise<string | null>,\n pattern: string | RegExp | null): Promise<boolean> {\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<T>) {\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<O>(name: string, option: O | undefined, predicate: AsyncOptionPredicate<T, O>) {\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<T[]> {\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<boolean> {\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] =\n _splitAndEscapeSelector(this.harnessType.hostSelector || '');\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 return result.join(', ');\n }\n\n /** Adds base options common to all harness types. */\n private _addBaseOptions(options: BaseHarnessFilters) {\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/** Represent a value as a string for the purpose of logging. */\nfunction _valueAsString(value: unknown) {\n if (value === undefined) {\n return 'undefined';\n }\n // `JSON.stringify` doesn't handle RegExp properly, so we need a custom replacer.\n try {\n return JSON.stringify(value, (_, v) => {\n if (v instanceof RegExp) {\n return `/${v.toString()}/`;\n }\n\n return typeof v === 'string' ? v.replace('/\\//g', '\\\\/') : v;\n }).replace(/\"\\/\\//g, '\\\\/').replace(/\\/\\/\"/g, '\\\\/').replace(/\\\\\\//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.io/license\n */\n\nimport {parallel} from './change-detection';\nimport {\n AsyncFactoryFn,\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<T extends ComponentHarness> = {\n /** The full list of queries, in their original order. */\n allQueries: (string | HarnessPredicate<T>)[],\n /**\n * A filtered view of `allQueries` containing only the queries that are looking for a\n * `ComponentHarness`\n */\n harnessQueries: HarnessPredicate<T>[],\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<ComponentHarnessConstructor<T>>,\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<E> implements HarnessLoader, LocatorFactory {\n // Implemented as part of the `LocatorFactory` interface.\n rootElement: TestElement;\n\n protected constructor(protected rawRootElement: E) {\n this.rootElement = this.createTestElement(rawRootElement);\n }\n\n // Implemented as part of the `LocatorFactory` interface.\n documentRootLocatorFactory(): LocatorFactory {\n return this.createEnvironment(this.getDocumentRoot());\n }\n\n // Implemented as part of the `LocatorFactory` interface.\n locatorFor<T extends (HarnessQuery<any> | string)[]>(...queries: T):\n AsyncFactoryFn<LocatorFnResult<T>> {\n return () => _assertResultFound(\n this._getAllHarnessesAndTestElements(queries),\n _getDescriptionForLocatorForQueries(queries));\n }\n\n // Implemented as part of the `LocatorFactory` interface.\n locatorForOptional<T extends (HarnessQuery<any> | string)[]>(...queries: T):\n AsyncFactoryFn<LocatorFnResult<T> | null> {\n return async () => (await this._getAllHarnessesAndTestElements(queries))[0] || null;\n }\n\n // Implemented as part of the `LocatorFactory` interface.\n locatorForAll<T extends (HarnessQuery<any> | string)[]>(...queries: T):\n AsyncFactoryFn<LocatorFnResult<T>[]> {\n return () => this._getAllHarnessesAndTestElements(queries);\n }\n\n // Implemented as part of the `LocatorFactory` interface.\n async rootHarnessLoader(): Promise<HarnessLoader> {\n return this;\n }\n\n // Implemented as part of the `LocatorFactory` interface.\n async harnessLoaderFor(selector: string): Promise<HarnessLoader> {\n return this.createEnvironment(await _assertResultFound(this.getAllRawElements(selector),\n [_getDescriptionForHarnessLoaderQuery(selector)]));\n }\n\n // Implemented as part of the `LocatorFactory` interface.\n async harnessLoaderForOptional(selector: string): Promise<HarnessLoader | null> {\n const elements = await this.getAllRawElements(selector);\n return elements[0] ? this.createEnvironment(elements[0]) : null;\n }\n\n // Implemented as part of the `LocatorFactory` interface.\n async harnessLoaderForAll(selector: string): Promise<HarnessLoader[]> {\n const elements = await this.getAllRawElements(selector);\n return elements.map(element => this.createEnvironment(element));\n }\n\n // Implemented as part of the `HarnessLoader` interface.\n getHarness<T extends ComponentHarness>(query: HarnessQuery<T>): Promise<T> {\n return this.locatorFor(query)();\n }\n\n // Implemented as part of the `HarnessLoader` interface.\n getAllHarnesses<T extends ComponentHarness>(query: HarnessQuery<T>): Promise<T[]> {\n return this.locatorForAll(query)();\n }\n\n // Implemented as part of the `HarnessLoader` interface.\n async getChildLoader(selector: string): Promise<HarnessLoader> {\n return this.createEnvironment(await _assertResultFound(this.getAllRawElements(selector),\n [_getDescriptionForHarnessLoaderQuery(selector)]));\n }\n\n // Implemented as part of the `HarnessLoader` interface.\n async getAllChildLoaders(selector: string): Promise<HarnessLoader[]> {\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<T extends ComponentHarness>(\n harnessType: ComponentHarnessConstructor<T>, element: E): T {\n return new harnessType(this.createEnvironment(element));\n }\n\n // Part of LocatorFactory interface, subclasses will implement.\n abstract forceStabilize(): Promise<void>;\n\n // Part of LocatorFactory interface, subclasses will implement.\n abstract waitForTasksOutsideAngular(): Promise<void>;\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 `HarnessLoader` rooted at the given raw element. */\n protected abstract createEnvironment(element: E): HarnessEnvironment<E>;\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<E[]>;\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<T extends (HarnessQuery<any> | string)[]>(\n queries: T): Promise<LocatorFnResult<T>[]> {\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 // 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 = (elementQueries.length === 0 && harnessTypes.size === 1) ||\n harnessQueries.length === 0;\n\n const perElementMatches = await parallel(() => 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 () => allQueries.map(query => this._getQueryResultForElement(\n query, rawElement, testElement, skipSelectorCheck)));\n return _removeDuplicateQueryResults(allResultsForElement);\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<T extends ComponentHarness>(\n query: string | HarnessPredicate<T>, rawElement: E, testElement: TestElement,\n skipSelectorCheck: boolean = false): Promise<T | TestElement | null> {\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<T extends (HarnessQuery<any> | string)[]>(queries: T):\n ParsedQueries<LocatorFnResult<T> & ComponentHarness> {\n const allQueries = [];\n const harnessQueries = [];\n const elementQueries = [];\n const harnessTypes =\n new Set<ComponentHarnessConstructor<LocatorFnResult<T> & ComponentHarness>>();\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<T extends (ComponentHarness | TestElement | null)[]>(\n results: T): Promise<T> {\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<T>(results: Promise<T[]>, queryDescriptions: string[]):\n Promise<T> {\n const result = (await results)[0];\n if (result == undefined) {\n throw Error(`Failed to find element matching one of the following queries:\\n` +\n queryDescriptions.map(desc => `(${desc})`).join(',\\n'));\n }\n return result;\n}\n\n/** Gets a list of description strings from a list of queries. */\nfunction _getDescriptionForLocatorForQueries(queries: (string | HarnessQuery<any>)[]) {\n return queries.map(query => typeof query === 'string' ?\n _getDescriptionForTestElementQuery(query) : _getDescriptionForComponentHarnessQuery(query));\n}\n\n/** Gets a description string for a `ComponentHarness` query. */\nfunction _getDescriptionForComponentHarnessQuery(query: HarnessQuery<any>) {\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 description + (constraints ?\n ` satisfying the constraints: ${harnessPredicate.getDescription()}` : '');\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.io/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 | number | boolean | undefined | null | EventData[] | {[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}\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<void>;\n\n /** Clear the element's input (for input and textarea elements only). */\n clear(): Promise<void>;\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<void>;\n\n /** Click the element at the element's center. */\n click(location: 'center', modifiers?: ModifierKeys): Promise<void>;\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<void>;\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 * @breaking-change 11.0.0 To become a required method.\n */\n rightClick?(relativeX: number, relativeY: number, modifiers?: ModifierKeys): Promise<void>;\n\n /** Focus the element. */\n focus(): Promise<void>;\n\n /** Get the computed value of the given CSS property for the element. */\n getCssValue(property: string): Promise<string>;\n\n /** Hovers the mouse over the element. */\n hover(): Promise<void>;\n\n /** Moves the mouse away from the element. */\n mouseAway(): Promise<void>;\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.\n */\n sendKeys(...keys: (string | TestKey)[]): Promise<void>;\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.\n */\n sendKeys(modifiers: ModifierKeys, ...keys: (string | TestKey)[]): Promise<void>;\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<string>;\n\n /** Gets the value for the given attribute from the element. */\n getAttribute(name: string): Promise<string | null>;\n\n /** Checks whether the element has the given class. */\n hasClass(name: string): Promise<boolean>;\n\n /** Gets the dimensions of the element. */\n getDimensions(): Promise<ElementDimensions>;\n\n /** Gets the value of a property of an element. */\n getProperty(name: string): Promise<any>;\n\n /** Checks whether this element matches the given selector. */\n matchesSelector(selector: string): Promise<boolean>;\n\n /** Checks whether the element is focused. */\n isFocused(): Promise<boolean>;\n\n /**\n * Sets the value of a property of an input.\n * @breaking-change 11.0.0 To become a required method.\n */\n setInputValue?(value: string): Promise<void>;\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/master/packages/forms/src/directives/select_control_value_accessor.ts#L19\n /**\n * Selects the options at the specified indexes inside of a native `select` element.\n * @breaking-change 12.0.0 To become a required method.\n */\n selectOptions?(...optionIndexes: number[]): Promise<void>;\n\n /**\n * Dispatches an event with a particular name.\n * @param name Name of the event to be dispatched.\n * @breaking-change 12.0.0 To be a required method.\n */\n dispatchEvent?(name: string, data?: Record<string, EventData>): Promise<void>;\n}\n\nexport interface TextOptions {\n /** Optional selector for elements to exclude. */\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.io/license\n */\n\n /**\n * Dimensions for element size and its position relative to the viewport.\n */\nexport interface ElementDimensions {\n top: number;\n left: number;\n width: number;\n height: number;\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\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 let child = exclusions[i];\n child.parentNode?.removeChild(child);\n }\n return (clone.textContent || '').trim();\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 './component-harness';\nexport * from './harness-environment';\nexport * from './test-element';\nexport * from './element-dimensions';\nexport * from './text-filtering';\nexport * from './change-detection';\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":"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"}