Skip to content

Commit 5db7deb

Browse files
committed
nits
1 parent 6f3384f commit 5db7deb

File tree

9 files changed

+101
-183
lines changed

9 files changed

+101
-183
lines changed

src/cdk-experimental/testing/component-harness.ts

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,7 @@ export interface HarnessLoader {
2424
* @return A `HarnessLoader` rooted at the element matching the given selector.
2525
* @throws If a matching element can't be found.
2626
*/
27-
findRequired(selector: string): Promise<HarnessLoader>;
28-
29-
/**
30-
* Searches for an element with the given selector under the current instances's root element,
31-
* and returns a `HarnessLoader` rooted at the matching element. If multiple elements match the
32-
* selector, the first is used. If no elements match, null is returned.
33-
* @param selector The selector for the root element of the new `HarnessLoader`
34-
* @return A `HarnessLoader` rooted at the element matching the given selector, or null if no
35-
* matching element was found.
36-
*/
37-
findOptional(selector: string): Promise<HarnessLoader | null>;
27+
getChildLoader(selector: string): Promise<HarnessLoader>;
3828

3929
/**
4030
* Searches for all elements with the given selector under the current instances's root element,
@@ -43,7 +33,7 @@ export interface HarnessLoader {
4333
* @param selector The selector for the root element of the new `HarnessLoader`
4434
* @return A list of `HarnessLoader`s, one for each matching element, rooted at that element.
4535
*/
46-
findAll(selector: string): Promise<HarnessLoader[]>;
36+
getAllChildLoaders(selector: string): Promise<HarnessLoader[]>;
4737

4838
/**
4939
* Searches for an instance of the component corresponding to the given harness type under the
@@ -54,27 +44,16 @@ export interface HarnessLoader {
5444
* @return An instance of the given harness type
5545
* @throws If a matching component instance can't be found.
5646
*/
57-
requiredHarness<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T>):
47+
getHarness<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T>):
5848
Promise<T>;
5949

60-
/**
61-
* Searches for an instance of the component corresponding to the given harness type under the
62-
* `HarnessLoader`'s root element, and returns a `ComponentHarness` for that instance. If multiple
63-
* matching components are found, a harness for the first one is returned. If no matching
64-
* component is found, null is returned.
65-
* @param harnessType The type of harness to create
66-
* @return An instance of the given harness type, or null if none is found.
67-
*/
68-
optionalHarness<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T>):
69-
Promise<T | null>;
70-
7150
/**
7251
* Searches for all instances of the component corresponding to the given harness type under the
7352
* `HarnessLoader`'s root element, and returns a list `ComponentHarness` for each instance.
7453
* @param harnessType The type of harness to create
7554
* @return A list instances of the given harness type.
7655
*/
77-
allHarnesses<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T>):
56+
getAllHarnesses<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T>):
7857
Promise<T[]>;
7958
}
8059

@@ -87,8 +66,8 @@ export interface LocatorFactory {
8766
/** Gets a locator factory rooted at the document root. */
8867
documentRootLocatorFactory(): LocatorFactory;
8968

90-
/** Gets the root element of this `LocatorFactory` as a `TestElement`. */
91-
rootElement(): TestElement;
69+
/** The root element of this `LocatorFactory` as a `TestElement`. */
70+
rootElement: TestElement;
9271

9372
/**
9473
* Creates an asynchronous locator function that can be used to search for elements with the given
@@ -99,7 +78,7 @@ export interface LocatorFactory {
9978
* @return An asynchronous locator function that searches for elements with the given selector,
10079
* and either finds one or throws an error
10180
*/
102-
locatorForRequired(selector: string): AsyncFn<TestElement>;
81+
locatorFor(selector: string): AsyncFn<TestElement>;
10382

10483
/**
10584
* Creates an asynchronous locator function that can be used to find a `ComponentHarness` for a
@@ -110,7 +89,7 @@ export interface LocatorFactory {
11089
* @return An asynchronous locator function that searches components matching the given harness
11190
* type, and either returns a `ComponentHarness` for the component, or throws an error.
11291
*/
113-
locatorForRequired<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T>):
92+
locatorFor<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T>):
11493
AsyncFn<T>;
11594

