UNPKG

65 kBSource Map (JSON)View Raw
1{"version":3,"file":"testbed.mjs","sources":["../../../../../../../src/cdk/testing/testbed/task-state-zone-interceptor.ts","../../../../../../../src/cdk/testing/testbed/fake-events/event-objects.ts","../../../../../../../src/cdk/testing/testbed/fake-events/dispatch-events.ts","../../../../../../../src/cdk/testing/testbed/fake-events/element-focus.ts","../../../../../../../src/cdk/testing/testbed/fake-events/type-in-element.ts","../../../../../../../src/cdk/testing/testbed/fake-events/index.ts","../../../../../../../src/cdk/testing/testbed/unit-test-element.ts","../../../../../../../src/cdk/testing/testbed/testbed-harness-environment.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, Observable} from 'rxjs';\nimport {ProxyZone, ProxyZoneStatic} from './proxy-zone-types';\n\n/** Current state of the intercepted zone. */\nexport interface TaskState {\n /** Whether the zone is stable (i.e. no microtasks and macrotasks). */\n stable: boolean;\n}\n\n/** Unique symbol that is used to patch a property to a proxy zone. */\nconst stateObservableSymbol = Symbol('ProxyZone_PATCHED#stateObservable');\n\n/** Type that describes a potentially patched proxy zone instance. */\ntype PatchedProxyZone = ProxyZone & {\n [stateObservableSymbol]: undefined | Observable<TaskState>;\n};\n\n/**\n * Interceptor that can be set up in a `ProxyZone` instance. The interceptor\n * will keep track of the task state and emit whenever the state changes.\n *\n * This serves as a workaround for https://github.com/angular/angular/issues/32896.\n */\nexport class TaskStateZoneInterceptor {\n /** Subject that can be used to emit a new state change. */\n private readonly _stateSubject = new BehaviorSubject<TaskState>(\n this._lastState ? this._getTaskStateFromInternalZoneState(this._lastState) : {stable: true},\n );\n\n /** Public observable that emits whenever the task state changes. */\n readonly state: Observable<TaskState> = this._stateSubject;\n\n constructor(private _lastState: HasTaskState | null) {}\n\n /** This will be called whenever the task state changes in the intercepted zone. */\n onHasTask(delegate: ZoneDelegate, current: Zone, target: Zone, hasTaskState: HasTaskState) {\n if (current === target) {\n this._stateSubject.next(this._getTaskStateFromInternalZoneState(hasTaskState));\n }\n }\n\n /** Gets the task state from the internal ZoneJS task state. */\n private _getTaskStateFromInternalZoneState(state: HasTaskState): TaskState {\n return {stable: !state.macroTask && !state.microTask};\n }\n\n /**\n * Sets up the custom task state Zone interceptor in the `ProxyZone`. Throws if\n * no `ProxyZone` could be found.\n * @returns an observable that emits whenever the task state changes.\n */\n static setup(): Observable<TaskState> {\n if (Zone === undefined) {\n throw Error(\n 'Could not find ZoneJS. For test harnesses running in TestBed, ' +\n 'ZoneJS needs to be installed.',\n );\n }\n\n // tslint:disable-next-line:variable-name\n const ProxyZoneSpec = (Zone as any)['ProxyZoneSpec'] as ProxyZoneStatic | undefined;\n\n // If there is no \"ProxyZoneSpec\" installed, we throw an error and recommend\n // setting up the proxy zone by pulling in the testing bundle.\n if (!ProxyZoneSpec) {\n throw Error(\n 'ProxyZoneSpec is needed for the test harnesses but could not be found. ' +\n 'Please make sure that your environment includes zone.js/dist/zone-testing.js',\n );\n }\n\n // Ensure that there is a proxy zone instance set up, and get\n // a reference to the instance if present.\n const zoneSpec = ProxyZoneSpec.assertPresent() as PatchedProxyZone;\n\n // If there already is a delegate registered in the proxy zone, and it\n // is type of the custom task state interceptor, we just use that state\n // observable. This allows us to only intercept Zone once per test\n // (similar to how `fakeAsync` or `async` work).\n if (zoneSpec[stateObservableSymbol]) {\n return zoneSpec[stateObservableSymbol]!;\n }\n\n // Since we intercept on environment creation and the fixture has been\n // created before, we might have missed tasks scheduled before. Fortunately\n // the proxy zone keeps track of the previous task state, so we can just pass\n // this as initial state to the task zone interceptor.\n const interceptor = new TaskStateZoneInterceptor(zoneSpec.lastTaskState);\n const zoneSpecOnHasTask = zoneSpec.onHasTask.bind(zoneSpec);\n\n // We setup the task state interceptor in the `ProxyZone`. Note that we cannot register\n // the interceptor as a new proxy zone delegate because it would mean that other zone\n // delegates (e.g. `FakeAsyncTestZone` or `AsyncTestZone`) can accidentally overwrite/disable\n // our interceptor. Since we just intend to monitor the task state of the proxy zone, it is\n // sufficient to just patch the proxy zone. This also avoids that we interfere with the task\n // queue scheduling logic.\n zoneSpec.onHasTask = function (...args: [ZoneDelegate, Zone, Zone, HasTaskState]) {\n zoneSpecOnHasTask(...args);\n interceptor.onHasTask(...args);\n };\n\n return (zoneSpec[stateObservableSymbol] = interceptor.state);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {ModifierKeys} from '@angular/cdk/testing';\n\n/** Used to generate unique IDs for events. */\nlet uniqueIds = 0;\n\n/**\n * Creates a browser MouseEvent with the specified options.\n * @docs-private\n */\nexport function createMouseEvent(\n type: string,\n clientX = 0,\n clientY = 0,\n offsetX = 1,\n offsetY = 1,\n button = 0,\n modifiers: ModifierKeys = {},\n) {\n // Note: We cannot determine the position of the mouse event based on the screen\n // because the dimensions and position of the browser window are not available\n // To provide reasonable `screenX` and `screenY` coordinates, we simply use the\n // client coordinates as if the browser is opened in fullscreen.\n const screenX = clientX;\n const screenY = clientY;\n\n const event = new MouseEvent(type, {\n bubbles: true,\n cancelable: true,\n composed: true, // Required for shadow DOM events.\n view: window,\n detail: 0,\n relatedTarget: null,\n screenX,\n screenY,\n clientX,\n clientY,\n ctrlKey: modifiers.control,\n altKey: modifiers.alt,\n shiftKey: modifiers.shift,\n metaKey: modifiers.meta,\n button: button,\n buttons: 1,\n });\n\n // The `MouseEvent` constructor doesn't allow us to pass these properties into the constructor.\n // Override them to `1`, because they're used for fake screen reader event detection.\n if (offsetX != null) {\n defineReadonlyEventProperty(event, 'offsetX', offsetX);\n }\n\n if (offsetY != null) {\n defineReadonlyEventProperty(event, 'offsetY', offsetY);\n }\n\n return event;\n}\n\n/**\n * Creates a browser `PointerEvent` with the specified options. Pointer events\n * by default will appear as if they are the primary pointer of their type.\n * https://www.w3.org/TR/pointerevents2/#dom-pointerevent-isprimary.\n *\n * For example, if pointer events for a multi-touch interaction are created, the non-primary\n * pointer touches would need to be represented by non-primary pointer events.\n *\n * @docs-private\n */\nexport function createPointerEvent(\n type: string,\n clientX = 0,\n clientY = 0,\n offsetX?: number,\n offsetY?: number,\n options: PointerEventInit = {isPrimary: true},\n) {\n const event = new PointerEvent(type, {\n bubbles: true,\n cancelable: true,\n composed: true, // Required for shadow DOM events.\n view: window,\n clientX,\n clientY,\n ...options,\n });\n\n if (offsetX != null) {\n defineReadonlyEventProperty(event, 'offsetX', offsetX);\n }\n\n if (offsetY != null) {\n defineReadonlyEventProperty(event, 'offsetY', offsetY);\n }\n\n return event;\n}\n\n/**\n * Creates a browser TouchEvent with the specified pointer coordinates.\n * @docs-private\n */\nexport function createTouchEvent(type: string, pageX = 0, pageY = 0, clientX = 0, clientY = 0) {\n // We cannot use the `TouchEvent` or `Touch` because Firefox and Safari lack support.\n // TODO: Switch to the constructor API when it is available for Firefox and Safari.\n const event = document.createEvent('UIEvent');\n const touchDetails = {pageX, pageY, clientX, clientY, identifier: uniqueIds++};\n\n // TS3.6 removes the initUIEvent method and suggests porting to \"new UIEvent()\".\n (event as any).initUIEvent(type, true, true, window, 0);\n\n // Most of the browsers don't have a \"initTouchEvent\" method that can be used to define\n // the touch details.\n defineReadonlyEventProperty(event, 'touches', [touchDetails]);\n defineReadonlyEventProperty(event, 'targetTouches', [touchDetails]);\n defineReadonlyEventProperty(event, 'changedTouches', [touchDetails]);\n\n return event;\n}\n\n/**\n * Creates a keyboard event with the specified key and modifiers.\n * @docs-private\n */\nexport function createKeyboardEvent(\n type: string,\n keyCode: number = 0,\n key: string = '',\n modifiers: ModifierKeys = {},\n) {\n return new KeyboardEvent(type, {\n bubbles: true,\n cancelable: true,\n composed: true, // Required for shadow DOM events.\n view: window,\n keyCode: keyCode,\n key: key,\n shiftKey: modifiers.shift,\n metaKey: modifiers.meta,\n altKey: modifiers.alt,\n ctrlKey: modifiers.control,\n });\n}\n\n/**\n * Creates a fake event object with any desired event type.\n * @docs-private\n */\nexport function createFakeEvent(type: string, bubbles = false, cancelable = true, composed = true) {\n return new Event(type, {bubbles, cancelable, composed});\n}\n\n/**\n * Defines a readonly property on the given event object. Readonly properties on an event object\n * are always set as configurable as that matches default readonly properties for DOM event objects.\n */\nfunction defineReadonlyEventProperty(event: Event, propertyName: string, value: any) {\n Object.defineProperty(event, propertyName, {get: () => value, configurable: 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 {ModifierKeys} from '@angular/cdk/testing';\nimport {\n createFakeEvent,\n createKeyboardEvent,\n createMouseEvent,\n createPointerEvent,\n createTouchEvent,\n} from './event-objects';\n\n/**\n * Utility to dispatch any event on a Node.\n * @docs-private\n */\nexport function dispatchEvent<T extends Event>(node: Node | Window, event: T): T {\n node.dispatchEvent(event);\n return event;\n}\n\n/**\n * Shorthand to dispatch a fake event on a specified node.\n * @docs-private\n */\nexport function dispatchFakeEvent(node: Node | Window, type: string, bubbles?: boolean): Event {\n return dispatchEvent(node, createFakeEvent(type, bubbles));\n}\n\n/**\n * Shorthand to dispatch a keyboard event with a specified key code and\n * optional modifiers.\n * @docs-private\n */\nexport function dispatchKeyboardEvent(\n node: Node,\n type: string,\n keyCode?: number,\n key?: string,\n modifiers?: ModifierKeys,\n): KeyboardEvent {\n return dispatchEvent(node, createKeyboardEvent(type, keyCode, key, modifiers));\n}\n\n/**\n * Shorthand to dispatch a mouse event on the specified coordinates.\n * @docs-private\n */\nexport function dispatchMouseEvent(\n node: Node,\n type: string,\n clientX = 0,\n clientY = 0,\n offsetX?: number,\n offsetY?: number,\n button?: number,\n modifiers?: ModifierKeys,\n): MouseEvent {\n return dispatchEvent(\n node,\n createMouseEvent(type, clientX, clientY, offsetX, offsetY, button, modifiers),\n );\n}\n\n/**\n * Shorthand to dispatch a pointer event on the specified coordinates.\n * @docs-private\n */\nexport function dispatchPointerEvent(\n node: Node,\n type: string,\n clientX = 0,\n clientY = 0,\n offsetX?: number,\n offsetY?: number,\n options?: PointerEventInit,\n): PointerEvent {\n return dispatchEvent(\n node,\n createPointerEvent(type, clientX, clientY, offsetX, offsetY, options),\n ) as PointerEvent;\n}\n\n/**\n * Shorthand to dispatch a touch event on the specified coordinates.\n * @docs-private\n */\nexport function dispatchTouchEvent(\n node: Node,\n type: string,\n pageX = 0,\n pageY = 0,\n clientX = 0,\n clientY = 0,\n) {\n return dispatchEvent(node, createTouchEvent(type, pageX, pageY, clientX, clientY));\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 {dispatchFakeEvent} from './dispatch-events';\n\nfunction triggerFocusChange(element: HTMLElement, event: 'focus' | 'blur') {\n let eventFired = false;\n const handler = () => (eventFired = true);\n element.addEventListener(event, handler);\n element[event]();\n element.removeEventListener(event, handler);\n if (!eventFired) {\n dispatchFakeEvent(element, event);\n }\n}\n\n/**\n * Patches an elements focus and blur methods to emit events consistently and predictably.\n * This is necessary, because some browsers can call the focus handlers asynchronously,\n * while others won't fire them at all if the browser window is not focused.\n * @docs-private\n */\n// TODO: Check if this element focus patching is still needed for local testing,\n// where browser is not necessarily focused.\nexport function patchElementFocus(element: HTMLElement) {\n element.focus = () => dispatchFakeEvent(element, 'focus');\n element.blur = () => dispatchFakeEvent(element, 'blur');\n}\n\n/** @docs-private */\nexport function triggerFocus(element: HTMLElement) {\n triggerFocusChange(element, 'focus');\n}\n\n/** @docs-private */\nexport function triggerBlur(element: HTMLElement) {\n triggerFocusChange(element, 'blur');\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 {getNoKeysSpecifiedError, ModifierKeys} from '@angular/cdk/testing';\nimport {PERIOD} from '@angular/cdk/keycodes';\nimport {dispatchFakeEvent, dispatchKeyboardEvent} from './dispatch-events';\nimport {triggerFocus} from './element-focus';\n\n/** Input types for which the value can be entered incrementally. */\nconst incrementalInputTypes = new Set([\n 'text',\n 'email',\n 'hidden',\n 'password',\n 'search',\n 'tel',\n 'url',\n]);\n\n/**\n * Checks whether the given Element is a text input element.\n * @docs-private\n */\nexport function isTextInput(element: Element): element is HTMLInputElement | HTMLTextAreaElement {\n const nodeName = element.nodeName.toLowerCase();\n return nodeName === 'input' || nodeName === 'textarea';\n}\n\n/**\n * If keys have been specified, focuses an input, sets its value and dispatches\n * the `input` event, simulating the user typing.\n * @param element Element onto which to set the value.\n * @param keys The keys to send to the element.\n * @docs-private\n */\nexport function typeInElement(\n element: HTMLElement,\n ...keys: (string | {keyCode?: number; key?: string})[]\n): void;\n\n/**\n * If keys have been specified, focuses an input, sets its value and dispatches\n * the `input` event, simulating the user typing.\n * @param element Element onto which to set the value.\n * @param modifiers Modifier keys that are held while typing.\n * @param keys The keys to send to the element.\n * @docs-private\n */\nexport function typeInElement(\n element: HTMLElement,\n modifiers: ModifierKeys,\n ...keys: (string | {keyCode?: number; key?: string})[]\n): void;\n\nexport function typeInElement(element: HTMLElement, ...modifiersAndKeys: any[]) {\n const first = modifiersAndKeys[0];\n let modifiers: ModifierKeys;\n let rest: (string | {keyCode?: number; key?: string})[];\n if (\n first !== undefined &&\n typeof first !== 'string' &&\n first.keyCode === undefined &&\n first.key === undefined\n ) {\n modifiers = first;\n rest = modifiersAndKeys.slice(1);\n } else {\n modifiers = {};\n rest = modifiersAndKeys;\n }\n const isInput = isTextInput(element);\n const inputType = element.getAttribute('type') || 'text';\n const keys: {keyCode?: number; key?: string}[] = rest\n .map(k =>\n typeof k === 'string'\n ? k.split('').map(c => ({keyCode: c.toUpperCase().charCodeAt(0), key: c}))\n : [k],\n )\n .reduce((arr, k) => arr.concat(k), []);\n\n // Throw an error if no keys have been specified. Calling this function with no\n // keys should not result in a focus event being dispatched unexpectedly.\n if (keys.length === 0) {\n throw getNoKeysSpecifiedError();\n }\n\n // We simulate the user typing in a value by incrementally assigning the value below. The problem\n // is that for some input types, the browser won't allow for an invalid value to be set via the\n // `value` property which will always be the case when going character-by-character. If we detect\n // such an input, we have to set the value all at once or listeners to the `input` event (e.g.\n // the `ReactiveFormsModule` uses such an approach) won't receive the correct value.\n const enterValueIncrementally =\n inputType === 'number'\n ? // The value can be set character by character in number inputs if it doesn't have any decimals.\n keys.every(key => key.key !== '.' && key.key !== '-' && key.keyCode !== PERIOD)\n : incrementalInputTypes.has(inputType);\n\n triggerFocus(element);\n\n // When we aren't entering the value incrementally, assign it all at once ahead\n // of time so that any listeners to the key events below will have access to it.\n if (!enterValueIncrementally) {\n (element as HTMLInputElement).value = keys.reduce((value, key) => value + (key.key || ''), '');\n }\n\n for (const key of keys) {\n dispatchKeyboardEvent(element, 'keydown', key.keyCode, key.key, modifiers);\n dispatchKeyboardEvent(element, 'keypress', key.keyCode, key.key, modifiers);\n if (isInput && key.key && key.key.length === 1) {\n if (enterValueIncrementally) {\n (element as HTMLInputElement | HTMLTextAreaElement).value += key.key;\n dispatchFakeEvent(element, 'input');\n }\n }\n dispatchKeyboardEvent(element, 'keyup', key.keyCode, key.key, modifiers);\n }\n\n // Since we weren't dispatching `input` events while sending the keys, we have to do it now.\n if (!enterValueIncrementally) {\n dispatchFakeEvent(element, 'input');\n }\n}\n\n/**\n * Clears the text in an input or textarea element.\n * @docs-private\n */\nexport function clearElement(element: HTMLInputElement | HTMLTextAreaElement) {\n triggerFocus(element as HTMLElement);\n element.value = '';\n dispatchFakeEvent(element, 'input');\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// These are private APIs that are used both by the public APIs inside of this package, as well\n// as in unit tests of other entry-points, hence why we need to re-export them through here.\nexport * from './dispatch-events';\nexport * from './event-objects';\nexport * from './element-focus';\nexport * from './type-in-element';\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 * as keyCodes from '@angular/cdk/keycodes';\nimport {\n _getTextWithExcludedElements,\n ElementDimensions,\n ModifierKeys,\n TestElement,\n TestKey,\n TextOptions,\n EventData,\n} from '@angular/cdk/testing';\nimport {\n clearElement,\n createFakeEvent,\n dispatchFakeEvent,\n dispatchMouseEvent,\n dispatchPointerEvent,\n isTextInput,\n triggerBlur,\n triggerFocus,\n typeInElement,\n dispatchEvent,\n} from './fake-events';\n\n/** Maps `TestKey` constants to the `keyCode` and `key` values used by native browser events. */\nconst keyMap = {\n [TestKey.BACKSPACE]: {keyCode: keyCodes.BACKSPACE, key: 'Backspace'},\n [TestKey.TAB]: {keyCode: keyCodes.TAB, key: 'Tab'},\n [TestKey.ENTER]: {keyCode: keyCodes.ENTER, key: 'Enter'},\n [TestKey.SHIFT]: {keyCode: keyCodes.SHIFT, key: 'Shift'},\n [TestKey.CONTROL]: {keyCode: keyCodes.CONTROL, key: 'Control'},\n [TestKey.ALT]: {keyCode: keyCodes.ALT, key: 'Alt'},\n [TestKey.ESCAPE]: {keyCode: keyCodes.ESCAPE, key: 'Escape'},\n [TestKey.PAGE_UP]: {keyCode: keyCodes.PAGE_UP, key: 'PageUp'},\n [TestKey.PAGE_DOWN]: {keyCode: keyCodes.PAGE_DOWN, key: 'PageDown'},\n [TestKey.END]: {keyCode: keyCodes.END, key: 'End'},\n [TestKey.HOME]: {keyCode: keyCodes.HOME, key: 'Home'},\n [TestKey.LEFT_ARROW]: {keyCode: keyCodes.LEFT_ARROW, key: 'ArrowLeft'},\n [TestKey.UP_ARROW]: {keyCode: keyCodes.UP_ARROW, key: 'ArrowUp'},\n [TestKey.RIGHT_ARROW]: {keyCode: keyCodes.RIGHT_ARROW, key: 'ArrowRight'},\n [TestKey.DOWN_ARROW]: {keyCode: keyCodes.DOWN_ARROW, key: 'ArrowDown'},\n [TestKey.INSERT]: {keyCode: keyCodes.INSERT, key: 'Insert'},\n [TestKey.DELETE]: {keyCode: keyCodes.DELETE, key: 'Delete'},\n [TestKey.F1]: {keyCode: keyCodes.F1, key: 'F1'},\n [TestKey.F2]: {keyCode: keyCodes.F2, key: 'F2'},\n [TestKey.F3]: {keyCode: keyCodes.F3, key: 'F3'},\n [TestKey.F4]: {keyCode: keyCodes.F4, key: 'F4'},\n [TestKey.F5]: {keyCode: keyCodes.F5, key: 'F5'},\n [TestKey.F6]: {keyCode: keyCodes.F6, key: 'F6'},\n [TestKey.F7]: {keyCode: keyCodes.F7, key: 'F7'},\n [TestKey.F8]: {keyCode: keyCodes.F8, key: 'F8'},\n [TestKey.F9]: {keyCode: keyCodes.F9, key: 'F9'},\n [TestKey.F10]: {keyCode: keyCodes.F10, key: 'F10'},\n [TestKey.F11]: {keyCode: keyCodes.F11, key: 'F11'},\n [TestKey.F12]: {keyCode: keyCodes.F12, key: 'F12'},\n [TestKey.META]: {keyCode: keyCodes.META, key: 'Meta'},\n};\n\n/** A `TestElement` implementation for unit tests. */\nexport class UnitTestElement implements TestElement {\n constructor(readonly element: Element, private _stabilize: () => Promise<void>) {}\n\n /** Blur the element. */\n async blur(): Promise<void> {\n triggerBlur(this.element as HTMLElement);\n await this._stabilize();\n }\n\n /** Clear the element's input (for input and textarea elements only). */\n async clear(): Promise<void> {\n if (!isTextInput(this.element)) {\n throw Error('Attempting to clear an invalid element');\n }\n clearElement(this.element);\n await this._stabilize();\n }\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 /** Click the element at the element's center. */\n click(location: 'center', modifiers?: ModifierKeys): Promise<void>;\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 async click(\n ...args: [ModifierKeys?] | ['center', ModifierKeys?] | [number, number, ModifierKeys?]\n ): Promise<void> {\n const isDisabled = (this.element as Partial<{disabled?: boolean}>).disabled === true;\n\n // If the element is `disabled` and has a `disabled` property, we emit the mouse event\n // sequence but not dispatch the `click` event. This is necessary to keep the behavior\n // consistent with an actual user interaction. The click event is not necessarily\n // automatically prevented by the browser. There is mismatch between Firefox and Chromium:\n // https://bugzilla.mozilla.org/show_bug.cgi?id=329509.\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1115661.\n await this._dispatchMouseEventSequence(isDisabled ? null : 'click', args, 0);\n await this._stabilize();\n }\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<void>;\n async rightClick(\n ...args: [ModifierKeys?] | ['center', ModifierKeys?] | [number, number, ModifierKeys?]\n ): Promise<void> {\n await this._dispatchMouseEventSequence('contextmenu', args, 2);\n await this._stabilize();\n }\n\n /** Focus the element. */\n async focus(): Promise<void> {\n triggerFocus(this.element as HTMLElement);\n await this._stabilize();\n }\n\n /** Get the computed value of the given CSS property for the element. */\n async getCssValue(property: string): Promise<string> {\n await this._stabilize();\n // TODO(mmalerba): Consider adding value normalization if we run into common cases where its\n // needed.\n return getComputedStyle(this.element).getPropertyValue(property);\n }\n\n /** Hovers the mouse over the element. */\n async hover(): Promise<void> {\n this._dispatchPointerEventIfSupported('pointerenter');\n dispatchMouseEvent(this.element, 'mouseover');\n dispatchMouseEvent(this.element, 'mouseenter');\n await this._stabilize();\n }\n\n /** Moves the mouse away from the element. */\n async mouseAway(): Promise<void> {\n this._dispatchPointerEventIfSupported('pointerleave');\n dispatchMouseEvent(this.element, 'mouseout');\n dispatchMouseEvent(this.element, 'mouseleave');\n await this._stabilize();\n }\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 this cannot\n * reproduce native browser behavior for keyboard shortcuts such as Tab, Ctrl + A, etc.\n */\n async sendKeys(...keys: (string | TestKey)[]): Promise<void>;\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 async sendKeys(modifiers: ModifierKeys, ...keys: (string | TestKey)[]): Promise<void>;\n async sendKeys(...modifiersAndKeys: any[]): Promise<void> {\n const args = modifiersAndKeys.map(k => (typeof k === 'number' ? keyMap[k as TestKey] : k));\n typeInElement(this.element as HTMLElement, ...args);\n await this._stabilize();\n }\n\n /**\n * Gets the text from the element.\n * @param options Options that affect what text is included.\n */\n async text(options?: TextOptions): Promise<string> {\n await this._stabilize();\n if (options?.exclude) {\n return _getTextWithExcludedElements(this.element, options.exclude);\n }\n return (this.element.textContent || '').trim();\n }\n\n /**\n * Sets the value of a `contenteditable` element.\n * @param value Value to be set on the element.\n */\n async setContenteditableValue(value: string): Promise<void> {\n const contenteditableAttr = await this.getAttribute('contenteditable');\n\n if (contenteditableAttr !== '' && contenteditableAttr !== 'true') {\n throw new Error('setContenteditableValue can only be called on a `contenteditable` element.');\n }\n\n await this._stabilize();\n this.element.textContent = value;\n }\n\n /** Gets the value for the given attribute from the element. */\n async getAttribute(name: string): Promise<string | null> {\n await this._stabilize();\n return this.element.getAttribute(name);\n }\n\n /** Checks whether the element has the given class. */\n async hasClass(name: string): Promise<boolean> {\n await this._stabilize();\n return this.element.classList.contains(name);\n }\n\n /** Gets the dimensions of the element. */\n async getDimensions(): Promise<ElementDimensions> {\n await this._stabilize();\n return this.element.getBoundingClientRect();\n }\n\n /** Gets the value of a property of an element. */\n async getProperty<T = any>(name: string): Promise<T> {\n await this._stabilize();\n return (this.element as any)[name];\n }\n\n /** Sets the value of a property of an input. */\n async setInputValue(value: string): Promise<void> {\n (this.element as any).value = value;\n await this._stabilize();\n }\n\n /** Selects the options at the specified indexes inside of a native `select` element. */\n async selectOptions(...optionIndexes: number[]): Promise<void> {\n let hasChanged = false;\n const options = this.element.querySelectorAll('option');\n const indexes = new Set(optionIndexes); // Convert to a set to remove duplicates.\n\n for (let i = 0; i < options.length; i++) {\n const option = options[i];\n const wasSelected = option.selected;\n\n // We have to go through `option.selected`, because `HTMLSelectElement.value` doesn't\n // allow for multiple options to be selected, even in `multiple` mode.\n option.selected = indexes.has(i);\n\n if (option.selected !== wasSelected) {\n hasChanged = true;\n dispatchFakeEvent(this.element, 'change');\n }\n }\n\n if (hasChanged) {\n await this._stabilize();\n }\n }\n\n /** Checks whether this element matches the given selector. */\n async matchesSelector(selector: string): Promise<boolean> {\n await this._stabilize();\n const elementPrototype = Element.prototype as any;\n return (elementPrototype['matches'] || elementPrototype['msMatchesSelector']).call(\n this.element,\n selector,\n );\n }\n\n /** Checks whether the element is focused. */\n async isFocused(): Promise<boolean> {\n await this._stabilize();\n return document.activeElement === this.element;\n }\n\n /**\n * Dispatches an event with a particular name.\n * @param name Name of the event to be dispatched.\n */\n async dispatchEvent(name: string, data?: Record<string, EventData>): Promise<void> {\n const event = createFakeEvent(name);\n\n if (data) {\n // tslint:disable-next-line:ban Have to use `Object.assign` to preserve the original object.\n Object.assign(event, data);\n }\n\n dispatchEvent(this.element, event);\n await this._stabilize();\n }\n\n /**\n * Dispatches a pointer event on the current element if the browser supports it.\n * @param name Name of the pointer event to be dispatched.\n * @param clientX Coordinate of the user's pointer along the X axis.\n * @param clientY Coordinate of the user's pointer along the Y axis.\n * @param button Mouse button that should be pressed when dispatching the event.\n */\n private _dispatchPointerEventIfSupported(\n name: string,\n clientX?: number,\n clientY?: number,\n offsetX?: number,\n offsetY?: number,\n button?: number,\n ) {\n // The latest versions of all browsers we support have the new `PointerEvent` API.\n // Though since we capture the two most recent versions of these browsers, we also\n // need to support Safari 12 at time of writing. Safari 12 does not have support for this,\n // so we need to conditionally create and dispatch these events based on feature detection.\n if (typeof PointerEvent !== 'undefined' && PointerEvent) {\n dispatchPointerEvent(this.element, name, clientX, clientY, offsetX, offsetY, {\n isPrimary: true,\n button,\n });\n }\n }\n\n /**\n * Dispatches all the events that are part of a mouse event sequence\n * and then emits a given primary event at the end, if speciifed.\n */\n private async _dispatchMouseEventSequence(\n primaryEventName: string | null,\n args: [ModifierKeys?] | ['center', ModifierKeys?] | [number, number, ModifierKeys?],\n button?: number,\n ) {\n let clientX: number | undefined = undefined;\n let clientY: number | undefined = undefined;\n let offsetX: number | undefined = undefined;\n let offsetY: number | undefined = undefined;\n let modifiers: ModifierKeys = {};\n\n if (args.length && typeof args[args.length - 1] === 'object') {\n modifiers = args.pop() as ModifierKeys;\n }\n\n if (args.length) {\n const {left, top, width, height} = await this.getDimensions();\n offsetX = args[0] === 'center' ? width / 2 : (args[0] as number);\n offsetY = args[0] === 'center' ? height / 2 : (args[1] as number);\n\n // Round the computed click position as decimal pixels are not\n // supported by mouse events and could lead to unexpected results.\n clientX = Math.round(left + offsetX);\n clientY = Math.round(top + offsetY);\n }\n\n this._dispatchPointerEventIfSupported(\n 'pointerdown',\n clientX,\n clientY,\n offsetX,\n offsetY,\n button,\n );\n dispatchMouseEvent(\n this.element,\n 'mousedown',\n clientX,\n clientY,\n offsetX,\n offsetY,\n button,\n modifiers,\n );\n this._dispatchPointerEventIfSupported('pointerup', clientX, clientY, offsetX, offsetY, button);\n dispatchMouseEvent(\n this.element,\n 'mouseup',\n clientX,\n clientY,\n offsetX,\n offsetY,\n button,\n modifiers,\n );\n\n // If a primary event name is specified, emit it after the mouse event sequence.\n if (primaryEventName !== null) {\n dispatchMouseEvent(\n this.element,\n primaryEventName,\n clientX,\n clientY,\n offsetX,\n offsetY,\n button,\n modifiers,\n );\n }\n\n // This call to _stabilize should not be needed since the callers will already do that them-\n // selves. Nevertheless it breaks some tests in g3 without it. It needs to be investigated\n // why removing breaks those tests.\n // See: https://github.com/angular/components/pull/20758/files#r520886256.\n await this._stabilize();\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {\n ComponentHarness,\n ComponentHarnessConstructor,\n handleAutoChangeDetectionStatus,\n HarnessEnvironment,\n HarnessLoader,\n stopHandlingAutoChangeDetectionStatus,\n TestElement,\n} from '@angular/cdk/testing';\nimport {ComponentFixture, flush} from '@angular/core/testing';\nimport {Observable} from 'rxjs';\nimport {takeWhile} from 'rxjs/operators';\nimport {TaskState, TaskStateZoneInterceptor} from './task-state-zone-interceptor';\nimport {UnitTestElement} from './unit-test-element';\n\n/** Options to configure the environment. */\nexport interface TestbedHarnessEnvironmentOptions {\n /** The query function used to find DOM elements. */\n queryFn: (selector: string, root: Element) => Iterable<Element> | ArrayLike<Element>;\n}\n\n/** The default environment options. */\nconst defaultEnvironmentOptions: TestbedHarnessEnvironmentOptions = {\n queryFn: (selector: string, root: Element) => root.querySelectorAll(selector),\n};\n\n/** Whether auto change detection is currently disabled. */\nlet disableAutoChangeDetection = false;\n\n/**\n * The set of non-destroyed fixtures currently being used by `TestbedHarnessEnvironment` instances.\n */\nconst activeFixtures = new Set<ComponentFixture<unknown>>();\n\n/**\n * Installs a handler for change detection batching status changes for a specific fixture.\n * @param fixture The fixture to handle change detection batching for.\n */\nfunction installAutoChangeDetectionStatusHandler(fixture: ComponentFixture<unknown>) {\n if (!activeFixtures.size) {\n handleAutoChangeDetectionStatus(({isDisabled, onDetectChangesNow}) => {\n disableAutoChangeDetection = isDisabled;\n if (onDetectChangesNow) {\n Promise.all(Array.from(activeFixtures).map(detectChanges)).then(onDetectChangesNow);\n }\n });\n }\n activeFixtures.add(fixture);\n}\n\n/**\n * Uninstalls a handler for change detection batching status changes for a specific fixture.\n * @param fixture The fixture to stop handling change detection batching for.\n */\nfunction uninstallAutoChangeDetectionStatusHandler(fixture: ComponentFixture<unknown>) {\n activeFixtures.delete(fixture);\n if (!activeFixtures.size) {\n stopHandlingAutoChangeDetectionStatus();\n }\n}\n\n/** Whether we are currently in the fake async zone. */\nfunction isInFakeAsyncZone() {\n return Zone!.current.get('FakeAsyncTestZoneSpec') != null;\n}\n\n/**\n * Triggers change detection for a specific fixture.\n * @param fixture The fixture to trigger change detection for.\n */\nasync function detectChanges(fixture: ComponentFixture<unknown>) {\n fixture.detectChanges();\n if (isInFakeAsyncZone()) {\n flush();\n } else {\n await fixture.whenStable();\n }\n}\n\n/** A `HarnessEnvironment` implementation for Angular's Testbed. */\nexport class TestbedHarnessEnvironment extends HarnessEnvironment<Element> {\n /** Whether the environment has been destroyed. */\n private _destroyed = false;\n\n /** Observable that emits whenever the test task state changes. */\n private _taskState: Observable<TaskState>;\n\n /** The options for this environment. */\n private _options: TestbedHarnessEnvironmentOptions;\n\n /** Environment stabilization callback passed to the created test elements. */\n private _stabilizeCallback: () => Promise<void>;\n\n protected constructor(\n rawRootElement: Element,\n private _fixture: ComponentFixture<unknown>,\n options?: TestbedHarnessEnvironmentOptions,\n ) {\n super(rawRootElement);\n this._options = {...defaultEnvironmentOptions, ...options};\n this._taskState = TaskStateZoneInterceptor.setup();\n this._stabilizeCallback = () => this.forceStabilize();\n installAutoChangeDetectionStatusHandler(_fixture);\n _fixture.componentRef.onDestroy(() => {\n uninstallAutoChangeDetectionStatusHandler(_fixture);\n this._destroyed = true;\n });\n }\n\n /** Creates a `HarnessLoader` rooted at the given fixture's root element. */\n static loader(\n fixture: ComponentFixture<unknown>,\n options?: TestbedHarnessEnvironmentOptions,\n ): HarnessLoader {\n return new TestbedHarnessEnvironment(fixture.nativeElement, fixture, options);\n }\n\n /**\n * Creates a `HarnessLoader` at the document root. This can be used if harnesses are\n * located outside of a fixture (e.g. overlays appended to the document body).\n */\n static documentRootLoader(\n fixture: ComponentFixture<unknown>,\n options?: TestbedHarnessEnvironmentOptions,\n ): HarnessLoader {\n return new TestbedHarnessEnvironment(document.body, fixture, options);\n }\n\n /** Gets the native DOM element corresponding to the given TestElement. */\n static getNativeElement(el: TestElement): Element {\n if (el instanceof UnitTestElement) {\n return el.element;\n }\n throw Error('This TestElement was not created by the TestbedHarnessEnvironment');\n }\n\n /**\n * Creates an instance of the given harness type, using the fixture's root element as the\n * harness's host element. This method should be used when creating a harness for the root element\n * of a fixture, as components do not have the correct selector when they are created as the root\n * of the fixture.\n */\n static async harnessForFixture<T extends ComponentHarness>(\n fixture: ComponentFixture<unknown>,\n harnessType: ComponentHarnessConstructor<T>,\n options?: TestbedHarnessEnvironmentOptions,\n ): Promise<T> {\n const environment = new TestbedHarnessEnvironment(fixture.nativeElement, fixture, options);\n await environment.forceStabilize();\n return environment.createComponentHarness(harnessType, fixture.nativeElement);\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 */\n async forceStabilize(): Promise<void> {\n if (!disableAutoChangeDetection) {\n if (this._destroyed) {\n throw Error('Harness is attempting to use a fixture that has already been destroyed.');\n }\n\n await detectChanges(this._fixture);\n }\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 async waitForTasksOutsideAngular(): Promise<void> {\n // If we run in the fake async zone, we run \"flush\" to run any scheduled tasks. This\n // ensures that the harnesses behave inside of the FakeAsyncTestZone similar to the\n // \"AsyncTestZone\" and the root zone (i.e. neither fakeAsync or async). Note that we\n // cannot just rely on the task state observable to become stable because the state will\n // never change. This is because the task queue will be only drained if the fake async\n // zone is being flushed.\n if (isInFakeAsyncZone()) {\n flush();\n }\n\n // Wait until the task queue has been drained and the zone is stable. Note that\n // we cannot rely on \"fixture.whenStable\" since it does not catch tasks scheduled\n // outside of the Angular zone. For test harnesses, we want to ensure that the\n // app is fully stabilized and therefore need to use our own zone interceptor.\n await this._taskState.pipe(takeWhile(state => !state.stable)).toPromise();\n }\n\n /** Gets the root element for the document. */\n protected getDocumentRoot(): Element {\n return document.body;\n }\n\n /** Creates a `TestElement` from a raw element. */\n protected createTestElement(element: Element): TestElement {\n return new UnitTestElement(element, this._stabilizeCallback);\n }\n\n /** Creates a `HarnessLoader` rooted at the given raw element. */\n protected createEnvironment(element: Element): HarnessEnvironment<Element> {\n return new TestbedHarnessEnvironment(element, this._fixture, this._options);\n }\n\n /**\n * Gets a list of all elements matching the given selector under this environment's root element.\n */\n protected async getAllRawElements(selector: string): Promise<Element[]> {\n await this.forceStabilize();\n return Array.from(this._options.queryFn(selector, this.rawRootElement));\n }\n}\n"],"names":[],"mappings":"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"}
\No newline at end of file