components
components copied to clipboard
feat(cdk/testing): be more lenient in HarnessQuery
Feature Description
We find the TestElement/ComponentHarness API exposed in @angular/cdk/testing
very useful, especially because it decouples much of the test code from the actual environment the test runs in.
We want to use this for non-Angular projects, where pulling in @angular/cdk
is a no-go. More specifically, we want to use this to create harnesses for web components, some of which will then end up being used in Angular applications.
We've created our own implementation of these types and we're trying to make these compatible with Angular types so that the web component library can use the non-Angular version but these harnesses can then still be used in Angular ComponentHarnesses.
We've nearly gotten to the point where everything works, there's only one thing we cannot resolve: the HarnessQuery
used in the LocatorFactory
interface's functions references the HarnessPredicate
class which has private properties.
This makes "our" version of HarnessQuery and the Angular version inherently incompatible according to typescript.
This could be a small change, e.g. limiting the type in HarnessQuery
to only the required properties:
export type HarnessQuery<T extends ComponentHarness> =
| ComponentHarnessConstructor<T>
- | HarnessPredicate<T>;
+ | Pick<HarnessPredicate<T>, 'getDescription' | 'getSelector' | 'harnessType'>
and in the harness-environment.ts
file use a new function instead of query instanceof HarnessPredicate
function isHarnessPredicate<T extends ComponentHarness>(value: HarnessQuery<T>): value is Pick<HarnessPredicate<T>, 'getDescription' | 'getSelector' | 'harnessType'> {
return 'harnessType' in value;
}
Use Case
As mentioned above, we want to use the component harness concept in a non-Angular context and we want those harnesses to be compatible with harnesses written using the CDK and the CDK's harness environments.
An alternative solution could be to extract part of @angular/cdk/testing
into a separate package that doesn't have any dependencies to the Angular framework. That way we wouldn't have to maintain our own copy of these types/classes.