You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/cdk/testing/testing.md
+80-1Lines changed: 80 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -549,4 +549,83 @@ may need to explicitly wait for tasks outside `NgZone`, as this does not happen
549
549
550
550
### API for harness environment authors
551
551
552
-
TODO(mmalerba): Fill in docs for harness environment authors
552
+
Harness environment authors are developers who want to add support for using component harnesses in
553
+
additional testing environments. Out of the box, these harnesses can be used in Protractor E2E tests
554
+
and Karma unit tests. Support for a new testing environment can be added by creating new
555
+
`TestElement` and `HarnessEnvironment` implementations for the environment.
556
+
557
+
#### Creating a `TestElement` implementation for the environment
558
+
559
+
The first step in adding support for a new testing environment is to create a `TestElement`
560
+
implementation. `TestElement` is simply an interface that serves as an environment-agnostic
561
+
representation of a DOM element. It provides a way for harnesses to interact with DOM elements
562
+
regardless of the environment they're used in. Because it is not possible to interact with elements
563
+
synchronously in all test environments (e.g. Protractor), all of the methods on this interface are
564
+
asynchronous and return a `Promise` with the result of the operation.
565
+
566
+
| Method | Description |
567
+
| ------ | ----------- |
568
+
|`blur(): Promise<void>`| Blurs the element. |
569
+
|`clear(): Promise<void>`| Clears the text from an element (only applies for `<input>` and `<textarea>`). |
570
+
|`click(relativeX?: number, relativeY?: number): Promise<void>`| Clicks an element at a point relative to it's top-left corner. |
571
+
|`focus(): Promise<void>`| Focuses the element. |
572
+
|`getCssValue(property: string): Promise<string>`| Gets the computed CSS value of the given property for the element. |
573
+
|`hover(): Promise<void>`| Hovers the mouse over the element. |
574
+
|`sendKeys(...keys: (string \| TestKey)[]): Promise<void>`| Sends a sequence of key events to the element. |
575
+
|`sendKeys(modifiers: ModifierKeys, ...keys: (string \| TestKey)[]): Promise<void>`| Sends a sequence of key events to the element, while holding a set of modifier keys. |
576
+
|`text(): Promise<string>`| Gets the text content of the element. |
577
+
|`getAttribute(name: string): Promise<string \| null>`| Gets the value of the given HTML attribute for the element. |
578
+
|`hasClass(name: string): Promise<boolean>`| Checks whether the element has the given class. |
579
+
|`getDimensions(): Promise<ElementDimensions>`| Gets the dimensions of the element. |
580
+
|`getProperty(name: string): Promise<any>`| Gets the value of the given property for the element. |
581
+
|`matchesSelector(selector: string): Promise<boolean>`| Checks whether the given selector matches the element. |
582
+
583
+
The `TestElement` interface consists largely of methods that look very similar to the methods
584
+
available on an `HTMLElement`; because of this, similar methods likely exist in most test
585
+
environments, which makes implementing the methods fairly straightforward. However, one important
586
+
difference to note when implementing the `sendKeys` method, is that the key codes in the `TestKey`
587
+
enum likely differ from the key codes used in the test environment. It is recommended to maintain a
588
+
mapping from `TestKey` codes to the codes used in the particular testing environment.
implementations that come with the CDK serve as good examples of implementations of this interface.
595
+
596
+
#### Creating a `HarnessEnvironemnt` implementation for the environment
597
+
598
+
`HarnessEnvironment` is an abstract class that needs to be extended to create a concrete subclass to
599
+
be used with the new environment. This is the class that test authors will use to actually create
600
+
component harness instances for use in their tests.
601
+
602
+
The first step in creating a `HarnessEnvironment` implementation for a new testing environment is to
603
+
extend `HarnessEnvironment` and fill in implementations for the abstract methods. The
604
+
`HarnessEnvironment` is generic on the raw element type of the environment, `E`. When extending the
605
+
class, it is recommended to fix this generic parameter to the correct type for the environment
606
+
(e.g. `Element` for the `TestbedHarnessEnvironment`, `ElementFinder` for the
607
+
`ProtractorHarnessEnvironment`). The following are the abstract methods that must be implemented:
608
+
609
+
| Method | Description |
610
+
| ------ | ----------- |
611
+
|`abstract getDocumentRoot(): E`| Gets the root element for the environment (e.g. `document.body`). |
612
+
|`abstract createTestElement(element: E): TestElement`| Creates a `TestElement` for the given raw element. |
613
+
|`abstract createEnvironment(element: E): HarnessEnvironment`| Creates a `HarnessEnvironment` rooted at the given raw element. |
614
+
|`abstract getAllRawElements(selector: string): Promise<E[]>`| Gets all of the raw elements under the root element of the environment matching the given selector. |
615
+
|`abstract forceStabilize(): Promise<void>`| Gets a `Promise` that resolves when the `NgZone` is stable. Additionally, if applicable, tells `NgZone` to stabilize (e.g. calling `flush()` in a `fakeAsync` test). |
616
+
|`abstract waitForTasksOutsideAngular(): Promise<void>`| Gets a `Promise` that resolves when the parent zone of `NgZone` is stable. |
617
+
618
+
In addition to implementing the missing methods, this class should provide a way for test authors to
619
+
get `ComponentHarness` instances. The recommended approach is to have a protected constructor and
620
+
provide a static method called `loader` that returns a `HarnessLoader` instance. This allows test
621
+
authors to write code like: `SomeHarnessEnvironment.loader().getHarness(...)`. Depending on the
622
+
needs of the particular environment, the class may provide several different static methods or
623
+
require arguments to be passed. (e.g. the `loader` method on `TestbedHarnessEnvironment` takes a
624
+
`ComponentFixture`, and the class provides additional static methods called `documentRootLoader` and
0 commit comments