11695
/**
@@ -165,11 +144,11 @@ export interface LocatorFactory {
165144
* should be inherited when defining user's own harness.
166145
*/
167146
export abstract class ComponentHarness {
168-
constructor(private readonly locatorFacotry: LocatorFactory) {}
147+
constructor(private readonly locatorFactory: LocatorFactory) {}
169148

170149
/** Gets a `Promise` for the `TestElement` representing the host element of the component. */
171150
async host(): Promise<TestElement> {
172-
return this.locatorFacotry.rootElement();
151+
return this.locatorFactory.rootElement;
173152
}
174153

175154
/**
@@ -178,7 +157,7 @@ export abstract class ComponentHarness {
178157
* appending to document.body).
179158
*/
180159
protected documentRootLocatorFactory(): LocatorFactory {
181-
return this.locatorFacotry.documentRootLocatorFactory();
160+
return this.locatorFactory.documentRootLocatorFactory();
182161
}
183162

184163
/**
@@ -190,7 +169,7 @@ export abstract class ComponentHarness {
190169
* @return An asynchronous locator function that searches for elements with the given selector,
191170
* and either finds one or throws an error
192171
*/
193-
protected locatorForRequired(selector: string): AsyncFn<TestElement>;
172+
protected locatorFor(selector: string): AsyncFn<TestElement>;
194173

195174
/**
196175
* Creates an asynchronous locator function that can be used to find a `ComponentHarness` for a
@@ -201,11 +180,11 @@ export abstract class ComponentHarness {
201180
* @return An asynchronous locator function that searches components matching the given harness
202181
* type, and either returns a `ComponentHarness` for the component, or throws an error.
203182
*/
204-
protected locatorForRequired<T extends ComponentHarness>(
183+
protected locatorFor<T extends ComponentHarness>(
205184
harnessType: ComponentHarnessConstructor<T>): AsyncFn<T>;
206185

207-
protected locatorForRequired(arg: any): any {
208-
return this.locatorFacotry.locatorForRequired(arg);
186+
protected locatorFor(arg: any): any {
187+
return this.locatorFactory.locatorFor(arg);
209188
}
210189

211190
/**
@@ -232,7 +211,7 @@ export abstract class ComponentHarness {
232211
harnessType: ComponentHarnessConstructor<T>): AsyncFn<T | null>;
233212

234213
protected locatorForOptional(arg: any): any {
235-
return this.locatorFacotry.locatorForOptional(arg);
214+
return this.locatorFactory.locatorForOptional(arg);
236215
}
237216

238217
/**
@@ -258,7 +237,7 @@ export abstract class ComponentHarness {
258237
AsyncFn<T[]>;
259238

260239
protected locatorForAll(arg: any): any {
261-
return this.locatorFacotry.locatorForAll(arg);
240+
return this.locatorFactory.locatorForAll(arg);
262241
}
263242
}
264243

src/cdk-experimental/testing/harness-environment.ts

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,23 @@ import {TestElement} from './test-element';
2222
* element type, `E`, used by the particular test environment.
2323
*/
2424
export abstract class HarnessEnvironment<E> implements HarnessLoader, LocatorFactory {
25-
protected constructor(protected rawRootElement: E) {}
25+
// Implemented as part of the `LocatorFactory` interface.
26+
rootElement: TestElement;
2627

27-
// Part of the `HarnessLoader` interface, delegated to concrete implementation.
28-
abstract documentRootLocatorFactory(): LocatorFactory;
28+
protected constructor(protected rawRootElement: E) {
29+
this.rootElement = this.createTestElement(rawRootElement);
30+
}
2931

3032
// Implemented as part of the `LocatorFactory` interface.
31-
rootElement(): TestElement {
32-
return this.createTestElement(this.rawRootElement);
33+
documentRootLocatorFactory(): LocatorFactory {
34+
return this.createEnvironment(this.getDocumentRoot());
3335
}
3436

3537
// Implemented as part of the `LocatorFactory` interface.
36-
locatorForRequired(selector: string): AsyncFn<TestElement>;
37-
locatorForRequired<T extends ComponentHarness>(harness: ComponentHarnessConstructor<T>):
38+
locatorFor(selector: string): AsyncFn<TestElement>;
39+
locatorFor<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T>):
3840
AsyncFn<T>;
39-
locatorForRequired<T extends ComponentHarness>(
41+
locatorFor<T extends ComponentHarness>(
4042
arg: string | ComponentHarnessConstructor<T>): AsyncFn<TestElement | T> {
4143
return async () => {
4244
if (typeof arg === 'string') {
@@ -57,7 +59,7 @@ export abstract class HarnessEnvironment<E> implements HarnessLoader, LocatorFac
5759

5860
// Implemented as part of the `LocatorFactory` interface.
5961
locatorForOptional(selector: string): AsyncFn<TestElement | null>;
60-
locatorForOptional<T extends ComponentHarness>(harness: ComponentHarnessConstructor<T>):
62+
locatorForOptional<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T>):
6163
AsyncFn<T | null>;
6264
locatorForOptional<T extends ComponentHarness>(
6365
arg: string | ComponentHarnessConstructor<T>): AsyncFn<TestElement | T | null> {
@@ -74,7 +76,8 @@ export abstract class HarnessEnvironment<E> implements HarnessLoader, LocatorFac
7476

7577
// Implemented as part of the `LocatorFactory` interface.
7678
locatorForAll(selector: string): AsyncFn<TestElement[]>;
77-
locatorForAll<T extends ComponentHarness>(harness: ComponentHarnessConstructor<T>): AsyncFn<T[]>;
79+
locatorForAll<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T>):
80+
AsyncFn<T[]>;
7881
locatorForAll<T extends ComponentHarness>(
7982
arg: string | ComponentHarnessConstructor<T>): AsyncFn<TestElement[] | T[]> {
8083
return async () => {
@@ -88,50 +91,45 @@ export abstract class HarnessEnvironment<E> implements HarnessLoader, LocatorFac
8891
}
8992

9093
// Implemented as part of the `HarnessLoader` interface.
91-
requiredHarness<T extends ComponentHarness>(harness: ComponentHarnessConstructor<T>): Promise<T> {
92-
return this.locatorForRequired(harness)();
93-
}
94-
95-
// Implemented as part of the `HarnessLoader` interface.
96-
optionalHarness<T extends ComponentHarness>(harness: ComponentHarnessConstructor<T>):
97-
Promise<T | null> {
98-
return this.locatorForOptional(harness)();
94+
getHarness<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T>):
95+
Promise<T> {
96+
return this.locatorFor(harnessType)();
9997
}
10098

10199
// Implemented as part of the `HarnessLoader` interface.
102-
allHarnesses<T extends ComponentHarness>(harness: ComponentHarnessConstructor<T>): Promise<T[]> {
103-
return this.locatorForAll(harness)();
100+
getAllHarnesses<T extends ComponentHarness>(harnessType: ComponentHarnessConstructor<T>):
101+
Promise<T[]> {
102+
return this.locatorForAll(harnessType)();
104103
}
105104

106105
// Implemented as part of the `HarnessLoader` interface.
107-
async findRequired(selector: string): Promise<HarnessLoader> {
106+
async getChildLoader(selector: string): Promise<HarnessLoader> {
108107
const element = await this.getRawElement(selector);
109108
if (element) {
110-
return this.createHarnessLoader(element);
109+
return this.createEnvironment(element);
111110
}
112111
throw Error(`Expected to find element matching selector: "${selector}", but none was found`);
113112
}
114113

115114
// Implemented as part of the `HarnessLoader` interface.
116-
async findOptional(selector: string): Promise<HarnessLoader | null> {
117-
const element = await this.getRawElement(selector);
118-
return element ? this.createHarnessLoader(element) : null;
115+
async getAllChildLoaders(selector: string): Promise<HarnessLoader[]> {
116+
return (await this.getAllRawElements(selector)).map(e => this.createEnvironment(e));
119117
}
120118

121-
// Implemented as part of the `HarnessLoader` interface.
122-
async findAll(selector: string): Promise<HarnessLoader[]> {
123-
return (await this.getAllRawElements(selector)).map(e => this.createHarnessLoader(e));
119+
/** Creates a `ComponentHarness` for the given harness type with the given raw host element. */
120+
protected createComponentHarness<T extends ComponentHarness>(
121+
harnessType: ComponentHarnessConstructor<T>, element: E): T {
122+
return new harnessType(this.createEnvironment(element));
124123
}
125124

125+
/** Gets the root element for the document. */
126+
protected abstract getDocumentRoot(): E;
127+
126128
/** Creates a `TestElement` from a raw element. */
127129
protected abstract createTestElement(element: E): TestElement;
128130

129-
/** Creates a `ComponentHarness` for the given harness type with the given raw host element. */
130-
protected abstract createComponentHarness<T extends ComponentHarness>(
131-
harnessType: ComponentHarnessConstructor<T>, element: E): T;
132-
133131
/** Creates a `HarnessLoader` rooted at the given raw element. */
134-
protected abstract createHarnessLoader(element: E): HarnessLoader;
132+
protected abstract createEnvironment(element: E): HarnessEnvironment<E>;
135133

136134
/**
137135
* Gets the first element matching the given selector under this environment's root element, or

src/cdk-experimental/testing/protractor/protractor-harness-environment.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@
77
*/
88

99
import {by, element as protractorElement, ElementFinder} from 'protractor';
10-
import {
11-
ComponentHarness,
12-
ComponentHarnessConstructor,
13-
HarnessLoader,
14-
LocatorFactory,
15-
} from '../component-harness';
10+
import {HarnessLoader} from '../component-harness';
1611
import {HarnessEnvironment} from '../harness-environment';
1712
import {TestElement} from '../test-element';
1813
import {ProtractorElement} from './protractor-element';
@@ -28,20 +23,15 @@ export class ProtractorHarnessEnvironment extends HarnessEnvironment<ElementFind
2823
return new ProtractorHarnessEnvironment(protractorElement(by.css('body')));
2924
}
3025

31-
documentRootLocatorFactory(): LocatorFactory {
32-
return new ProtractorHarnessEnvironment(protractorElement(by.css('body')));
26+
protected getDocumentRoot(): ElementFinder {
27+
return protractorElement(by.css('body'));
3328
}
3429

3530
protected createTestElement(element: ElementFinder): TestElement {
3631
return new ProtractorElement(element);
3732
}
3833

39-
protected createComponentHarness<T extends ComponentHarness>(
40-
harnessType: ComponentHarnessConstructor<T>, element: ElementFinder): T {
41-
return new harnessType(new ProtractorHarnessEnvironment(element));
42-
}
43-
44-
protected createHarnessLoader(element: ElementFinder): HarnessLoader {
34+
protected createEnvironment(element: ElementFinder): HarnessEnvironment<ElementFinder> {
4535
return new ProtractorHarnessEnvironment(element);
4636
}
4737

src/cdk-experimental/testing/testbed/testbed-harness-environment.ts

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,20 @@
77
*/
88

99
import {ComponentFixture} from '@angular/core/testing';
10-
import {
11-
ComponentHarness,
12-
ComponentHarnessConstructor,
13-
HarnessLoader,
14-
LocatorFactory
15-
} from '../component-harness';
10+
import {ComponentHarness, ComponentHarnessConstructor, HarnessLoader} from '../component-harness';
1611
import {HarnessEnvironment} from '../harness-environment';
1712
import {TestElement} from '../test-element';
1813
import {UnitTestElement} from './unit-test-element';
1914

2015
/** A `HarnessEnvironment` implementation for Angular's Testbed. */
2116
export class TestbedHarnessEnvironment extends HarnessEnvironment<Element> {
22-
protected constructor(rawRootElement: Element, private _stabilize: () => Promise<void>) {
17+
protected constructor(rawRootElement: Element, private _fixture: ComponentFixture<unknown>) {
2318
super(rawRootElement);
2419
}
2520

2621
/** Creates a `HarnessLoader` rooted at the given fixture's root element. */
2722
static create(fixture: ComponentFixture<unknown>): HarnessLoader {
28-
const stabilize = async () => {
29-
fixture.detectChanges();
30-
await fixture.whenStable();
31-
};
32-
return new TestbedHarnessEnvironment(fixture.nativeElement, stabilize);
23+
return new TestbedHarnessEnvironment(fixture.nativeElement, fixture);
3324
}
3425

3526
/**
@@ -38,36 +29,23 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment<Element> {
3829
* of a fixture, as components do not have the correct selector when they are created as the root
3930
* of the fixture.
4031
*/
41-
static async harnessForFixtureRoot<T extends ComponentHarness>(
32+
static async harnessForFixture<T extends ComponentHarness>(
4233
fixture: ComponentFixture<unknown>, harnessType: ComponentHarnessConstructor<T>): Promise<T> {
43-
const stabilize = async () => {
44-
fixture.detectChanges();
45-
await fixture.whenStable();
46-
};
47-
const environment = new TestbedHarnessEnvironment(fixture.nativeElement, stabilize);
34+
const environment = new TestbedHarnessEnvironment(fixture.nativeElement, fixture);
4835
await environment._stabilize();
4936
return environment.createComponentHarness(harnessType, fixture.nativeElement);
5037
}
5138

52-
documentRootLocatorFactory(): LocatorFactory {
53-
let element = this.rawRootElement;
54-
while (element.parentElement) {
55-
element = element.parentElement;
56-
}
57-
return new TestbedHarnessEnvironment(element, this._stabilize);
39+
protected getDocumentRoot(): Element {
40+
return this._fixture.nativeElement;
5841
}
5942

6043
protected createTestElement(element: Element): TestElement {
61-
return new UnitTestElement(element, this._stabilize);
44+
return new UnitTestElement(element, this._stabilize.bind(this));
6245
}
6346

64-
protected createComponentHarness<T extends ComponentHarness>(
65-
harnessType: ComponentHarnessConstructor<T>, element: Element): T {
66-
return new harnessType(new TestbedHarnessEnvironment(element, this._stabilize));
67-
}
68-
69-
protected createHarnessLoader(element: Element): HarnessLoader {
70-
return new TestbedHarnessEnvironment(element, this._stabilize);
47+
protected createEnvironment(element: Element): HarnessEnvironment<Element> {
48+
return new TestbedHarnessEnvironment(element, this._fixture);
7149
}
7250

7351
protected async getRawElement(selector: string): Promise<Element | null> {
@@ -79,4 +57,9 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment<Element> {
7957
await this._stabilize();
8058
return Array.from(this.rawRootElement.querySelectorAll(selector));
8159
}
60+
61+
private async _stabilize(): Promise<void> {
62+
this._fixture.detectChanges();
63+
await this._fixture.whenStable();
64+
}
8265
}

0 commit comments

Comments
 (0)