Skip to content

refactor: move force-stabilize from TestElement to ComponentHarness #17149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/cdk/testing/component-harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,13 @@ export interface LocatorFactory {
*/
locatorForAll<T extends ComponentHarness>(
harnessType: ComponentHarnessConstructor<T> | HarnessPredicate<T>): AsyncFactoryFn<T[]>;

/**
* Flushes change detection and async tasks.
* In most cases it should not be necessary to call this manually. However, there may be some edge
* cases where it is needed to fully flush animation events.
*/
forceStabilize(): Promise<void>;
}

/**
Expand Down Expand Up @@ -245,6 +252,15 @@ export abstract class ComponentHarness {
protected locatorForAll(arg: any) {
return this.locatorFactory.locatorForAll(arg);
}

/**
* Flushes change detection and async tasks.
* In most cases it should not be necessary to call this manually. However, there may be some edge
* cases where it is needed to fully flush animation events.
*/
protected async forceStabilize() {
return this.locatorFactory.forceStabilize();
}
}

/** Constructor for a ComponentHarness subclass. */
Expand Down
3 changes: 3 additions & 0 deletions src/cdk/testing/harness-environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ export abstract class HarnessEnvironment<E> implements HarnessLoader, LocatorFac
return new harnessType(this.createEnvironment(element));
}

// Part of LocatorFactory interface, subclasses will implement.
abstract forceStabilize(): Promise<void>;

/** Gets the root element for the document. */
protected abstract getDocumentRoot(): E;

Expand Down
2 changes: 0 additions & 2 deletions src/cdk/testing/protractor/protractor-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,4 @@ export class ProtractorElement implements TestElement {
Element.prototype.msMatchesSelector).call(arguments[0], arguments[1])
`, this.element, selector);
}

async forceStabilize(): Promise<void> {}
}
4 changes: 3 additions & 1 deletion src/cdk/testing/protractor/protractor-harness-environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/

import {HarnessEnvironment} from '@angular/cdk/testing';
import {by, element as protractorElement, ElementFinder} from 'protractor';
import {HarnessLoader} from '../component-harness';
import {HarnessEnvironment} from '../harness-environment';
import {TestElement} from '../test-element';
import {ProtractorElement} from './protractor-element';

Expand All @@ -23,6 +23,8 @@ export class ProtractorHarnessEnvironment extends HarnessEnvironment<ElementFind
return new ProtractorHarnessEnvironment(protractorElement(by.css('body')));
}

async forceStabilize(): Promise<void> {}

protected getDocumentRoot(): ElementFinder {
return protractorElement(by.css('body'));
}
Expand Down
7 changes: 0 additions & 7 deletions src/cdk/testing/test-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,4 @@ export interface TestElement {

/** Checks whether this element matches the given selector. */
matchesSelector(selector: string): Promise<boolean>;

/**
* Flushes change detection and async tasks.
* In most cases it should not be necessary to call this. However, there may be some edge cases
* where it is needed to fully flush animation events.
*/
forceStabilize(): Promise<void>;
}
26 changes: 13 additions & 13 deletions src/cdk/testing/testbed/testbed-harness-environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/

import {HarnessEnvironment} from '@angular/cdk/testing';
import {ComponentFixture} from '@angular/core/testing';
import {ComponentHarness, ComponentHarnessConstructor, HarnessLoader} from '../component-harness';
import {HarnessEnvironment} from '../harness-environment';
import {TestElement} from '../test-element';
import {UnitTestElement} from './unit-test-element';

Expand Down Expand Up @@ -43,33 +43,33 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment<Element> {
static async harnessForFixture<T extends ComponentHarness>(
fixture: ComponentFixture<unknown>, harnessType: ComponentHarnessConstructor<T>): Promise<T> {
const environment = new TestbedHarnessEnvironment(fixture.nativeElement, fixture);
await environment._stabilize();
await environment.forceStabilize();
return environment.createComponentHarness(harnessType, fixture.nativeElement);
}

async forceStabilize(): Promise<void> {
if (this._destroyed) {
throw Error('Harness is attempting to use a fixture that has already been destroyed.');
}

this._fixture.detectChanges();
await this._fixture.whenStable();
}

protected getDocumentRoot(): Element {
return document.body;
}

protected createTestElement(element: Element): TestElement {
return new UnitTestElement(element, this._stabilize.bind(this));
return new UnitTestElement(element, () => this.forceStabilize());
}

protected createEnvironment(element: Element): HarnessEnvironment<Element> {
return new TestbedHarnessEnvironment(element, this._fixture);
}

protected async getAllRawElements(selector: string): Promise<Element[]> {
await this._stabilize();
await this.forceStabilize();
return Array.from(this.rawRootElement.querySelectorAll(selector));
}

private async _stabilize(): Promise<void> {
if (this._destroyed) {
throw Error('Harness is attempting to use a fixture that has already been destroyed.');
}

this._fixture.detectChanges();
await this._fixture.whenStable();
}
}
4 changes: 0 additions & 4 deletions src/cdk/testing/testbed/unit-test-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,4 @@ export class UnitTestElement implements TestElement {
return (elementPrototype['matches'] || elementPrototype['msMatchesSelector'])
.call(this.element, selector);
}

async forceStabilize(): Promise<void> {
return this._stabilize();
}
}
4 changes: 3 additions & 1 deletion tools/public_api_guard/cdk/testing.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export declare function clearElement(element: HTMLInputElement | HTMLTextAreaEle
export declare abstract class ComponentHarness {
constructor(locatorFactory: LocatorFactory);
protected documentRootLocatorFactory(): LocatorFactory;
protected forceStabilize(): Promise<void>;
host(): Promise<TestElement>;
protected locatorFor(selector: string): AsyncFactoryFn<TestElement>;
protected locatorFor<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T> | HarnessPredicate<T>): AsyncFactoryFn<T>;
Expand Down Expand Up @@ -54,6 +55,7 @@ export declare abstract class HarnessEnvironment<E> implements HarnessLoader, Lo
protected abstract createEnvironment(element: E): HarnessEnvironment<E>;
protected abstract createTestElement(element: E): TestElement;
documentRootLocatorFactory(): LocatorFactory;
abstract forceStabilize(): Promise<void>;
getAllChildLoaders(selector: string): Promise<HarnessLoader[]>;
getAllHarnesses<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T> | HarnessPredicate<T>): Promise<T[]>;
protected abstract getAllRawElements(selector: string): Promise<E[]>;
Expand Down Expand Up @@ -92,6 +94,7 @@ export declare function isTextInput(element: Element): element is HTMLInputEleme
export interface LocatorFactory {
rootElement: TestElement;
documentRootLocatorFactory(): LocatorFactory;
forceStabilize(): Promise<void>;
locatorFor(selector: string): AsyncFactoryFn<TestElement>;
locatorFor<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T> | HarnessPredicate<T>): AsyncFactoryFn<T>;
locatorForAll(selector: string): AsyncFactoryFn<TestElement[]>;
Expand All @@ -114,7 +117,6 @@ export interface TestElement {
clear(): Promise<void>;
click(relativeX?: number, relativeY?: number): Promise<void>;
focus(): Promise<void>;
forceStabilize(): Promise<void>;
getAttribute(name: string): Promise<string | null>;
getCssValue(property: string): Promise<string>;
getDimensions(): Promise<ElementDimensions>;
Expand Down